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