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.database.ContentObserver; 21import android.net.Uri; 22import android.os.AsyncTask; 23import android.os.Handler; 24import android.os.RemoteException; 25import android.os.ServiceManager; 26import android.provider.Settings; 27import android.util.Log; 28import android.view.IWindowManager; 29import android.view.Surface; 30 31/** 32 * Provides helper functions for configuring the display rotation policy. 33 */ 34public final class RotationPolicy { 35 private static final String TAG = "RotationPolicy"; 36 37 private RotationPolicy() { 38 } 39 40 /** 41 * Returns true if the device supports the rotation-lock toggle feature 42 * in the system UI or system bar. 43 * 44 * When the rotation-lock toggle is supported, the "auto-rotate screen" option in 45 * Display settings should be hidden, but it should remain available in Accessibility 46 * settings. 47 */ 48 public static boolean isRotationLockToggleSupported(Context context) { 49 return context.getResources().getConfiguration().smallestScreenWidthDp >= 600; 50 } 51 52 /** 53 * Returns true if the rotation-lock toggle should be shown in the UI. 54 */ 55 public static boolean isRotationLockToggleVisible(Context context) { 56 return isRotationLockToggleSupported(context) && 57 Settings.System.getInt(context.getContentResolver(), 58 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0) == 0; 59 } 60 61 /** 62 * Returns true if rotation lock is enabled. 63 */ 64 public static boolean isRotationLocked(Context context) { 65 return Settings.System.getInt(context.getContentResolver(), 66 Settings.System.ACCELEROMETER_ROTATION, 0) == 0; 67 } 68 69 /** 70 * Enables or disables rotation lock. 71 * 72 * Should be used by the rotation lock toggle. 73 */ 74 public static void setRotationLock(Context context, final boolean enabled) { 75 Settings.System.putInt(context.getContentResolver(), 76 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0); 77 78 AsyncTask.execute(new Runnable() { 79 @Override 80 public void run() { 81 try { 82 IWindowManager wm = IWindowManager.Stub.asInterface( 83 ServiceManager.getService(Context.WINDOW_SERVICE)); 84 if (enabled) { 85 wm.freezeRotation(-1); 86 } else { 87 wm.thawRotation(); 88 } 89 } catch (RemoteException exc) { 90 Log.w(TAG, "Unable to save auto-rotate setting"); 91 } 92 } 93 }); 94 } 95 96 /** 97 * Enables or disables rotation lock and adjusts whether the rotation lock toggle 98 * should be hidden for accessibility purposes. 99 * 100 * Should be used by Display settings and Accessibility settings. 101 */ 102 public static void setRotationLockForAccessibility(Context context, final boolean enabled) { 103 Settings.System.putInt(context.getContentResolver(), 104 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, enabled ? 1 : 0); 105 106 AsyncTask.execute(new Runnable() { 107 @Override 108 public void run() { 109 try { 110 IWindowManager wm = IWindowManager.Stub.asInterface( 111 ServiceManager.getService(Context.WINDOW_SERVICE)); 112 if (enabled) { 113 wm.freezeRotation(Surface.ROTATION_0); 114 } else { 115 wm.thawRotation(); 116 } 117 } catch (RemoteException exc) { 118 Log.w(TAG, "Unable to save auto-rotate setting"); 119 } 120 } 121 }); 122 } 123 124 /** 125 * Registers a listener for rotation policy changes. 126 */ 127 public static void registerRotationPolicyListener(Context context, 128 RotationPolicyListener listener) { 129 context.getContentResolver().registerContentObserver(Settings.System.getUriFor( 130 Settings.System.ACCELEROMETER_ROTATION), 131 false, listener.mObserver); 132 context.getContentResolver().registerContentObserver(Settings.System.getUriFor( 133 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY), 134 false, listener.mObserver); 135 } 136 137 /** 138 * Unregisters a listener for rotation policy changes. 139 */ 140 public static void unregisterRotationPolicyListener(Context context, 141 RotationPolicyListener listener) { 142 context.getContentResolver().unregisterContentObserver(listener.mObserver); 143 } 144 145 /** 146 * Listener that is invoked whenever a change occurs that might affect the rotation policy. 147 */ 148 public static abstract class RotationPolicyListener { 149 final ContentObserver mObserver = new ContentObserver(new Handler()) { 150 public void onChange(boolean selfChange, Uri uri) { 151 RotationPolicyListener.this.onChange(); 152 } 153 }; 154 155 public abstract void onChange(); 156 } 157}