DevelopmentSettings.java revision 83b09a57e158f3050c7feb5ea75e8dd2d626697e
1/* 2 * Copyright (C) 2008 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 android.app.ActivityManagerNative; 20import android.app.AlertDialog; 21import android.app.Dialog; 22import android.content.ContentResolver; 23import android.content.DialogInterface; 24import android.content.Intent; 25import android.os.BatteryManager; 26import android.os.Build; 27import android.os.Bundle; 28import android.os.IBinder; 29import android.os.Parcel; 30import android.os.RemoteException; 31import android.os.ServiceManager; 32import android.os.StrictMode; 33import android.os.SystemProperties; 34import android.preference.CheckBoxPreference; 35import android.preference.ListPreference; 36import android.preference.Preference; 37import android.preference.PreferenceFragment; 38import android.preference.PreferenceScreen; 39import android.preference.Preference.OnPreferenceChangeListener; 40import android.provider.Settings; 41import android.text.TextUtils; 42import android.view.IWindowManager; 43 44/* 45 * Displays preferences for application developers. 46 */ 47public class DevelopmentSettings extends PreferenceFragment 48 implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener, 49 OnPreferenceChangeListener { 50 51 private static final String ENABLE_ADB = "enable_adb"; 52 private static final String KEEP_SCREEN_ON = "keep_screen_on"; 53 private static final String ALLOW_MOCK_LOCATION = "allow_mock_location"; 54 private static final String HDCP_CHECKING_KEY = "hdcp_checking"; 55 private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking"; 56 57 private static final String STRICT_MODE_KEY = "strict_mode"; 58 private static final String POINTER_LOCATION_KEY = "pointer_location"; 59 private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates"; 60 private static final String SHOW_CPU_USAGE_KEY = "show_cpu_usage"; 61 private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale"; 62 private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale"; 63 64 private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY 65 = "immediately_destroy_activities"; 66 private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit"; 67 68 private IWindowManager mWindowManager; 69 70 private CheckBoxPreference mEnableAdb; 71 private CheckBoxPreference mKeepScreenOn; 72 private CheckBoxPreference mAllowMockLocation; 73 74 private CheckBoxPreference mStrictMode; 75 private CheckBoxPreference mPointerLocation; 76 private CheckBoxPreference mShowScreenUpdates; 77 private CheckBoxPreference mShowCpuUsage; 78 private ListPreference mWindowAnimationScale; 79 private ListPreference mTransitionAnimationScale; 80 81 private CheckBoxPreference mImmediatelyDestroyActivities; 82 private ListPreference mAppProcessLimit; 83 84 // To track whether Yes was clicked in the adb warning dialog 85 private boolean mOkClicked; 86 87 private Dialog mOkDialog; 88 89 @Override 90 public void onCreate(Bundle icicle) { 91 super.onCreate(icicle); 92 93 mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 94 95 addPreferencesFromResource(R.xml.development_prefs); 96 97 mEnableAdb = (CheckBoxPreference) findPreference(ENABLE_ADB); 98 mKeepScreenOn = (CheckBoxPreference) findPreference(KEEP_SCREEN_ON); 99 mAllowMockLocation = (CheckBoxPreference) findPreference(ALLOW_MOCK_LOCATION); 100 101 mStrictMode = (CheckBoxPreference) findPreference(STRICT_MODE_KEY); 102 mPointerLocation = (CheckBoxPreference) findPreference(POINTER_LOCATION_KEY); 103 mShowScreenUpdates = (CheckBoxPreference) findPreference(SHOW_SCREEN_UPDATES_KEY); 104 mShowCpuUsage = (CheckBoxPreference) findPreference(SHOW_CPU_USAGE_KEY); 105 mWindowAnimationScale = (ListPreference) findPreference(WINDOW_ANIMATION_SCALE_KEY); 106 mWindowAnimationScale.setOnPreferenceChangeListener(this); 107 mTransitionAnimationScale = (ListPreference) findPreference(TRANSITION_ANIMATION_SCALE_KEY); 108 mTransitionAnimationScale.setOnPreferenceChangeListener(this); 109 110 mImmediatelyDestroyActivities = (CheckBoxPreference) findPreference( 111 IMMEDIATELY_DESTROY_ACTIVITIES_KEY); 112 mAppProcessLimit = (ListPreference) findPreference(APP_PROCESS_LIMIT_KEY); 113 mAppProcessLimit.setOnPreferenceChangeListener(this); 114 115 removeHdcpOptionsForProduction(); 116 } 117 118 private void removeHdcpOptionsForProduction() { 119 if ("user".equals(Build.TYPE)) { 120 Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY); 121 if (hdcpChecking != null) { 122 // Remove the preference 123 getPreferenceScreen().removePreference(hdcpChecking); 124 } 125 } 126 } 127 128 @Override 129 public void onResume() { 130 super.onResume(); 131 132 final ContentResolver cr = getActivity().getContentResolver(); 133 mEnableAdb.setChecked(Settings.Secure.getInt(cr, 134 Settings.Secure.ADB_ENABLED, 0) != 0); 135 mKeepScreenOn.setChecked(Settings.System.getInt(cr, 136 Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0) != 0); 137 mAllowMockLocation.setChecked(Settings.Secure.getInt(cr, 138 Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0); 139 updateHdcpValues(); 140 updateStrictModeVisualOptions(); 141 updatePointerLocationOptions(); 142 updateFlingerOptions(); 143 updateCpuUsageOptions(); 144 updateAnimationScaleOptions(); 145 updateImmediatelyDestroyActivitiesOptions(); 146 updateAppProcessLimitOptions(); 147 } 148 149 private void updateHdcpValues() { 150 int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values 151 ListPreference hdcpChecking = (ListPreference) findPreference(HDCP_CHECKING_KEY); 152 if (hdcpChecking != null) { 153 String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY); 154 String[] values = getResources().getStringArray(R.array.hdcp_checking_values); 155 String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries); 156 for (int i = 0; i < values.length; i++) { 157 if (currentValue.equals(values[i])) { 158 index = i; 159 break; 160 } 161 } 162 hdcpChecking.setValue(values[index]); 163 hdcpChecking.setSummary(summaries[index]); 164 hdcpChecking.setOnPreferenceChangeListener(this); 165 } 166 } 167 168 // Returns the current state of the system property that controls 169 // strictmode flashes. One of: 170 // 0: not explicitly set one way or another 171 // 1: on 172 // 2: off 173 private int currentStrictModeActiveIndex() { 174 if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) { 175 return 0; 176 } 177 boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false); 178 return enabled ? 1 : 2; 179 } 180 181 private void writeStrictModeVisualOptions() { 182 try { 183 mWindowManager.setStrictModeVisualIndicatorPreference(mStrictMode.isChecked() 184 ? "1" : ""); 185 } catch (RemoteException e) { 186 } 187 } 188 189 private void updateStrictModeVisualOptions() { 190 mStrictMode.setChecked(currentStrictModeActiveIndex() == 1); 191 } 192 193 private void writePointerLocationOptions() { 194 Settings.System.putInt(getActivity().getContentResolver(), 195 Settings.System.POINTER_LOCATION, mPointerLocation.isChecked() ? 1 : 0); 196 } 197 198 private void updatePointerLocationOptions() { 199 mPointerLocation.setChecked(Settings.System.getInt(getActivity().getContentResolver(), 200 Settings.System.POINTER_LOCATION, 0) != 0); 201 } 202 203 private void updateFlingerOptions() { 204 // magic communication with surface flinger. 205 try { 206 IBinder flinger = ServiceManager.getService("SurfaceFlinger"); 207 if (flinger != null) { 208 Parcel data = Parcel.obtain(); 209 Parcel reply = Parcel.obtain(); 210 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 211 flinger.transact(1010, data, reply, 0); 212 @SuppressWarnings("unused") 213 int showCpu = reply.readInt(); 214 @SuppressWarnings("unused") 215 int enableGL = reply.readInt(); 216 int showUpdates = reply.readInt(); 217 mShowScreenUpdates.setChecked(showUpdates != 0); 218 @SuppressWarnings("unused") 219 int showBackground = reply.readInt(); 220 reply.recycle(); 221 data.recycle(); 222 } 223 } catch (RemoteException ex) { 224 } 225 } 226 227 private void writeFlingerOptions() { 228 try { 229 IBinder flinger = ServiceManager.getService("SurfaceFlinger"); 230 if (flinger != null) { 231 Parcel data = Parcel.obtain(); 232 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 233 data.writeInt(mShowScreenUpdates.isChecked() ? 1 : 0); 234 flinger.transact(1002, data, null, 0); 235 data.recycle(); 236 237 updateFlingerOptions(); 238 } 239 } catch (RemoteException ex) { 240 } 241 } 242 243 private void updateCpuUsageOptions() { 244 mShowCpuUsage.setChecked(Settings.System.getInt(getActivity().getContentResolver(), 245 Settings.System.SHOW_PROCESSES, 0) != 0); 246 } 247 248 private void writeCpuUsageOptions() { 249 boolean value = mShowCpuUsage.isChecked(); 250 Settings.System.putInt(getActivity().getContentResolver(), 251 Settings.System.SHOW_PROCESSES, value ? 1 : 0); 252 Intent service = (new Intent()) 253 .setClassName("android", "com.android.server.LoadAverageService"); 254 if (value) { 255 getActivity().startService(service); 256 } else { 257 getActivity().stopService(service); 258 } 259 } 260 261 private void writeImmediatelyDestroyActivitiesOptions() { 262 try { 263 ActivityManagerNative.getDefault().setAlwaysFinish( 264 mImmediatelyDestroyActivities.isChecked()); 265 } catch (RemoteException ex) { 266 } 267 } 268 269 private void updateImmediatelyDestroyActivitiesOptions() { 270 mImmediatelyDestroyActivities.setChecked(Settings.System.getInt( 271 getActivity().getContentResolver(), Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0); 272 } 273 274 private void updateAnimationScaleValue(int which, ListPreference pref) { 275 try { 276 float scale = mWindowManager.getAnimationScale(which); 277 CharSequence[] values = pref.getEntryValues(); 278 for (int i=0; i<values.length; i++) { 279 float val = Float.parseFloat(values[i].toString()); 280 if (scale <= val) { 281 pref.setValueIndex(i); 282 pref.setSummary(pref.getEntries()[i]); 283 return; 284 } 285 } 286 pref.setValueIndex(values.length-1); 287 pref.setSummary(pref.getEntries()[0]); 288 } catch (RemoteException e) { 289 } 290 } 291 292 private void updateAnimationScaleOptions() { 293 updateAnimationScaleValue(0, mWindowAnimationScale); 294 updateAnimationScaleValue(1, mTransitionAnimationScale); 295 } 296 297 private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) { 298 try { 299 float scale = Float.parseFloat(newValue.toString()); 300 mWindowManager.setAnimationScale(which, scale); 301 } catch (RemoteException e) { 302 } 303 } 304 305 private void updateAppProcessLimitOptions() { 306 try { 307 int limit = ActivityManagerNative.getDefault().getProcessLimit(); 308 CharSequence[] values = mAppProcessLimit.getEntryValues(); 309 for (int i=0; i<values.length; i++) { 310 int val = Integer.parseInt(values[i].toString()); 311 if (val >= limit) { 312 mAppProcessLimit.setValueIndex(i); 313 mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]); 314 return; 315 } 316 } 317 mAppProcessLimit.setValueIndex(0); 318 mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]); 319 } catch (RemoteException e) { 320 } 321 } 322 323 private void writeAppProcessLimitOptions(Object newValue) { 324 try { 325 int limit = Integer.parseInt(newValue.toString()); 326 ActivityManagerNative.getDefault().setProcessLimit(limit); 327 } catch (RemoteException e) { 328 } 329 } 330 331 @Override 332 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 333 334 if (Utils.isMonkeyRunning()) { 335 return false; 336 } 337 338 if (preference == mEnableAdb) { 339 if (mEnableAdb.isChecked()) { 340 mOkClicked = false; 341 if (mOkDialog != null) dismissDialog(); 342 mOkDialog = new AlertDialog.Builder(getActivity()).setMessage( 343 getActivity().getResources().getString(R.string.adb_warning_message)) 344 .setTitle(R.string.adb_warning_title) 345 .setIcon(android.R.drawable.ic_dialog_alert) 346 .setPositiveButton(android.R.string.yes, this) 347 .setNegativeButton(android.R.string.no, this) 348 .show(); 349 mOkDialog.setOnDismissListener(this); 350 } else { 351 Settings.Secure.putInt(getActivity().getContentResolver(), 352 Settings.Secure.ADB_ENABLED, 0); 353 } 354 } else if (preference == mKeepScreenOn) { 355 Settings.System.putInt(getActivity().getContentResolver(), 356 Settings.System.STAY_ON_WHILE_PLUGGED_IN, 357 mKeepScreenOn.isChecked() ? 358 (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) : 0); 359 } else if (preference == mAllowMockLocation) { 360 Settings.Secure.putInt(getActivity().getContentResolver(), 361 Settings.Secure.ALLOW_MOCK_LOCATION, 362 mAllowMockLocation.isChecked() ? 1 : 0); 363 } else if (preference == mStrictMode) { 364 writeStrictModeVisualOptions(); 365 } else if (preference == mPointerLocation) { 366 writePointerLocationOptions(); 367 } else if (preference == mShowScreenUpdates) { 368 writeFlingerOptions(); 369 } else if (preference == mShowCpuUsage) { 370 writeCpuUsageOptions(); 371 } else if (preference == mImmediatelyDestroyActivities) { 372 writeImmediatelyDestroyActivitiesOptions(); 373 } 374 375 return false; 376 } 377 378 @Override 379 public boolean onPreferenceChange(Preference preference, Object newValue) { 380 if (HDCP_CHECKING_KEY.equals(preference.getKey())) { 381 SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString()); 382 updateHdcpValues(); 383 return true; 384 } else if (preference == mWindowAnimationScale) { 385 writeAnimationScaleOption(0, mWindowAnimationScale, newValue); 386 return true; 387 } else if (preference == mTransitionAnimationScale) { 388 writeAnimationScaleOption(1, mTransitionAnimationScale, newValue); 389 return true; 390 } else if (preference == mAppProcessLimit) { 391 writeAppProcessLimitOptions(newValue); 392 return true; 393 } 394 return false; 395 } 396 397 private void dismissDialog() { 398 if (mOkDialog == null) return; 399 mOkDialog.dismiss(); 400 mOkDialog = null; 401 } 402 403 public void onClick(DialogInterface dialog, int which) { 404 if (which == DialogInterface.BUTTON_POSITIVE) { 405 mOkClicked = true; 406 Settings.Secure.putInt(getActivity().getContentResolver(), 407 Settings.Secure.ADB_ENABLED, 1); 408 } else { 409 // Reset the toggle 410 mEnableAdb.setChecked(false); 411 } 412 } 413 414 public void onDismiss(DialogInterface dialog) { 415 // Assuming that onClick gets called first 416 if (!mOkClicked) { 417 mEnableAdb.setChecked(false); 418 } 419 } 420 421 @Override 422 public void onDestroy() { 423 dismissDialog(); 424 super.onDestroy(); 425 } 426} 427