DisplaySettings.java revision cbf312ec2984dcc42bc39b01f4b126b0901740cf
1/* 2 * Copyright (C) 2010 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.settings; 18 19import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; 20 21import android.app.ActivityManagerNative; 22import android.app.admin.DevicePolicyManager; 23import android.content.ContentResolver; 24import android.content.Context; 25import android.content.res.Configuration; 26import android.content.res.Resources; 27import android.database.ContentObserver; 28import android.os.Bundle; 29import android.os.Handler; 30import android.os.RemoteException; 31import android.os.ServiceManager; 32import android.preference.CheckBoxPreference; 33import android.preference.ListPreference; 34import android.preference.Preference; 35import android.preference.PreferenceScreen; 36import android.provider.Settings; 37import android.provider.Settings.SettingNotFoundException; 38import android.util.Log; 39import android.view.IWindowManager; 40import android.view.Surface; 41 42import java.util.ArrayList; 43 44public class DisplaySettings extends SettingsPreferenceFragment implements 45 Preference.OnPreferenceChangeListener { 46 private static final String TAG = "DisplaySettings"; 47 48 /** If there is no setting in the provider, use this. */ 49 private static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000; 50 51 private static final String KEY_SCREEN_TIMEOUT = "screen_timeout"; 52 private static final String KEY_ACCELEROMETER = "accelerometer"; 53 private static final String KEY_FONT_SIZE = "font_size"; 54 private static final String KEY_NOTIFICATION_PULSE = "notification_pulse"; 55 56 private CheckBoxPreference mAccelerometer; 57 private ListPreference mFontSizePref; 58 private CheckBoxPreference mNotificationPulse; 59 60 private final Configuration mCurConfig = new Configuration(); 61 62 private ListPreference mScreenTimeoutPreference; 63 64 private ContentObserver mAccelerometerRotationObserver = new ContentObserver(new Handler()) { 65 @Override 66 public void onChange(boolean selfChange) { 67 updateAccelerometerRotationCheckbox(); 68 } 69 }; 70 71 @Override 72 public void onCreate(Bundle savedInstanceState) { 73 super.onCreate(savedInstanceState); 74 ContentResolver resolver = getActivity().getContentResolver(); 75 76 addPreferencesFromResource(R.xml.display_settings); 77 78 mAccelerometer = (CheckBoxPreference) findPreference(KEY_ACCELEROMETER); 79 mAccelerometer.setPersistent(false); 80 81 mScreenTimeoutPreference = (ListPreference) findPreference(KEY_SCREEN_TIMEOUT); 82 final long currentTimeout = Settings.System.getLong(resolver, SCREEN_OFF_TIMEOUT, 83 FALLBACK_SCREEN_TIMEOUT_VALUE); 84 mScreenTimeoutPreference.setValue(String.valueOf(currentTimeout)); 85 mScreenTimeoutPreference.setOnPreferenceChangeListener(this); 86 disableUnusableTimeouts(mScreenTimeoutPreference); 87 updateTimeoutPreferenceDescription(currentTimeout); 88 89 mFontSizePref = (ListPreference) findPreference(KEY_FONT_SIZE); 90 mFontSizePref.setOnPreferenceChangeListener(this); 91 mNotificationPulse = (CheckBoxPreference) findPreference(KEY_NOTIFICATION_PULSE); 92 if (mNotificationPulse != null 93 && getResources().getBoolean( 94 com.android.internal.R.bool.config_intrusiveNotificationLed) == false) { 95 getPreferenceScreen().removePreference(mNotificationPulse); 96 } else { 97 try { 98 mNotificationPulse.setChecked(Settings.System.getInt(resolver, 99 Settings.System.NOTIFICATION_LIGHT_PULSE) == 1); 100 mNotificationPulse.setOnPreferenceChangeListener(this); 101 } catch (SettingNotFoundException snfe) { 102 Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found"); 103 } 104 } 105 } 106 107 private void updateTimeoutPreferenceDescription(long currentTimeout) { 108 ListPreference preference = mScreenTimeoutPreference; 109 String summary; 110 if (currentTimeout < 0) { 111 // Unsupported value 112 summary = ""; 113 } else { 114 final CharSequence[] entries = preference.getEntries(); 115 final CharSequence[] values = preference.getEntryValues(); 116 int best = 0; 117 for (int i = 0; i < values.length; i++) { 118 long timeout = Long.parseLong(values[i].toString()); 119 if (currentTimeout >= timeout) { 120 best = i; 121 } 122 } 123 summary = preference.getContext().getString(R.string.screen_timeout_summary, 124 entries[best]); 125 } 126 preference.setSummary(summary); 127 } 128 129 private void disableUnusableTimeouts(ListPreference screenTimeoutPreference) { 130 final DevicePolicyManager dpm = 131 (DevicePolicyManager) getActivity().getSystemService( 132 Context.DEVICE_POLICY_SERVICE); 133 final long maxTimeout = dpm != null ? dpm.getMaximumTimeToLock(null) : 0; 134 if (maxTimeout == 0) { 135 return; // policy not enforced 136 } 137 final CharSequence[] entries = screenTimeoutPreference.getEntries(); 138 final CharSequence[] values = screenTimeoutPreference.getEntryValues(); 139 ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>(); 140 ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>(); 141 for (int i = 0; i < values.length; i++) { 142 long timeout = Long.parseLong(values[i].toString()); 143 if (timeout <= maxTimeout) { 144 revisedEntries.add(entries[i]); 145 revisedValues.add(values[i]); 146 } 147 } 148 if (revisedEntries.size() != entries.length || revisedValues.size() != values.length) { 149 screenTimeoutPreference.setEntries( 150 revisedEntries.toArray(new CharSequence[revisedEntries.size()])); 151 screenTimeoutPreference.setEntryValues( 152 revisedValues.toArray(new CharSequence[revisedValues.size()])); 153 final int userPreference = Integer.parseInt(screenTimeoutPreference.getValue()); 154 if (userPreference <= maxTimeout) { 155 screenTimeoutPreference.setValue(String.valueOf(userPreference)); 156 } else { 157 // There will be no highlighted selection since nothing in the list matches 158 // maxTimeout. The user can still select anything less than maxTimeout. 159 // TODO: maybe append maxTimeout to the list and mark selected. 160 } 161 } 162 screenTimeoutPreference.setEnabled(revisedEntries.size() > 0); 163 } 164 165 int floatToIndex(float val) { 166 String[] indices = getResources().getStringArray(R.array.entryvalues_font_size); 167 float lastVal = Float.parseFloat(indices[0]); 168 for (int i=1; i<indices.length; i++) { 169 float thisVal = Float.parseFloat(indices[i]); 170 if (val < (lastVal + (thisVal-lastVal)*.5f)) { 171 return i-1; 172 } 173 lastVal = thisVal; 174 } 175 return indices.length-1; 176 } 177 178 public void readFontSizePreference(ListPreference pref) { 179 try { 180 mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration()); 181 } catch (RemoteException e) { 182 Log.w(TAG, "Unable to retrieve font size"); 183 } 184 185 // mark the appropriate item in the preferences list 186 int index = floatToIndex(mCurConfig.fontScale); 187 pref.setValueIndex(index); 188 189 // report the current size in the summary text 190 final Resources res = getResources(); 191 String[] fontSizeNames = res.getStringArray(R.array.entries_font_size); 192 pref.setSummary(String.format(res.getString(R.string.summary_font_size), 193 fontSizeNames[index])); 194 } 195 196 @Override 197 public void onResume() { 198 super.onResume(); 199 200 updateState(); 201 getContentResolver().registerContentObserver( 202 Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), true, 203 mAccelerometerRotationObserver); 204 } 205 206 @Override 207 public void onPause() { 208 super.onPause(); 209 210 getContentResolver().unregisterContentObserver(mAccelerometerRotationObserver); 211 } 212 213 private void updateState() { 214 updateAccelerometerRotationCheckbox(); 215 readFontSizePreference(mFontSizePref); 216 } 217 218 private void updateAccelerometerRotationCheckbox() { 219 mAccelerometer.setChecked(Settings.System.getInt( 220 getContentResolver(), 221 Settings.System.ACCELEROMETER_ROTATION, 0) != 0); 222 } 223 224 public void writeFontSizePreference(Object objValue) { 225 try { 226 mCurConfig.fontScale = Float.parseFloat(objValue.toString()); 227 ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig); 228 } catch (RemoteException e) { 229 Log.w(TAG, "Unable to save font size"); 230 } 231 } 232 233 @Override 234 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 235 if (preference == mAccelerometer) { 236 try { 237 IWindowManager wm = IWindowManager.Stub.asInterface( 238 ServiceManager.getService(Context.WINDOW_SERVICE)); 239 if (mAccelerometer.isChecked()) { 240 wm.thawRotation(); 241 } else { 242 wm.freezeRotation(Surface.ROTATION_0); 243 } 244 } catch (RemoteException exc) { 245 Log.w(TAG, "Unable to save auto-rotate setting"); 246 } 247 } else if (preference == mNotificationPulse) { 248 boolean value = mNotificationPulse.isChecked(); 249 Settings.System.putInt(getContentResolver(), Settings.System.NOTIFICATION_LIGHT_PULSE, 250 value ? 1 : 0); 251 return true; 252 } 253 return super.onPreferenceTreeClick(preferenceScreen, preference); 254 } 255 256 public boolean onPreferenceChange(Preference preference, Object objValue) { 257 final String key = preference.getKey(); 258 if (KEY_SCREEN_TIMEOUT.equals(key)) { 259 int value = Integer.parseInt((String) objValue); 260 try { 261 Settings.System.putInt(getContentResolver(), SCREEN_OFF_TIMEOUT, value); 262 updateTimeoutPreferenceDescription(value); 263 } catch (NumberFormatException e) { 264 Log.e(TAG, "could not persist screen timeout setting", e); 265 } 266 } 267 if (KEY_FONT_SIZE.equals(key)) { 268 writeFontSizePreference(objValue); 269 } 270 271 return true; 272 } 273} 274