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