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