DevelopmentSettings.java revision 2d803a3931797891a30158c1a912ce775049f974
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 static android.Manifest.permission.READ_EXTERNAL_STORAGE; 20 21import android.app.ActionBar; 22import android.app.Activity; 23import android.app.ActivityManagerNative; 24import android.app.ActivityThread; 25import android.app.AlertDialog; 26import android.app.Dialog; 27import android.app.DialogFragment; 28import android.app.admin.DevicePolicyManager; 29import android.app.backup.IBackupManager; 30import android.content.ContentResolver; 31import android.content.Context; 32import android.content.DialogInterface; 33import android.content.DialogInterface.OnClickListener; 34import android.content.Intent; 35import android.content.pm.ApplicationInfo; 36import android.content.pm.PackageManager; 37import android.os.AsyncTask; 38import android.os.BatteryManager; 39import android.os.Build; 40import android.os.Bundle; 41import android.os.IBinder; 42import android.os.Parcel; 43import android.os.RemoteException; 44import android.os.ServiceManager; 45import android.os.StrictMode; 46import android.os.SystemProperties; 47import android.os.Trace; 48import android.preference.CheckBoxPreference; 49import android.preference.ListPreference; 50import android.preference.MultiCheckPreference; 51import android.preference.Preference; 52import android.preference.Preference.OnPreferenceChangeListener; 53import android.preference.PreferenceFragment; 54import android.preference.PreferenceScreen; 55import android.provider.Settings; 56import android.text.TextUtils; 57import android.view.Gravity; 58import android.view.HardwareRenderer; 59import android.view.IWindowManager; 60import android.view.View; 61import android.widget.CompoundButton; 62import android.widget.Switch; 63 64import java.util.ArrayList; 65import java.util.HashSet; 66 67/* 68 * Displays preferences for application developers. 69 */ 70public class DevelopmentSettings extends PreferenceFragment 71 implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener, 72 OnPreferenceChangeListener, CompoundButton.OnCheckedChangeListener { 73 74 private static final String ENABLE_ADB = "enable_adb"; 75 private static final String KEEP_SCREEN_ON = "keep_screen_on"; 76 private static final String ALLOW_MOCK_LOCATION = "allow_mock_location"; 77 private static final String HDCP_CHECKING_KEY = "hdcp_checking"; 78 private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking"; 79 private static final String ENFORCE_READ_EXTERNAL = "enforce_read_external"; 80 private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password"; 81 private static final String HARDWARE_UI_PROPERTY = "persist.sys.ui.hw"; 82 private static final String BUGREPORT_IN_POWER_KEY = "bugreport_in_power"; 83 84 private static final String DEBUG_APP_KEY = "debug_app"; 85 private static final String WAIT_FOR_DEBUGGER_KEY = "wait_for_debugger"; 86 private static final String STRICT_MODE_KEY = "strict_mode"; 87 private static final String POINTER_LOCATION_KEY = "pointer_location"; 88 private static final String SHOW_TOUCHES_KEY = "show_touches"; 89 private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates"; 90 private static final String DISABLE_OVERLAYS_KEY = "disable_overlays"; 91 private static final String SHOW_CPU_USAGE_KEY = "show_cpu_usage"; 92 private static final String FORCE_HARDWARE_UI_KEY = "force_hw_ui"; 93 private static final String TRACK_FRAME_TIME_KEY = "track_frame_time"; 94 private static final String SHOW_HW_SCREEN_UPDATES_KEY = "show_hw_screen_udpates"; 95 private static final String DEBUG_LAYOUT_KEY = "debug_layout"; 96 private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale"; 97 private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale"; 98 private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale"; 99 100 private static final String ENABLE_TRACES_KEY = "enable_traces"; 101 102 private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY 103 = "immediately_destroy_activities"; 104 private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit"; 105 106 private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs"; 107 108 private static final String TAG_CONFIRM_ENFORCE = "confirm_enforce"; 109 110 private static final int RESULT_DEBUG_APP = 1000; 111 112 private IWindowManager mWindowManager; 113 private IBackupManager mBackupManager; 114 private DevicePolicyManager mDpm; 115 116 private Switch mEnabledSwitch; 117 private boolean mLastEnabledState; 118 private boolean mHaveDebugSettings; 119 private boolean mDontPokeProperties; 120 121 private CheckBoxPreference mEnableAdb; 122 private CheckBoxPreference mBugreportInPower; 123 private CheckBoxPreference mKeepScreenOn; 124 private CheckBoxPreference mEnforceReadExternal; 125 private CheckBoxPreference mAllowMockLocation; 126 private PreferenceScreen mPassword; 127 128 private String mDebugApp; 129 private Preference mDebugAppPref; 130 private CheckBoxPreference mWaitForDebugger; 131 132 private CheckBoxPreference mStrictMode; 133 private CheckBoxPreference mPointerLocation; 134 private CheckBoxPreference mShowTouches; 135 private CheckBoxPreference mShowScreenUpdates; 136 private CheckBoxPreference mDisableOverlays; 137 private CheckBoxPreference mShowCpuUsage; 138 private CheckBoxPreference mForceHardwareUi; 139 private CheckBoxPreference mTrackFrameTime; 140 private CheckBoxPreference mShowHwScreenUpdates; 141 private CheckBoxPreference mDebugLayout; 142 private ListPreference mWindowAnimationScale; 143 private ListPreference mTransitionAnimationScale; 144 private ListPreference mAnimatorDurationScale; 145 private MultiCheckPreference mEnableTracesPref; 146 147 private CheckBoxPreference mImmediatelyDestroyActivities; 148 private ListPreference mAppProcessLimit; 149 150 private CheckBoxPreference mShowAllANRs; 151 152 private final ArrayList<Preference> mAllPrefs = new ArrayList<Preference>(); 153 private final ArrayList<CheckBoxPreference> mResetCbPrefs 154 = new ArrayList<CheckBoxPreference>(); 155 156 private final HashSet<Preference> mDisabledPrefs = new HashSet<Preference>(); 157 158 // To track whether a confirmation dialog was clicked. 159 private boolean mDialogClicked; 160 private Dialog mEnableDialog; 161 private Dialog mAdbDialog; 162 163 @Override 164 public void onCreate(Bundle icicle) { 165 super.onCreate(icicle); 166 167 mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 168 mBackupManager = IBackupManager.Stub.asInterface( 169 ServiceManager.getService(Context.BACKUP_SERVICE)); 170 mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE); 171 172 addPreferencesFromResource(R.xml.development_prefs); 173 174 mEnableAdb = findAndInitCheckboxPref(ENABLE_ADB); 175 mBugreportInPower = findAndInitCheckboxPref(BUGREPORT_IN_POWER_KEY); 176 mKeepScreenOn = findAndInitCheckboxPref(KEEP_SCREEN_ON); 177 mEnforceReadExternal = findAndInitCheckboxPref(ENFORCE_READ_EXTERNAL); 178 mAllowMockLocation = findAndInitCheckboxPref(ALLOW_MOCK_LOCATION); 179 mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD); 180 mAllPrefs.add(mPassword); 181 182 mDebugAppPref = findPreference(DEBUG_APP_KEY); 183 mAllPrefs.add(mDebugAppPref); 184 mWaitForDebugger = findAndInitCheckboxPref(WAIT_FOR_DEBUGGER_KEY); 185 mStrictMode = findAndInitCheckboxPref(STRICT_MODE_KEY); 186 mPointerLocation = findAndInitCheckboxPref(POINTER_LOCATION_KEY); 187 mShowTouches = findAndInitCheckboxPref(SHOW_TOUCHES_KEY); 188 mShowScreenUpdates = findAndInitCheckboxPref(SHOW_SCREEN_UPDATES_KEY); 189 mDisableOverlays = findAndInitCheckboxPref(DISABLE_OVERLAYS_KEY); 190 mShowCpuUsage = findAndInitCheckboxPref(SHOW_CPU_USAGE_KEY); 191 mForceHardwareUi = findAndInitCheckboxPref(FORCE_HARDWARE_UI_KEY); 192 mTrackFrameTime = findAndInitCheckboxPref(TRACK_FRAME_TIME_KEY); 193 mShowHwScreenUpdates = findAndInitCheckboxPref(SHOW_HW_SCREEN_UPDATES_KEY); 194 mDebugLayout = findAndInitCheckboxPref(DEBUG_LAYOUT_KEY); 195 mWindowAnimationScale = (ListPreference) findPreference(WINDOW_ANIMATION_SCALE_KEY); 196 mAllPrefs.add(mWindowAnimationScale); 197 mWindowAnimationScale.setOnPreferenceChangeListener(this); 198 mTransitionAnimationScale = (ListPreference) findPreference(TRANSITION_ANIMATION_SCALE_KEY); 199 mAllPrefs.add(mTransitionAnimationScale); 200 mTransitionAnimationScale.setOnPreferenceChangeListener(this); 201 mAnimatorDurationScale = (ListPreference) findPreference(ANIMATOR_DURATION_SCALE_KEY); 202 mAllPrefs.add(mAnimatorDurationScale); 203 mAnimatorDurationScale.setOnPreferenceChangeListener(this); 204 mEnableTracesPref = (MultiCheckPreference)findPreference(ENABLE_TRACES_KEY); 205 String[] traceValues = new String[Trace.TRACE_TAGS.length]; 206 for (int i=Trace.TRACE_FLAGS_START_BIT; i<traceValues.length; i++) { 207 traceValues[i] = Integer.toString(1<<i); 208 } 209 mEnableTracesPref.setEntries(Trace.TRACE_TAGS); 210 mEnableTracesPref.setEntryValues(traceValues); 211 mAllPrefs.add(mEnableTracesPref); 212 mEnableTracesPref.setOnPreferenceChangeListener(this); 213 214 mImmediatelyDestroyActivities = (CheckBoxPreference) findPreference( 215 IMMEDIATELY_DESTROY_ACTIVITIES_KEY); 216 mAllPrefs.add(mImmediatelyDestroyActivities); 217 mResetCbPrefs.add(mImmediatelyDestroyActivities); 218 mAppProcessLimit = (ListPreference) findPreference(APP_PROCESS_LIMIT_KEY); 219 mAllPrefs.add(mAppProcessLimit); 220 mAppProcessLimit.setOnPreferenceChangeListener(this); 221 222 mShowAllANRs = (CheckBoxPreference) findPreference( 223 SHOW_ALL_ANRS_KEY); 224 mAllPrefs.add(mShowAllANRs); 225 mResetCbPrefs.add(mShowAllANRs); 226 227 Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY); 228 if (hdcpChecking != null) { 229 mAllPrefs.add(hdcpChecking); 230 } 231 removeHdcpOptionsForProduction(); 232 } 233 234 private CheckBoxPreference findAndInitCheckboxPref(String key) { 235 CheckBoxPreference pref = (CheckBoxPreference) findPreference(key); 236 if (pref == null) { 237 throw new IllegalArgumentException("Cannot find preference with key = " + key); 238 } 239 mAllPrefs.add(pref); 240 mResetCbPrefs.add(pref); 241 return pref; 242 } 243 244 @Override 245 public void onActivityCreated(Bundle savedInstanceState) { 246 super.onActivityCreated(savedInstanceState); 247 248 final Activity activity = getActivity(); 249 mEnabledSwitch = new Switch(activity); 250 251 final int padding = activity.getResources().getDimensionPixelSize( 252 R.dimen.action_bar_switch_padding); 253 mEnabledSwitch.setPadding(0, 0, padding, 0); 254 mEnabledSwitch.setOnCheckedChangeListener(this); 255 } 256 257 @Override 258 public void onStart() { 259 super.onStart(); 260 final Activity activity = getActivity(); 261 activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, 262 ActionBar.DISPLAY_SHOW_CUSTOM); 263 activity.getActionBar().setCustomView(mEnabledSwitch, new ActionBar.LayoutParams( 264 ActionBar.LayoutParams.WRAP_CONTENT, 265 ActionBar.LayoutParams.WRAP_CONTENT, 266 Gravity.CENTER_VERTICAL | Gravity.END)); 267 } 268 269 @Override 270 public void onStop() { 271 super.onStop(); 272 final Activity activity = getActivity(); 273 activity.getActionBar().setDisplayOptions(0, ActionBar.DISPLAY_SHOW_CUSTOM); 274 activity.getActionBar().setCustomView(null); 275 } 276 277 private void removeHdcpOptionsForProduction() { 278 if ("user".equals(Build.TYPE)) { 279 Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY); 280 if (hdcpChecking != null) { 281 // Remove the preference 282 getPreferenceScreen().removePreference(hdcpChecking); 283 mAllPrefs.remove(hdcpChecking); 284 } 285 } 286 } 287 288 private void setPrefsEnabledState(boolean enabled) { 289 for (int i = 0; i < mAllPrefs.size(); i++) { 290 Preference pref = mAllPrefs.get(i); 291 pref.setEnabled(enabled && !mDisabledPrefs.contains(pref)); 292 } 293 updateAllOptions(); 294 } 295 296 @Override 297 public void onResume() { 298 super.onResume(); 299 300 if (mDpm.getMaximumTimeToLock(null) > 0) { 301 // A DeviceAdmin has specified a maximum time until the device 302 // will lock... in this case we can't allow the user to turn 303 // on "stay awake when plugged in" because that would defeat the 304 // restriction. 305 mDisabledPrefs.add(mKeepScreenOn); 306 } else { 307 mDisabledPrefs.remove(mKeepScreenOn); 308 } 309 310 final ContentResolver cr = getActivity().getContentResolver(); 311 mLastEnabledState = Settings.Secure.getInt(cr, 312 Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0; 313 mEnabledSwitch.setChecked(mLastEnabledState); 314 setPrefsEnabledState(mLastEnabledState); 315 316 if (mHaveDebugSettings && !mLastEnabledState) { 317 // Overall debugging is disabled, but there are some debug 318 // settings that are enabled. This is an invalid state. Switch 319 // to debug settings being enabled, so the user knows there is 320 // stuff enabled and can turn it all off if they want. 321 Settings.Secure.putInt(getActivity().getContentResolver(), 322 Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED, 1); 323 mLastEnabledState = true; 324 setPrefsEnabledState(mLastEnabledState); 325 } 326 } 327 328 void updateCheckBox(CheckBoxPreference checkBox, boolean value) { 329 checkBox.setChecked(value); 330 mHaveDebugSettings |= value; 331 } 332 333 private void updateAllOptions() { 334 final Context context = getActivity(); 335 final ContentResolver cr = context.getContentResolver(); 336 mHaveDebugSettings = false; 337 updateCheckBox(mEnableAdb, Settings.Secure.getInt(cr, 338 Settings.Secure.ADB_ENABLED, 0) != 0); 339 updateCheckBox(mBugreportInPower, Settings.Secure.getInt(cr, 340 Settings.Secure.BUGREPORT_IN_POWER_MENU, 0) != 0); 341 updateCheckBox(mKeepScreenOn, Settings.System.getInt(cr, 342 Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0) != 0); 343 updateCheckBox(mEnforceReadExternal, isPermissionEnforced(context, READ_EXTERNAL_STORAGE)); 344 updateCheckBox(mAllowMockLocation, Settings.Secure.getInt(cr, 345 Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0); 346 updateHdcpValues(); 347 updatePasswordSummary(); 348 updateDebuggerOptions(); 349 updateStrictModeVisualOptions(); 350 updatePointerLocationOptions(); 351 updateShowTouchesOptions(); 352 updateFlingerOptions(); 353 updateCpuUsageOptions(); 354 updateHardwareUiOptions(); 355 updateTrackFrameTimeOptions(); 356 updateShowHwScreenUpdatesOptions(); 357 updateDebugLayoutOptions(); 358 updateAnimationScaleOptions(); 359 updateEnableTracesOptions(); 360 updateImmediatelyDestroyActivitiesOptions(); 361 updateAppProcessLimitOptions(); 362 updateShowAllANRsOptions(); 363 } 364 365 private void resetDangerousOptions() { 366 mDontPokeProperties = true; 367 for (int i=0; i<mResetCbPrefs.size(); i++) { 368 CheckBoxPreference cb = mResetCbPrefs.get(i); 369 if (cb.isChecked()) { 370 cb.setChecked(false); 371 onPreferenceTreeClick(null, cb); 372 } 373 } 374 resetDebuggerOptions(); 375 writeAnimationScaleOption(0, mWindowAnimationScale, null); 376 writeAnimationScaleOption(1, mTransitionAnimationScale, null); 377 writeAnimationScaleOption(2, mAnimatorDurationScale, null); 378 writeEnableTracesOptions(0); 379 writeAppProcessLimitOptions(null); 380 mHaveDebugSettings = false; 381 updateAllOptions(); 382 mDontPokeProperties = false; 383 pokeSystemProperties(); 384 } 385 386 private void updateHdcpValues() { 387 int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values 388 ListPreference hdcpChecking = (ListPreference) findPreference(HDCP_CHECKING_KEY); 389 if (hdcpChecking != null) { 390 String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY); 391 String[] values = getResources().getStringArray(R.array.hdcp_checking_values); 392 String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries); 393 for (int i = 0; i < values.length; i++) { 394 if (currentValue.equals(values[i])) { 395 index = i; 396 break; 397 } 398 } 399 hdcpChecking.setValue(values[index]); 400 hdcpChecking.setSummary(summaries[index]); 401 hdcpChecking.setOnPreferenceChangeListener(this); 402 } 403 } 404 405 private void updatePasswordSummary() { 406 try { 407 if (mBackupManager.hasBackupPassword()) { 408 mPassword.setSummary(R.string.local_backup_password_summary_change); 409 } else { 410 mPassword.setSummary(R.string.local_backup_password_summary_none); 411 } 412 } catch (RemoteException e) { 413 // Not much we can do here 414 } 415 } 416 417 private void writeDebuggerOptions() { 418 try { 419 ActivityManagerNative.getDefault().setDebugApp( 420 mDebugApp, mWaitForDebugger.isChecked(), true); 421 } catch (RemoteException ex) { 422 } 423 } 424 425 private static void resetDebuggerOptions() { 426 try { 427 ActivityManagerNative.getDefault().setDebugApp( 428 null, false, true); 429 } catch (RemoteException ex) { 430 } 431 } 432 433 private void updateDebuggerOptions() { 434 mDebugApp = Settings.System.getString( 435 getActivity().getContentResolver(), Settings.System.DEBUG_APP); 436 updateCheckBox(mWaitForDebugger, Settings.System.getInt( 437 getActivity().getContentResolver(), Settings.System.WAIT_FOR_DEBUGGER, 0) != 0); 438 if (mDebugApp != null && mDebugApp.length() > 0) { 439 String label; 440 try { 441 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(mDebugApp, 442 PackageManager.GET_DISABLED_COMPONENTS); 443 CharSequence lab = getActivity().getPackageManager().getApplicationLabel(ai); 444 label = lab != null ? lab.toString() : mDebugApp; 445 } catch (PackageManager.NameNotFoundException e) { 446 label = mDebugApp; 447 } 448 mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_set, label)); 449 mWaitForDebugger.setEnabled(true); 450 mHaveDebugSettings = true; 451 } else { 452 mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_not_set)); 453 mWaitForDebugger.setEnabled(false); 454 } 455 } 456 457 // Returns the current state of the system property that controls 458 // strictmode flashes. One of: 459 // 0: not explicitly set one way or another 460 // 1: on 461 // 2: off 462 private static int currentStrictModeActiveIndex() { 463 if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) { 464 return 0; 465 } 466 boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false); 467 return enabled ? 1 : 2; 468 } 469 470 private void writeStrictModeVisualOptions() { 471 try { 472 mWindowManager.setStrictModeVisualIndicatorPreference(mStrictMode.isChecked() 473 ? "1" : ""); 474 } catch (RemoteException e) { 475 } 476 } 477 478 private void updateStrictModeVisualOptions() { 479 updateCheckBox(mStrictMode, currentStrictModeActiveIndex() == 1); 480 } 481 482 private void writePointerLocationOptions() { 483 Settings.System.putInt(getActivity().getContentResolver(), 484 Settings.System.POINTER_LOCATION, mPointerLocation.isChecked() ? 1 : 0); 485 } 486 487 private void updatePointerLocationOptions() { 488 updateCheckBox(mPointerLocation, Settings.System.getInt(getActivity().getContentResolver(), 489 Settings.System.POINTER_LOCATION, 0) != 0); 490 } 491 492 private void writeShowTouchesOptions() { 493 Settings.System.putInt(getActivity().getContentResolver(), 494 Settings.System.SHOW_TOUCHES, mShowTouches.isChecked() ? 1 : 0); 495 } 496 497 private void updateShowTouchesOptions() { 498 updateCheckBox(mShowTouches, Settings.System.getInt(getActivity().getContentResolver(), 499 Settings.System.SHOW_TOUCHES, 0) != 0); 500 } 501 502 private void updateFlingerOptions() { 503 // magic communication with surface flinger. 504 try { 505 IBinder flinger = ServiceManager.getService("SurfaceFlinger"); 506 if (flinger != null) { 507 Parcel data = Parcel.obtain(); 508 Parcel reply = Parcel.obtain(); 509 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 510 flinger.transact(1010, data, reply, 0); 511 @SuppressWarnings("unused") 512 int showCpu = reply.readInt(); 513 @SuppressWarnings("unused") 514 int enableGL = reply.readInt(); 515 int showUpdates = reply.readInt(); 516 updateCheckBox(mShowScreenUpdates, showUpdates != 0); 517 @SuppressWarnings("unused") 518 int showBackground = reply.readInt(); 519 int disableOverlays = reply.readInt(); 520 updateCheckBox(mDisableOverlays, disableOverlays != 0); 521 reply.recycle(); 522 data.recycle(); 523 } 524 } catch (RemoteException ex) { 525 } 526 } 527 528 private void writeShowUpdatesOption() { 529 try { 530 IBinder flinger = ServiceManager.getService("SurfaceFlinger"); 531 if (flinger != null) { 532 Parcel data = Parcel.obtain(); 533 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 534 final int showUpdates = mShowScreenUpdates.isChecked() ? 1 : 0; 535 data.writeInt(showUpdates); 536 flinger.transact(1002, data, null, 0); 537 data.recycle(); 538 539 updateFlingerOptions(); 540 } 541 } catch (RemoteException ex) { 542 } 543 } 544 545 private void writeDisableOverlaysOption() { 546 try { 547 IBinder flinger = ServiceManager.getService("SurfaceFlinger"); 548 if (flinger != null) { 549 Parcel data = Parcel.obtain(); 550 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 551 final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0; 552 data.writeInt(disableOverlays); 553 flinger.transact(1008, data, null, 0); 554 data.recycle(); 555 556 updateFlingerOptions(); 557 } 558 } catch (RemoteException ex) { 559 } 560 } 561 562 private void updateHardwareUiOptions() { 563 updateCheckBox(mForceHardwareUi, SystemProperties.getBoolean(HARDWARE_UI_PROPERTY, false)); 564 } 565 566 private void writeHardwareUiOptions() { 567 SystemProperties.set(HARDWARE_UI_PROPERTY, mForceHardwareUi.isChecked() ? "true" : "false"); 568 pokeSystemProperties(); 569 } 570 571 private void updateTrackFrameTimeOptions() { 572 updateCheckBox(mTrackFrameTime, 573 SystemProperties.getBoolean(HardwareRenderer.PROFILE_PROPERTY, false)); 574 } 575 576 private void writeTrackFrameTimeOptions() { 577 SystemProperties.set(HardwareRenderer.PROFILE_PROPERTY, 578 mTrackFrameTime.isChecked() ? "true" : "false"); 579 pokeSystemProperties(); 580 } 581 582 private void updateShowHwScreenUpdatesOptions() { 583 updateCheckBox(mShowHwScreenUpdates, 584 SystemProperties.getBoolean(HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, false)); 585 } 586 587 private void writeShowHwScreenUpdatesOptions() { 588 SystemProperties.set(HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, 589 mShowHwScreenUpdates.isChecked() ? "true" : "false"); 590 pokeSystemProperties(); 591 } 592 593 private void updateDebugLayoutOptions() { 594 updateCheckBox(mDebugLayout, 595 SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false)); 596 } 597 598 private void writeDebugLayoutOptions() { 599 SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY, 600 mDebugLayout.isChecked() ? "true" : "false"); 601 pokeSystemProperties(); 602 } 603 604 private void updateCpuUsageOptions() { 605 updateCheckBox(mShowCpuUsage, Settings.System.getInt(getActivity().getContentResolver(), 606 Settings.System.SHOW_PROCESSES, 0) != 0); 607 } 608 609 private void writeCpuUsageOptions() { 610 boolean value = mShowCpuUsage.isChecked(); 611 Settings.System.putInt(getActivity().getContentResolver(), 612 Settings.System.SHOW_PROCESSES, value ? 1 : 0); 613 Intent service = (new Intent()) 614 .setClassName("com.android.systemui", "com.android.systemui.LoadAverageService"); 615 if (value) { 616 getActivity().startService(service); 617 } else { 618 getActivity().stopService(service); 619 } 620 } 621 622 private void writeImmediatelyDestroyActivitiesOptions() { 623 try { 624 ActivityManagerNative.getDefault().setAlwaysFinish( 625 mImmediatelyDestroyActivities.isChecked()); 626 } catch (RemoteException ex) { 627 } 628 } 629 630 private void updateImmediatelyDestroyActivitiesOptions() { 631 updateCheckBox(mImmediatelyDestroyActivities, Settings.System.getInt( 632 getActivity().getContentResolver(), Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0); 633 } 634 635 private void updateAnimationScaleValue(int which, ListPreference pref) { 636 try { 637 float scale = mWindowManager.getAnimationScale(which); 638 if (scale != 1) { 639 mHaveDebugSettings = true; 640 } 641 CharSequence[] values = pref.getEntryValues(); 642 for (int i=0; i<values.length; i++) { 643 float val = Float.parseFloat(values[i].toString()); 644 if (scale <= val) { 645 pref.setValueIndex(i); 646 pref.setSummary(pref.getEntries()[i]); 647 return; 648 } 649 } 650 pref.setValueIndex(values.length-1); 651 pref.setSummary(pref.getEntries()[0]); 652 } catch (RemoteException e) { 653 } 654 } 655 656 private void updateAnimationScaleOptions() { 657 updateAnimationScaleValue(0, mWindowAnimationScale); 658 updateAnimationScaleValue(1, mTransitionAnimationScale); 659 updateAnimationScaleValue(2, mAnimatorDurationScale); 660 } 661 662 private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) { 663 try { 664 float scale = newValue != null ? Float.parseFloat(newValue.toString()) : 1; 665 mWindowManager.setAnimationScale(which, scale); 666 updateAnimationScaleValue(which, pref); 667 } catch (RemoteException e) { 668 } 669 } 670 671 private void updateAppProcessLimitOptions() { 672 try { 673 int limit = ActivityManagerNative.getDefault().getProcessLimit(); 674 CharSequence[] values = mAppProcessLimit.getEntryValues(); 675 for (int i=0; i<values.length; i++) { 676 int val = Integer.parseInt(values[i].toString()); 677 if (val >= limit) { 678 if (i != 0) { 679 mHaveDebugSettings = true; 680 } 681 mAppProcessLimit.setValueIndex(i); 682 mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]); 683 return; 684 } 685 } 686 mAppProcessLimit.setValueIndex(0); 687 mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]); 688 } catch (RemoteException e) { 689 } 690 } 691 692 private void writeAppProcessLimitOptions(Object newValue) { 693 try { 694 int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1; 695 ActivityManagerNative.getDefault().setProcessLimit(limit); 696 updateAppProcessLimitOptions(); 697 } catch (RemoteException e) { 698 } 699 } 700 701 private void writeShowAllANRsOptions() { 702 Settings.Secure.putInt(getActivity().getContentResolver(), 703 Settings.Secure.ANR_SHOW_BACKGROUND, 704 mShowAllANRs.isChecked() ? 1 : 0); 705 } 706 707 private void updateShowAllANRsOptions() { 708 updateCheckBox(mShowAllANRs, Settings.Secure.getInt( 709 getActivity().getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0); 710 } 711 712 private void updateEnableTracesOptions() { 713 String strValue = SystemProperties.get(Trace.PROPERTY_TRACE_TAG_ENABLEFLAGS); 714 long flags = SystemProperties.getLong(Trace.PROPERTY_TRACE_TAG_ENABLEFLAGS, 0); 715 String[] values = mEnableTracesPref.getEntryValues(); 716 int numSet = 0; 717 for (int i=Trace.TRACE_FLAGS_START_BIT; i<values.length; i++) { 718 boolean set = (flags&(1<<i)) != 0; 719 mEnableTracesPref.setValue(i-Trace.TRACE_FLAGS_START_BIT, set); 720 if (set) { 721 numSet++; 722 } 723 } 724 if (numSet == 0) { 725 mEnableTracesPref.setSummary(R.string.enable_traces_summary_none); 726 } else if (numSet == values.length) { 727 mHaveDebugSettings = true; 728 mEnableTracesPref.setSummary(R.string.enable_traces_summary_all); 729 } else { 730 mHaveDebugSettings = true; 731 mEnableTracesPref.setSummary(getString(R.string.enable_traces_summary_num, numSet)); 732 } 733 } 734 735 private void writeEnableTracesOptions() { 736 long value = 0; 737 String[] values = mEnableTracesPref.getEntryValues(); 738 for (int i=Trace.TRACE_FLAGS_START_BIT; i<values.length; i++) { 739 if (mEnableTracesPref.getValue(i-Trace.TRACE_FLAGS_START_BIT)) { 740 value |= 1<<i; 741 } 742 } 743 writeEnableTracesOptions(value); 744 // Make sure summary is updated. 745 updateEnableTracesOptions(); 746 } 747 748 private void writeEnableTracesOptions(long value) { 749 SystemProperties.set(Trace.PROPERTY_TRACE_TAG_ENABLEFLAGS, 750 "0x" + Long.toString(value, 16)); 751 pokeSystemProperties(); 752 } 753 754 @Override 755 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 756 if (buttonView == mEnabledSwitch) { 757 if (isChecked != mLastEnabledState) { 758 if (isChecked) { 759 mDialogClicked = false; 760 if (mEnableDialog != null) dismissDialogs(); 761 mEnableDialog = new AlertDialog.Builder(getActivity()).setMessage( 762 getActivity().getResources().getString( 763 R.string.dev_settings_warning_message)) 764 .setTitle(R.string.dev_settings_warning_title) 765 .setIcon(android.R.drawable.ic_dialog_alert) 766 .setPositiveButton(android.R.string.yes, this) 767 .setNegativeButton(android.R.string.no, this) 768 .show(); 769 mEnableDialog.setOnDismissListener(this); 770 } else { 771 resetDangerousOptions(); 772 Settings.Secure.putInt(getActivity().getContentResolver(), 773 Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED, 0); 774 mLastEnabledState = isChecked; 775 setPrefsEnabledState(mLastEnabledState); 776 } 777 } 778 } 779 } 780 781 @Override 782 public void onActivityResult(int requestCode, int resultCode, Intent data) { 783 if (requestCode == RESULT_DEBUG_APP) { 784 if (resultCode == Activity.RESULT_OK) { 785 mDebugApp = data.getAction(); 786 writeDebuggerOptions(); 787 updateDebuggerOptions(); 788 } 789 } else { 790 super.onActivityResult(requestCode, resultCode, data); 791 } 792 } 793 794 @Override 795 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 796 797 if (Utils.isMonkeyRunning()) { 798 return false; 799 } 800 801 if (preference == mEnableAdb) { 802 if (mEnableAdb.isChecked()) { 803 mDialogClicked = false; 804 if (mAdbDialog != null) dismissDialogs(); 805 mAdbDialog = new AlertDialog.Builder(getActivity()).setMessage( 806 getActivity().getResources().getString(R.string.adb_warning_message)) 807 .setTitle(R.string.adb_warning_title) 808 .setIcon(android.R.drawable.ic_dialog_alert) 809 .setPositiveButton(android.R.string.yes, this) 810 .setNegativeButton(android.R.string.no, this) 811 .show(); 812 mAdbDialog.setOnDismissListener(this); 813 } else { 814 Settings.Secure.putInt(getActivity().getContentResolver(), 815 Settings.Secure.ADB_ENABLED, 0); 816 } 817 } else if (preference == mBugreportInPower) { 818 Settings.Secure.putInt(getActivity().getContentResolver(), 819 Settings.Secure.BUGREPORT_IN_POWER_MENU, 820 mBugreportInPower.isChecked() ? 1 : 0); 821 } else if (preference == mKeepScreenOn) { 822 Settings.System.putInt(getActivity().getContentResolver(), 823 Settings.System.STAY_ON_WHILE_PLUGGED_IN, 824 mKeepScreenOn.isChecked() ? 825 (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) : 0); 826 } else if (preference == mEnforceReadExternal) { 827 if (mEnforceReadExternal.isChecked()) { 828 ConfirmEnforceFragment.show(this); 829 } else { 830 setPermissionEnforced(getActivity(), READ_EXTERNAL_STORAGE, false); 831 } 832 } else if (preference == mAllowMockLocation) { 833 Settings.Secure.putInt(getActivity().getContentResolver(), 834 Settings.Secure.ALLOW_MOCK_LOCATION, 835 mAllowMockLocation.isChecked() ? 1 : 0); 836 } else if (preference == mDebugAppPref) { 837 startActivityForResult(new Intent(getActivity(), AppPicker.class), RESULT_DEBUG_APP); 838 } else if (preference == mWaitForDebugger) { 839 writeDebuggerOptions(); 840 } else if (preference == mStrictMode) { 841 writeStrictModeVisualOptions(); 842 } else if (preference == mPointerLocation) { 843 writePointerLocationOptions(); 844 } else if (preference == mShowTouches) { 845 writeShowTouchesOptions(); 846 } else if (preference == mShowScreenUpdates) { 847 writeShowUpdatesOption(); 848 } else if (preference == mDisableOverlays) { 849 writeDisableOverlaysOption(); 850 } else if (preference == mShowCpuUsage) { 851 writeCpuUsageOptions(); 852 } else if (preference == mImmediatelyDestroyActivities) { 853 writeImmediatelyDestroyActivitiesOptions(); 854 } else if (preference == mShowAllANRs) { 855 writeShowAllANRsOptions(); 856 } else if (preference == mForceHardwareUi) { 857 writeHardwareUiOptions(); 858 } else if (preference == mTrackFrameTime) { 859 writeTrackFrameTimeOptions(); 860 } else if (preference == mShowHwScreenUpdates) { 861 writeShowHwScreenUpdatesOptions(); 862 } else if (preference == mDebugLayout) { 863 writeDebugLayoutOptions(); 864 } 865 866 return false; 867 } 868 869 @Override 870 public boolean onPreferenceChange(Preference preference, Object newValue) { 871 if (HDCP_CHECKING_KEY.equals(preference.getKey())) { 872 SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString()); 873 updateHdcpValues(); 874 pokeSystemProperties(); 875 return true; 876 } else if (preference == mWindowAnimationScale) { 877 writeAnimationScaleOption(0, mWindowAnimationScale, newValue); 878 return true; 879 } else if (preference == mTransitionAnimationScale) { 880 writeAnimationScaleOption(1, mTransitionAnimationScale, newValue); 881 return true; 882 } else if (preference == mAnimatorDurationScale) { 883 writeAnimationScaleOption(2, mAnimatorDurationScale, newValue); 884 return true; 885 } else if (preference == mEnableTracesPref) { 886 writeEnableTracesOptions(); 887 return true; 888 } else if (preference == mAppProcessLimit) { 889 writeAppProcessLimitOptions(newValue); 890 return true; 891 } 892 return false; 893 } 894 895 private void dismissDialogs() { 896 if (mAdbDialog != null) { 897 mAdbDialog.dismiss(); 898 mAdbDialog = null; 899 } 900 if (mEnableDialog != null) { 901 mEnableDialog.dismiss(); 902 mEnableDialog = null; 903 } 904 } 905 906 public void onClick(DialogInterface dialog, int which) { 907 if (dialog == mAdbDialog) { 908 if (which == DialogInterface.BUTTON_POSITIVE) { 909 mDialogClicked = true; 910 Settings.Secure.putInt(getActivity().getContentResolver(), 911 Settings.Secure.ADB_ENABLED, 1); 912 } else { 913 // Reset the toggle 914 mEnableAdb.setChecked(false); 915 } 916 } else if (dialog == mEnableDialog) { 917 if (which == DialogInterface.BUTTON_POSITIVE) { 918 mDialogClicked = true; 919 Settings.Secure.putInt(getActivity().getContentResolver(), 920 Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED, 1); 921 mLastEnabledState = true; 922 setPrefsEnabledState(mLastEnabledState); 923 } else { 924 // Reset the toggle 925 mEnabledSwitch.setChecked(false); 926 } 927 } 928 } 929 930 public void onDismiss(DialogInterface dialog) { 931 // Assuming that onClick gets called first 932 if (dialog == mAdbDialog) { 933 if (!mDialogClicked) { 934 mEnableAdb.setChecked(false); 935 } 936 mAdbDialog = null; 937 } else if (dialog == mEnableDialog) { 938 if (!mDialogClicked) { 939 mEnabledSwitch.setChecked(false); 940 } 941 mEnableDialog = null; 942 } 943 } 944 945 @Override 946 public void onDestroy() { 947 dismissDialogs(); 948 super.onDestroy(); 949 } 950 951 void pokeSystemProperties() { 952 if (!mDontPokeProperties) { 953 (new SystemPropPoker()).execute(); 954 } 955 } 956 957 static class SystemPropPoker extends AsyncTask<Void, Void, Void> { 958 @Override 959 protected Void doInBackground(Void... params) { 960 String[] services; 961 try { 962 services = ServiceManager.listServices(); 963 } catch (RemoteException e) { 964 return null; 965 } 966 for (String service : services) { 967 IBinder obj = ServiceManager.checkService(service); 968 if (obj != null) { 969 Parcel data = Parcel.obtain(); 970 try { 971 obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0); 972 } catch (RemoteException e) { 973 } 974 data.recycle(); 975 } 976 } 977 return null; 978 } 979 } 980 981 /** 982 * Dialog to confirm enforcement of {@link #READ_EXTERNAL_STORAGE}. 983 */ 984 public static class ConfirmEnforceFragment extends DialogFragment { 985 public static void show(DevelopmentSettings parent) { 986 final ConfirmEnforceFragment dialog = new ConfirmEnforceFragment(); 987 dialog.setTargetFragment(parent, 0); 988 dialog.show(parent.getFragmentManager(), TAG_CONFIRM_ENFORCE); 989 } 990 991 @Override 992 public Dialog onCreateDialog(Bundle savedInstanceState) { 993 final Context context = getActivity(); 994 995 final AlertDialog.Builder builder = new AlertDialog.Builder(context); 996 builder.setTitle(R.string.enforce_read_external_confirm_title); 997 builder.setMessage(R.string.enforce_read_external_confirm_message); 998 999 builder.setPositiveButton(android.R.string.ok, new OnClickListener() { 1000 @Override 1001 public void onClick(DialogInterface dialog, int which) { 1002 setPermissionEnforced(context, READ_EXTERNAL_STORAGE, true); 1003 ((DevelopmentSettings) getTargetFragment()).updateAllOptions(); 1004 } 1005 }); 1006 builder.setNegativeButton(android.R.string.cancel, new OnClickListener() { 1007 @Override 1008 public void onClick(DialogInterface dialog, int which) { 1009 ((DevelopmentSettings) getTargetFragment()).updateAllOptions(); 1010 } 1011 }); 1012 1013 return builder.create(); 1014 } 1015 } 1016 1017 private static boolean isPermissionEnforced(Context context, String permission) { 1018 try { 1019 return ActivityThread.getPackageManager().isPermissionEnforced(READ_EXTERNAL_STORAGE); 1020 } catch (RemoteException e) { 1021 throw new RuntimeException("Problem talking with PackageManager", e); 1022 } 1023 } 1024 1025 private static void setPermissionEnforced( 1026 Context context, String permission, boolean enforced) { 1027 try { 1028 // TODO: offload to background thread 1029 ActivityThread.getPackageManager() 1030 .setPermissionEnforced(READ_EXTERNAL_STORAGE, enforced); 1031 } catch (RemoteException e) { 1032 throw new RuntimeException("Problem talking with PackageManager", e); 1033 } 1034 } 1035} 1036