1 /* 2 * Copyright (C) 2015 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 17 package com.android.tv.settings.system.development; 18 19 import static android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED; 20 21 import static com.android.tv.settings.overlay.FlavorUtils.X_EXPERIENCE_FLAVORS_MASK; 22 23 import android.Manifest; 24 import android.app.Activity; 25 import android.app.ActivityManager; 26 import android.app.AppOpsManager; 27 import android.app.admin.DevicePolicyManager; 28 import android.app.backup.IBackupManager; 29 import android.content.BroadcastReceiver; 30 import android.content.ComponentName; 31 import android.content.ContentResolver; 32 import android.content.Context; 33 import android.content.Intent; 34 import android.content.IntentFilter; 35 import android.content.pm.ApplicationInfo; 36 import android.content.pm.PackageManager; 37 import android.content.pm.ResolveInfo; 38 import android.database.ContentObserver; 39 import android.hardware.usb.UsbManager; 40 import android.media.MediaRecorder.AudioSource; 41 import android.net.ConnectivityManager; 42 import android.net.Network; 43 import android.net.NetworkCapabilities; 44 import android.net.NetworkInfo; 45 import android.net.NetworkRequest; 46 import android.net.Uri; 47 import android.net.wifi.WifiManager; 48 import android.os.BatteryManager; 49 import android.os.Build; 50 import android.os.Bundle; 51 import android.os.Handler; 52 import android.os.IBinder; 53 import android.os.Looper; 54 import android.os.Parcel; 55 import android.os.RemoteException; 56 import android.os.ServiceManager; 57 import android.os.StrictMode; 58 import android.os.SystemProperties; 59 import android.os.UserManager; 60 import android.provider.Settings; 61 import android.sysprop.AdbProperties; 62 import android.sysprop.DisplayProperties; 63 import android.text.TextUtils; 64 import android.util.Log; 65 import android.util.Pair; 66 import android.view.IWindowManager; 67 import android.view.LayoutInflater; 68 import android.view.ThreadedRenderer; 69 import android.view.View; 70 import android.view.ViewGroup; 71 import android.view.accessibility.AccessibilityManager; 72 import android.widget.Toast; 73 74 import androidx.preference.ListPreference; 75 import androidx.preference.Preference; 76 import androidx.preference.PreferenceGroup; 77 import androidx.preference.PreferenceScreen; 78 import androidx.preference.TwoStatePreference; 79 80 import com.android.internal.app.LocalePicker; 81 import com.android.settingslib.core.ConfirmationDialogController; 82 import com.android.settingslib.development.DevelopmentSettingsEnabler; 83 import com.android.settingslib.development.SystemPropPoker; 84 import com.android.tv.settings.R; 85 import com.android.tv.settings.RestrictedPreferenceAdapter; 86 import com.android.tv.settings.SettingsPreferenceFragment; 87 import com.android.tv.settings.overlay.FlavorUtils; 88 import com.android.tv.settings.system.development.audio.AudioDebug; 89 import com.android.tv.settings.system.development.audio.AudioMetrics; 90 import com.android.tv.settings.system.development.audio.AudioReaderException; 91 92 import java.util.ArrayList; 93 import java.util.HashSet; 94 import java.util.List; 95 import java.util.Optional; 96 97 /** 98 * Displays preferences for application developers. 99 */ 100 public class DevelopmentFragment extends SettingsPreferenceFragment 101 implements Preference.OnPreferenceChangeListener, 102 EnableDevelopmentDialog.Callback, OemUnlockDialog.Callback, AdbDialog.Callback { 103 private static final String TAG = "DevelopmentSettings"; 104 105 private static final String ENABLE_DEVELOPER = "development_settings_enable"; 106 private static final String ENABLE_ADB = "enable_adb"; 107 private static final String CLEAR_ADB_KEYS = "clear_adb_keys"; 108 private static final String ENABLE_TERMINAL = "enable_terminal"; 109 private static final String KEEP_SCREEN_ON = "keep_screen_on"; 110 private static final String BT_HCI_SNOOP_LOG = "bt_hci_snoop_log"; 111 private static final String BTSNOOP_LOG_MODE_PROPERTY = "persist.bluetooth.btsnooplogmode"; 112 private static final String ENABLE_OEM_UNLOCK = "oem_unlock_enable"; 113 private static final String HDCP_CHECKING_KEY = "hdcp_checking"; 114 private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking"; 115 private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password"; 116 private static final String BUGREPORT = "bugreport"; 117 private static final String BUGREPORT_IN_POWER_KEY = "bugreport_in_power"; 118 private static final String RUNNING_APPS = "running_apps"; 119 120 private static final String DEBUG_APP_KEY = "debug_app"; 121 private static final String WAIT_FOR_DEBUGGER_KEY = "wait_for_debugger"; 122 private static final String MOCK_LOCATION_APP_KEY = "mock_location_app"; 123 private static final String VERIFY_APPS_OVER_USB_KEY = "verify_apps_over_usb"; 124 private static final String DEBUG_VIEW_ATTRIBUTES = "debug_view_attributes"; 125 private static final String FORCE_ALLOW_ON_EXTERNAL_KEY = "force_allow_on_external"; 126 private static final String STRICT_MODE_KEY = "strict_mode"; 127 private static final String POINTER_LOCATION_KEY = "pointer_location"; 128 private static final String SHOW_TOUCHES_KEY = "show_touches"; 129 private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates"; 130 private static final String DISABLE_OVERLAYS_KEY = "disable_overlays"; 131 private static final String SIMULATE_COLOR_SPACE = "simulate_color_space"; 132 private static final String USB_AUDIO_KEY = "usb_audio"; 133 private static final String RECORD_AUDIO_KEY = "record_audio"; 134 private static final String PLAY_RECORDED_AUDIO_KEY = "play_recorded_audio"; 135 private static final String SAVE_RECORDED_AUDIO_KEY = "save_recorded_audio"; 136 private static final String TIME_TO_START_READ_KEY = "time_to_start_read"; 137 private static final String TIME_TO_VALID_AUDIO_KEY = "time_to_valid_audio"; 138 private static final String EMPTY_AUDIO_DURATION_KEY = "empty_audio_duration"; 139 private static final String RECORDED_AUDIO_SOURCE_KEY = "record_audio_source"; 140 private static final String FORCE_MSAA_KEY = "force_msaa"; 141 private static final String TRACK_FRAME_TIME_KEY = "track_frame_time"; 142 private static final String SHOW_NON_RECTANGULAR_CLIP_KEY = "show_non_rect_clip"; 143 private static final String SHOW_HW_SCREEN_UPDATES_KEY = "show_hw_screen_udpates"; 144 private static final String SHOW_HW_LAYERS_UPDATES_KEY = "show_hw_layers_udpates"; 145 private static final String DEBUG_HW_OVERDRAW_KEY = "debug_hw_overdraw"; 146 private static final String DEBUG_LAYOUT_KEY = "debug_layout"; 147 private static final String FORCE_RTL_LAYOUT_KEY = "force_rtl_layout_all_locales"; 148 private static final String WINDOW_BLURS_KEY = "window_blurs"; 149 private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale"; 150 private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale"; 151 private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale"; 152 private static final String OVERLAY_DISPLAY_DEVICES_KEY = "overlay_display_devices"; 153 private static final String DEBUG_DEBUGGING_CATEGORY_KEY = "debug_debugging_category"; 154 155 private static final String WIFI_DISPLAY_CERTIFICATION_KEY = "wifi_display_certification"; 156 private static final String WIFI_VERBOSE_LOGGING_KEY = "wifi_verbose_logging"; 157 private static final String USB_CONFIGURATION_KEY = "select_usb_configuration"; 158 private static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on"; 159 private static final String KEY_COLOR_MODE = "color_mode"; 160 private static final String FORCE_RESIZABLE_KEY = "force_resizable_activities"; 161 162 private static final String INACTIVE_APPS_KEY = "inactive_apps"; 163 164 private static final String OPENGL_TRACES_KEY = "enable_opengl_traces"; 165 166 private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY 167 = "immediately_destroy_activities"; 168 private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit"; 169 170 private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs"; 171 172 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 173 174 private static final String TERMINAL_APP_PACKAGE = "com.android.terminal"; 175 176 private static final int RESULT_DEBUG_APP = 1000; 177 private static final int RESULT_MOCK_LOCATION_APP = 1001; 178 179 private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst"; 180 181 private static final String DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES = "262144"; // 256K 182 183 private static final int[] MOCK_LOCATION_APP_OPS = new int[]{AppOpsManager.OP_MOCK_LOCATION}; 184 185 private static final String STATE_SHOWING_DIALOG_KEY = "showing_dialog_key"; 186 187 private static final String TOGGLE_ADB_WIRELESS_KEY = "toggle_adb_wireless"; 188 189 private String mPendingDialogKey; 190 191 private IWindowManager mWindowManager; 192 private IBackupManager mBackupManager; 193 private DevicePolicyManager mDpm; 194 private UserManager mUm; 195 private WifiManager mWifiManager; 196 private ContentResolver mContentResolver; 197 198 private boolean mLastEnabledState; 199 private boolean mHaveDebugSettings; 200 201 private TwoStatePreference mEnableDeveloper; 202 private TwoStatePreference mEnableAdb; 203 private Preference mClearAdbKeys; 204 private TwoStatePreference mEnableTerminal; 205 private Preference mBugreport; 206 private TwoStatePreference mKeepScreenOn; 207 private ListPreference mBtHciSnoopLog; 208 private OemUnlockPreferenceController mEnableOemUnlock; 209 private TwoStatePreference mDebugViewAttributes; 210 private TwoStatePreference mForceAllowOnExternal; 211 212 private PreferenceScreen mPassword; 213 private String mDebugApp; 214 private Preference mDebugAppPref; 215 216 private String mMockLocationApp; 217 private Preference mMockLocationAppPref; 218 219 private TwoStatePreference mWaitForDebugger; 220 private TwoStatePreference mVerifyAppsOverUsb; 221 private TwoStatePreference mWifiDisplayCertification; 222 private TwoStatePreference mWifiVerboseLogging; 223 private TwoStatePreference mMobileDataAlwaysOn; 224 225 private TwoStatePreference mStrictMode; 226 private TwoStatePreference mPointerLocation; 227 private TwoStatePreference mShowTouches; 228 private TwoStatePreference mShowScreenUpdates; 229 private TwoStatePreference mDisableOverlays; 230 private TwoStatePreference mForceMsaa; 231 private TwoStatePreference mShowHwScreenUpdates; 232 private TwoStatePreference mShowHwLayersUpdates; 233 private TwoStatePreference mDebugLayout; 234 private TwoStatePreference mForceRtlLayout; 235 private TwoStatePreference mWindowBlurs; 236 private ListPreference mDebugHwOverdraw; 237 private LogdSizePreferenceController mLogdSizeController; 238 private LogpersistPreferenceController mLogpersistController; 239 private RestrictedPreferenceAdapter<ListPreference> mUsbConfiguration; 240 private ListPreference mTrackFrameTime; 241 private ListPreference mShowNonRectClip; 242 private ListPreference mWindowAnimationScale; 243 private ListPreference mTransitionAnimationScale; 244 private ListPreference mAnimatorDurationScale; 245 private ListPreference mOverlayDisplayDevices; 246 private ListPreference mOpenGLTraces; 247 248 private ListPreference mSimulateColorSpace; 249 250 private TwoStatePreference mUSBAudio; 251 252 private TwoStatePreference mRecordAudio; 253 private Preference mPlayRecordedAudio; 254 private Preference mSaveAudio; 255 private Preference mTimeToStartRead; 256 private Preference mTimeToValidAudio; 257 private Preference mEmptyAudioDuration; 258 private ListPreference mRecordAudioSource; 259 260 private TwoStatePreference mImmediatelyDestroyActivities; 261 262 private ListPreference mAppProcessLimit; 263 264 private TwoStatePreference mShowAllANRs; 265 266 private ColorModePreference mColorModePreference; 267 268 private TwoStatePreference mForceResizable; 269 270 private Preference mWirelessDebugging; 271 272 private final ArrayList<Preference> mAllPrefs = new ArrayList<>(); 273 274 private final ArrayList<TwoStatePreference> mResetSwitchPrefs = new ArrayList<>(); 275 276 private final HashSet<Preference> mDisabledPrefs = new HashSet<>(); 277 278 private boolean mUnavailable; 279 280 private AudioDebug mAudioDebug; 281 282 private ConnectivityManager mConnectivityManager; 283 newInstance()284 public static DevelopmentFragment newInstance() { 285 return new DevelopmentFragment(); 286 } 287 288 private final Handler mHandler = new Handler(Looper.getMainLooper()); 289 private final NetworkCallback mNetworkCallback = new NetworkCallback(); 290 private ContentObserver mToggleContentObserver; 291 292 @Override onCreate(Bundle icicle)293 public void onCreate(Bundle icicle) { 294 295 if (icicle != null) { 296 // Don't show this in onCreate since we might be on the back stack 297 mPendingDialogKey = icicle.getString(STATE_SHOWING_DIALOG_KEY); 298 } 299 300 mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 301 mBackupManager = IBackupManager.Stub.asInterface( 302 ServiceManager.getService(Context.BACKUP_SERVICE)); 303 mDpm = (DevicePolicyManager) getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE); 304 mUm = (UserManager) getActivity().getSystemService(Context.USER_SERVICE); 305 306 mWifiManager = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE); 307 308 mContentResolver = getActivity().getContentResolver(); 309 310 mAudioDebug = new AudioDebug(getActivity(), 311 (boolean successful) -> onAudioRecorded(successful), 312 (AudioMetrics.Data data) -> updateAudioRecordingMetrics(data)); 313 314 mConnectivityManager = getContext().getSystemService(ConnectivityManager.class); 315 316 mToggleContentObserver = new ContentObserver(new Handler(Looper.myLooper())) { 317 @Override 318 public void onChange(boolean selfChange, Uri uri) { 319 updateWirelessDebuggingPreference(); 320 } 321 }; 322 mContentResolver.registerContentObserver( 323 Settings.Global.getUriFor(Settings.Global.ADB_WIFI_ENABLED), 324 false, 325 mToggleContentObserver); 326 327 super.onCreate(icicle); 328 } 329 330 @Override onCreatePreferences(Bundle savedInstanceState, String rootKey)331 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 332 mLogdSizeController = new LogdSizePreferenceController(getActivity()); 333 mLogpersistController = new LogpersistPreferenceController(getActivity(), 334 getSettingsLifecycle()); 335 336 if (!mUm.isAdminUser() 337 || mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES) 338 || Settings.Global.getInt(mContentResolver, 339 Settings.Global.DEVICE_PROVISIONED, 0) == 0) { 340 // Block access to developer options if the user is not the owner, if user policy 341 // restricts it, or if the device has not been provisioned 342 mUnavailable = true; 343 addPreferencesFromResource(R.xml.development_prefs_not_available); 344 return; 345 } 346 347 addPreferencesFromResource(R.xml.development_prefs); 348 final PreferenceScreen preferenceScreen = getPreferenceScreen(); 349 350 // Don't add to prefs lists or it'll disable itself when switched off 351 mEnableDeveloper = findPreference(ENABLE_DEVELOPER); 352 353 final PreferenceGroup debugDebuggingCategory = (PreferenceGroup) 354 findPreference(DEBUG_DEBUGGING_CATEGORY_KEY); 355 mEnableAdb = findAndInitSwitchPref(ENABLE_ADB); 356 mClearAdbKeys = findPreference(CLEAR_ADB_KEYS); 357 if (!AdbProperties.secure().orElse(false)) { 358 if (debugDebuggingCategory != null) { 359 debugDebuggingCategory.removePreference(mClearAdbKeys); 360 } 361 } 362 mAllPrefs.add(mClearAdbKeys); 363 mEnableTerminal = findAndInitSwitchPref(ENABLE_TERMINAL); 364 if (!isPackageInstalled(getActivity(), TERMINAL_APP_PACKAGE)) { 365 if (debugDebuggingCategory != null) { 366 debugDebuggingCategory.removePreference(mEnableTerminal); 367 } 368 mEnableTerminal = null; 369 } 370 371 mBugreport = findPreference(BUGREPORT); 372 if (!showBugReportPreference()) { 373 removePreference(mBugreport); 374 } 375 376 mLogdSizeController.displayPreference(preferenceScreen); 377 mLogpersistController.displayPreference(preferenceScreen); 378 379 mKeepScreenOn = findAndInitSwitchPref(KEEP_SCREEN_ON); 380 mBtHciSnoopLog = addListPreference(BT_HCI_SNOOP_LOG); 381 mEnableOemUnlock = new OemUnlockPreferenceController( 382 getActivity(), findAndInitSwitchPref(ENABLE_OEM_UNLOCK)); 383 384 // TODO: implement UI for TV 385 removePreference(RUNNING_APPS); 386 387 mDebugViewAttributes = findAndInitSwitchPref(DEBUG_VIEW_ATTRIBUTES); 388 mForceAllowOnExternal = findAndInitSwitchPref(FORCE_ALLOW_ON_EXTERNAL_KEY); 389 mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD); 390 // We don't have a backup password activity on TV 391 mPassword.setVisible(false); 392 mAllPrefs.add(mPassword); 393 394 if (!mUm.isAdminUser()) { 395 disableForUser(mEnableAdb); 396 disableForUser(mClearAdbKeys); 397 disableForUser(mEnableTerminal); 398 disableForUser(mPassword); 399 } 400 401 mDebugAppPref = findPreference(DEBUG_APP_KEY); 402 mAllPrefs.add(mDebugAppPref); 403 mWaitForDebugger = findAndInitSwitchPref(WAIT_FOR_DEBUGGER_KEY); 404 405 mMockLocationAppPref = findPreference(MOCK_LOCATION_APP_KEY); 406 mAllPrefs.add(mMockLocationAppPref); 407 408 mVerifyAppsOverUsb = findAndInitSwitchPref(VERIFY_APPS_OVER_USB_KEY); 409 if (!showVerifierSetting()) { 410 if (debugDebuggingCategory != null) { 411 debugDebuggingCategory.removePreference(mVerifyAppsOverUsb); 412 } else { 413 mVerifyAppsOverUsb.setEnabled(false); 414 } 415 } 416 mStrictMode = findAndInitSwitchPref(STRICT_MODE_KEY); 417 mPointerLocation = findAndInitSwitchPref(POINTER_LOCATION_KEY); 418 mShowTouches = findAndInitSwitchPref(SHOW_TOUCHES_KEY); 419 mShowScreenUpdates = findAndInitSwitchPref(SHOW_SCREEN_UPDATES_KEY); 420 mDisableOverlays = findAndInitSwitchPref(DISABLE_OVERLAYS_KEY); 421 mForceMsaa = findAndInitSwitchPref(FORCE_MSAA_KEY); 422 mTrackFrameTime = addListPreference(TRACK_FRAME_TIME_KEY); 423 mShowNonRectClip = addListPreference(SHOW_NON_RECTANGULAR_CLIP_KEY); 424 mShowHwScreenUpdates = findAndInitSwitchPref(SHOW_HW_SCREEN_UPDATES_KEY); 425 mShowHwLayersUpdates = findAndInitSwitchPref(SHOW_HW_LAYERS_UPDATES_KEY); 426 mDebugLayout = findAndInitSwitchPref(DEBUG_LAYOUT_KEY); 427 mForceRtlLayout = findAndInitSwitchPref(FORCE_RTL_LAYOUT_KEY); 428 mWindowBlurs = findAndInitSwitchPref(WINDOW_BLURS_KEY); 429 mDebugHwOverdraw = addListPreference(DEBUG_HW_OVERDRAW_KEY); 430 mWifiDisplayCertification = findAndInitSwitchPref(WIFI_DISPLAY_CERTIFICATION_KEY); 431 mWifiVerboseLogging = findAndInitSwitchPref(WIFI_VERBOSE_LOGGING_KEY); 432 mMobileDataAlwaysOn = findAndInitSwitchPref(MOBILE_DATA_ALWAYS_ON); 433 mUsbConfiguration = addListRestrictedPreference(USB_CONFIGURATION_KEY, 434 UserManager.DISALLOW_USB_FILE_TRANSFER); 435 // Only show those functions that are available 436 listOnlySettableUsbConfigurationValues(); 437 438 mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY); 439 mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY); 440 mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY); 441 mOverlayDisplayDevices = addListPreference(OVERLAY_DISPLAY_DEVICES_KEY); 442 mOpenGLTraces = addListPreference(OPENGL_TRACES_KEY); 443 mSimulateColorSpace = addListPreference(SIMULATE_COLOR_SPACE); 444 mUSBAudio = findAndInitSwitchPref(USB_AUDIO_KEY); 445 mRecordAudio = findAndInitSwitchPref(RECORD_AUDIO_KEY); 446 mPlayRecordedAudio = findPreference(PLAY_RECORDED_AUDIO_KEY); 447 mPlayRecordedAudio.setVisible(false); 448 mSaveAudio = findPreference(SAVE_RECORDED_AUDIO_KEY); 449 mSaveAudio.setVisible(false); 450 mTimeToStartRead = findPreference(TIME_TO_START_READ_KEY); 451 mTimeToStartRead.setVisible(false); 452 mTimeToValidAudio = findPreference(TIME_TO_VALID_AUDIO_KEY); 453 mTimeToValidAudio.setVisible(false); 454 mEmptyAudioDuration = findPreference(EMPTY_AUDIO_DURATION_KEY); 455 mEmptyAudioDuration.setVisible(false); 456 mRecordAudioSource = addListPreference(RECORDED_AUDIO_SOURCE_KEY); 457 mRecordAudioSource.setVisible(false); 458 mForceResizable = findAndInitSwitchPref(FORCE_RESIZABLE_KEY); 459 460 mImmediatelyDestroyActivities = findPreference(IMMEDIATELY_DESTROY_ACTIVITIES_KEY); 461 mAllPrefs.add(mImmediatelyDestroyActivities); 462 mResetSwitchPrefs.add(mImmediatelyDestroyActivities); 463 464 mAppProcessLimit = addListPreference(APP_PROCESS_LIMIT_KEY); 465 466 mShowAllANRs = findPreference(SHOW_ALL_ANRS_KEY); 467 mAllPrefs.add(mShowAllANRs); 468 mResetSwitchPrefs.add(mShowAllANRs); 469 470 Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY); 471 if (hdcpChecking != null) { 472 mAllPrefs.add(hdcpChecking); 473 removePreferenceForProduction(hdcpChecking); 474 } 475 476 mColorModePreference = (ColorModePreference) findPreference(KEY_COLOR_MODE); 477 mColorModePreference.updateCurrentAndSupported(); 478 if (mColorModePreference.getColorModeCount() < 2) { 479 removePreference(KEY_COLOR_MODE); 480 mColorModePreference = null; 481 } 482 483 mWirelessDebugging = findPreference(TOGGLE_ADB_WIRELESS_KEY); 484 if (FlavorUtils.isTwoPanel(getContext())) { 485 mWirelessDebugging.setFragment(WirelessDebuggingInfoFragment.class.getName()); 486 } else { 487 mWirelessDebugging.setFragment(WirelessDebuggingFragment.class.getName()); 488 } 489 } 490 removePreference(String key)491 private void removePreference(String key) { 492 final Preference preference = findPreference(key); 493 if (preference != null) { 494 getPreferenceScreen().removePreference(preference); 495 } 496 } 497 addListPreference(String prefKey)498 private ListPreference addListPreference(String prefKey) { 499 ListPreference pref = (ListPreference) findPreference(prefKey); 500 mAllPrefs.add(pref); 501 pref.setOnPreferenceChangeListener(this); 502 return pref; 503 } 504 addListRestrictedPreference(String prefKey, String userRestriction)505 private RestrictedPreferenceAdapter<ListPreference> addListRestrictedPreference(String prefKey, 506 String userRestriction) { 507 final ListPreference pref = (ListPreference) findPreference(prefKey); 508 pref.setOnPreferenceChangeListener(this); 509 final RestrictedPreferenceAdapter<ListPreference> restrictedListPref = 510 RestrictedPreferenceAdapter.adapt(pref, userRestriction); 511 mAllPrefs.add(restrictedListPref.getOriginalPreference()); 512 return restrictedListPref; 513 } 514 disableForUser(Preference pref)515 private void disableForUser(Preference pref) { 516 if (pref != null) { 517 pref.setEnabled(false); 518 mDisabledPrefs.add(pref); 519 } 520 } 521 findAndInitSwitchPref(String key)522 private TwoStatePreference findAndInitSwitchPref(String key) { 523 TwoStatePreference pref = findPreference(key); 524 if (pref == null) { 525 throw new IllegalArgumentException("Cannot find preference with key = " + key); 526 } 527 mAllPrefs.add(pref); 528 mResetSwitchPrefs.add(pref); 529 return pref; 530 } 531 532 @Override onActivityCreated(Bundle savedInstanceState)533 public void onActivityCreated(Bundle savedInstanceState) { 534 super.onActivityCreated(savedInstanceState); 535 536 if (mUnavailable) { 537 if (mEnableDeveloper != null) { 538 mEnableDeveloper.setEnabled(false); 539 } 540 } 541 } 542 removePreferenceForProduction(Preference preference)543 private boolean removePreferenceForProduction(Preference preference) { 544 if ("user".equals(Build.TYPE)) { 545 removePreference(preference); 546 return true; 547 } 548 return false; 549 } 550 removePreference(Preference preference)551 private void removePreference(Preference preference) { 552 getPreferenceScreen().removePreference(preference); 553 mAllPrefs.remove(preference); 554 mResetSwitchPrefs.remove(preference); 555 } 556 setPrefsEnabledState(boolean enabled)557 private void setPrefsEnabledState(boolean enabled) { 558 for (final Preference pref : mAllPrefs) { 559 pref.setEnabled(enabled && !mDisabledPrefs.contains(pref)); 560 } 561 mLogdSizeController.enablePreference(enabled); 562 mLogpersistController.enablePreference(enabled); 563 updateAllOptions(); 564 } 565 566 @Override onResume()567 public void onResume() { 568 super.onResume(); 569 570 if (mUnavailable) { 571 return; 572 } 573 574 if (mDpm.getMaximumTimeToLock(null) > 0) { 575 // A DeviceAdmin has specified a maximum time until the device 576 // will lock... in this case we can't allow the user to turn 577 // on "stay awake when plugged in" because that would defeat the 578 // restriction. 579 mDisabledPrefs.add(mKeepScreenOn); 580 } else { 581 mDisabledPrefs.remove(mKeepScreenOn); 582 } 583 584 mLastEnabledState = DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext()); 585 mEnableDeveloper.setChecked(mLastEnabledState); 586 setPrefsEnabledState(mLastEnabledState); 587 588 if (mHaveDebugSettings && !mLastEnabledState) { 589 // Overall debugging is disabled, but there are some debug 590 // settings that are enabled. This is an invalid state. Switch 591 // to debug settings being enabled, so the user knows there is 592 // stuff enabled and can turn it all off if they want. 593 DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), true); 594 mLastEnabledState = true; 595 mEnableDeveloper.setChecked(mLastEnabledState); 596 setPrefsEnabledState(mLastEnabledState); 597 } 598 599 if (mColorModePreference != null) { 600 mColorModePreference.startListening(); 601 mColorModePreference.updateCurrentAndSupported(); 602 } 603 604 if (mPendingDialogKey != null) { 605 recreateDialogForKey(mPendingDialogKey); 606 mPendingDialogKey = null; 607 } 608 609 mConnectivityManager.registerNetworkCallback( 610 new NetworkRequest.Builder() 611 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) 612 .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) 613 .build(), 614 mNetworkCallback); 615 } 616 617 @Override onPause()618 public void onPause() { 619 super.onPause(); 620 if (mColorModePreference != null) { 621 mColorModePreference.stopListening(); 622 } 623 624 mAudioDebug.cancelRecording(); 625 mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); 626 } 627 628 @Override onSaveInstanceState(Bundle outState)629 public void onSaveInstanceState(Bundle outState) { 630 super.onSaveInstanceState(outState); 631 outState.putString(STATE_SHOWING_DIALOG_KEY, getKeyForShowingDialog()); 632 } 633 634 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)635 public View onCreateView(LayoutInflater inflater, ViewGroup container, 636 Bundle savedInstanceState) { 637 IntentFilter filter = new IntentFilter(); 638 filter.addAction(UsbManager.ACTION_USB_STATE); 639 if (getActivity().registerReceiver(mUsbReceiver, filter) == null) { 640 updateUsbConfigurationValues(); 641 } 642 return super.onCreateView(inflater, container, savedInstanceState); 643 } 644 645 @Override onDestroyView()646 public void onDestroyView() { 647 super.onDestroyView(); 648 649 getActivity().unregisterReceiver(mUsbReceiver); 650 } 651 652 @Override onDestroy()653 public void onDestroy() { 654 super.onDestroy(); 655 dismissDialogs(); 656 mContentResolver.unregisterContentObserver(mToggleContentObserver); 657 } 658 updateSwitchPreference(TwoStatePreference switchPreference, boolean value)659 void updateSwitchPreference(TwoStatePreference switchPreference, boolean value) { 660 switchPreference.setChecked(value); 661 mHaveDebugSettings |= value; 662 } 663 updateAllOptions()664 private void updateAllOptions() { 665 final Context context = getActivity(); 666 final ContentResolver cr = context.getContentResolver(); 667 mHaveDebugSettings = false; 668 updateSwitchPreference(mEnableAdb, Settings.Global.getInt(cr, 669 Settings.Global.ADB_ENABLED, 0) != 0); 670 if (mEnableTerminal != null) { 671 updateSwitchPreference(mEnableTerminal, 672 context.getPackageManager().getApplicationEnabledSetting(TERMINAL_APP_PACKAGE) 673 == PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 674 } 675 updateSwitchPreference(mKeepScreenOn, Settings.Global.getInt(cr, 676 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0); 677 mEnableOemUnlock.updateState(); 678 updateSwitchPreference(mDebugViewAttributes, Settings.Global.getInt(cr, 679 Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0); 680 updateSwitchPreference(mForceAllowOnExternal, Settings.Global.getInt(cr, 681 Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0); 682 updateBluetoothHciSnoopLogValues(); 683 updateHdcpValues(); 684 updatePasswordSummary(); 685 updateDebuggerOptions(); 686 updateMockLocation(); 687 updateStrictModeVisualOptions(); 688 updatePointerLocationOptions(); 689 updateShowTouchesOptions(); 690 updateFlingerOptions(); 691 updateMsaaOptions(); 692 updateTrackFrameTimeOptions(); 693 updateShowNonRectClipOptions(); 694 updateShowHwScreenUpdatesOptions(); 695 updateShowHwLayersUpdatesOptions(); 696 updateDebugHwOverdrawOptions(); 697 updateDebugLayoutOptions(); 698 updateAnimationScaleOptions(); 699 updateOverlayDisplayDevicesOptions(); 700 updateOpenGLTracesOptions(); 701 updateImmediatelyDestroyActivitiesOptions(); 702 updateAppProcessLimitOptions(); 703 updateShowAllANRsOptions(); 704 updateVerifyAppsOverUsbOptions(); 705 updateBugreportOptions(); 706 updateForceRtlOptions(); 707 updateWindowBlursOptions(); 708 mLogdSizeController.updateLogdSizeValues(); 709 mLogpersistController.updateLogpersistValues(); 710 updateWifiDisplayCertificationOptions(); 711 updateWifiVerboseLoggingOptions(); 712 updateMobileDataAlwaysOnOptions(); 713 updateSimulateColorSpace(); 714 updateUSBAudioOptions(); 715 updateForceResizableOptions(); 716 updateAudioRecordingOptions(); 717 } 718 resetDangerousOptions()719 private void resetDangerousOptions() { 720 SystemPropPoker.getInstance().blockPokes(); 721 for (final TwoStatePreference cb : mResetSwitchPrefs) { 722 if (cb.isChecked()) { 723 cb.setChecked(false); 724 onPreferenceTreeClick(cb); 725 } 726 } 727 resetDebuggerOptions(); 728 mLogpersistController.writeLogpersistOption(null, true); 729 mLogdSizeController.writeLogdSizeOption(null); 730 writeAnimationScaleOption(0, mWindowAnimationScale, null); 731 writeAnimationScaleOption(1, mTransitionAnimationScale, null); 732 writeAnimationScaleOption(2, mAnimatorDurationScale, null); 733 // Only poke the color space setting if we control it. 734 if (usingDevelopmentColorSpace()) { 735 writeSimulateColorSpace(-1); 736 } 737 writeOverlayDisplayDevicesOptions(null); 738 writeAppProcessLimitOptions(null); 739 mHaveDebugSettings = false; 740 updateAllOptions(); 741 SystemPropPoker.getInstance().unblockPokes(); 742 SystemPropPoker.getInstance().poke(); 743 } 744 updateBluetoothHciSnoopLogValues()745 private void updateBluetoothHciSnoopLogValues() { 746 ListPreference bluetoothSnoopLog = (ListPreference) findPreference(BT_HCI_SNOOP_LOG); 747 if (bluetoothSnoopLog != null) { 748 String currentValue = SystemProperties.get(BTSNOOP_LOG_MODE_PROPERTY); 749 String[] values = getResources().getStringArray(R.array.bt_hci_snoop_log_values); 750 String[] summaries = getResources().getStringArray(R.array.bt_hci_snoop_log_entries); 751 int disabledIndex = 0; // defaults to DISABLED 752 updateListPreference(bluetoothSnoopLog, currentValue, values, summaries, disabledIndex); 753 } 754 } 755 updateListPreference(ListPreference preference, String currentValue, String[] values, String[] summaries, int index)756 private void updateListPreference(ListPreference preference, String currentValue, 757 String[] values, String[] summaries, int index) { 758 for (int i = 0; i < values.length; i++) { 759 if (currentValue.equals(values[i])) { 760 index = i; 761 break; 762 } 763 } 764 preference.setValue(values[index]); 765 preference.setSummary(summaries[index]); 766 preference.setOnPreferenceChangeListener(this); 767 } 768 updateHdcpValues()769 private void updateHdcpValues() { 770 ListPreference hdcpChecking = (ListPreference) findPreference(HDCP_CHECKING_KEY); 771 if (hdcpChecking != null) { 772 String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY); 773 String[] values = getResources().getStringArray(R.array.hdcp_checking_values); 774 String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries); 775 int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values 776 updateListPreference(hdcpChecking, currentValue, values, summaries, index); 777 } 778 } 779 updatePasswordSummary()780 private void updatePasswordSummary() { 781 try { 782 if (mBackupManager.hasBackupPassword()) { 783 mPassword.setSummary(R.string.local_backup_password_summary_change); 784 } else { 785 mPassword.setSummary(R.string.local_backup_password_summary_none); 786 } 787 } catch (RemoteException e) { 788 // ignore 789 } 790 } 791 writeBtHciSnoopLogOptions(Object newValue)792 private void writeBtHciSnoopLogOptions(Object newValue) { 793 SystemProperties.set(BTSNOOP_LOG_MODE_PROPERTY, 794 newValue == null ? "" : newValue.toString()); 795 updateBluetoothHciSnoopLogValues(); 796 SystemPropPoker.getInstance().poke(); 797 } 798 writeDebuggerOptions()799 private void writeDebuggerOptions() { 800 try { 801 ActivityManager.getService().setDebugApp( 802 mDebugApp, mWaitForDebugger.isChecked(), true); 803 } catch (RemoteException ex) { 804 // ignore 805 } 806 } 807 writeMockLocation()808 private void writeMockLocation() { 809 AppOpsManager appOpsManager = 810 (AppOpsManager) getActivity().getSystemService(Context.APP_OPS_SERVICE); 811 812 // Disable the app op of the previous mock location app if such. 813 List<AppOpsManager.PackageOps> packageOps = 814 appOpsManager.getPackagesForOps(MOCK_LOCATION_APP_OPS); 815 if (packageOps != null) { 816 // Should be one but in case we are in a bad state due to use of command line tools. 817 for (AppOpsManager.PackageOps packageOp : packageOps) { 818 if (packageOp.getOps().get(0).getMode() != AppOpsManager.MODE_ERRORED) { 819 String oldMockLocationApp = packageOp.getPackageName(); 820 try { 821 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo( 822 oldMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS); 823 appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid, 824 oldMockLocationApp, AppOpsManager.MODE_ERRORED); 825 } catch (PackageManager.NameNotFoundException e) { 826 /* ignore */ 827 } 828 } 829 } 830 } 831 832 // Enable the app op of the new mock location app if such. 833 if (!TextUtils.isEmpty(mMockLocationApp)) { 834 try { 835 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo( 836 mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS); 837 appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid, 838 mMockLocationApp, AppOpsManager.MODE_ALLOWED); 839 } catch (PackageManager.NameNotFoundException e) { 840 /* ignore */ 841 } 842 } 843 } 844 resetDebuggerOptions()845 private static void resetDebuggerOptions() { 846 try { 847 ActivityManager.getService().setDebugApp( 848 null, false, true); 849 } catch (RemoteException ex) { 850 // ignore 851 } 852 } 853 updateDebuggerOptions()854 private void updateDebuggerOptions() { 855 mDebugApp = Settings.Global.getString(mContentResolver, Settings.Global.DEBUG_APP); 856 updateSwitchPreference(mWaitForDebugger, Settings.Global.getInt(mContentResolver, 857 Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0); 858 if (mDebugApp != null && mDebugApp.length() > 0) { 859 String label; 860 try { 861 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(mDebugApp, 862 PackageManager.GET_DISABLED_COMPONENTS); 863 CharSequence lab = getActivity().getPackageManager().getApplicationLabel(ai); 864 label = lab != null ? lab.toString() : mDebugApp; 865 } catch (PackageManager.NameNotFoundException e) { 866 label = mDebugApp; 867 } 868 mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_set, label)); 869 mWaitForDebugger.setEnabled(true); 870 mHaveDebugSettings = true; 871 } else { 872 mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_not_set)); 873 mWaitForDebugger.setEnabled(false); 874 } 875 } 876 updateMockLocation()877 private void updateMockLocation() { 878 AppOpsManager appOpsManager = 879 (AppOpsManager) getActivity().getSystemService(Context.APP_OPS_SERVICE); 880 881 List<AppOpsManager.PackageOps> packageOps = 882 appOpsManager.getPackagesForOps(MOCK_LOCATION_APP_OPS); 883 if (packageOps != null) { 884 for (AppOpsManager.PackageOps packageOp : packageOps) { 885 if (packageOp.getOps().get(0).getMode() == AppOpsManager.MODE_ALLOWED) { 886 mMockLocationApp = packageOps.get(0).getPackageName(); 887 break; 888 } 889 } 890 } 891 892 if (!TextUtils.isEmpty(mMockLocationApp)) { 893 String label = mMockLocationApp; 894 try { 895 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo( 896 mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS); 897 CharSequence appLabel = getActivity().getPackageManager().getApplicationLabel(ai); 898 if (appLabel != null) { 899 label = appLabel.toString(); 900 } 901 } catch (PackageManager.NameNotFoundException e) { 902 /* ignore */ 903 } 904 905 mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_set, label)); 906 mHaveDebugSettings = true; 907 } else { 908 mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_not_set)); 909 } 910 } 911 updateVerifyAppsOverUsbOptions()912 private void updateVerifyAppsOverUsbOptions() { 913 updateSwitchPreference(mVerifyAppsOverUsb, 914 Settings.Global.getInt(mContentResolver, 915 Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0); 916 mVerifyAppsOverUsb.setEnabled(enableVerifierSetting()); 917 } 918 writeVerifyAppsOverUsbOptions()919 private void writeVerifyAppsOverUsbOptions() { 920 Settings.Global.putInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 921 mVerifyAppsOverUsb.isChecked() ? 1 : 0); 922 } 923 enableVerifierSetting()924 private boolean enableVerifierSetting() { 925 if (Settings.Global.getInt(mContentResolver, Settings.Global.ADB_ENABLED, 0) == 0) { 926 return false; 927 } 928 final PackageManager pm = getActivity().getPackageManager(); 929 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 930 verification.setType(PACKAGE_MIME_TYPE); 931 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 932 final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(verification, 0); 933 return !receivers.isEmpty(); 934 } 935 showVerifierSetting()936 private boolean showVerifierSetting() { 937 return Settings.Global.getInt(mContentResolver, 938 Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0; 939 } 940 showEnableOemUnlockPreference()941 private static boolean showEnableOemUnlockPreference() { 942 return !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals(""); 943 } 944 showBugReportPreference()945 private boolean showBugReportPreference() { 946 return (FlavorUtils.getFlavor(getContext()) & X_EXPERIENCE_FLAVORS_MASK) == 0; 947 } 948 updateBugreportOptions()949 private void updateBugreportOptions() { 950 boolean enabled = "1".equals(SystemProperties.get("ro.debuggable")) 951 || mEnableDeveloper.isChecked(); 952 mBugreport.setEnabled(enabled); 953 final ComponentName componentName = new ComponentName("com.android.shell", 954 "com.android.shell.BugreportStorageProvider"); 955 getActivity().getPackageManager().setComponentEnabledSetting(componentName, 956 enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 957 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 958 0); 959 } 960 961 /** 962 * Take bug report and show notification. 963 * @param activity 964 */ captureBugReport(Activity activity)965 public static void captureBugReport(Activity activity) { 966 Toast.makeText(activity, R.string.capturing_bugreport, Toast.LENGTH_SHORT).show(); 967 try { 968 ActivityManager.getService().requestInteractiveBugReport(); 969 } catch (RemoteException e) { 970 Log.e(TAG, "Error taking bugreport", e); 971 } 972 } 973 974 // Returns the current state of the system property that controls 975 // strictmode flashes. One of: 976 // 0: not explicitly set one way or another 977 // 1: on 978 // 2: off currentStrictModeActiveIndex()979 private static int currentStrictModeActiveIndex() { 980 if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) { 981 return 0; 982 } 983 boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false); 984 return enabled ? 1 : 2; 985 } 986 writeStrictModeVisualOptions()987 private void writeStrictModeVisualOptions() { 988 try { 989 mWindowManager.setStrictModeVisualIndicatorPreference(mStrictMode.isChecked() 990 ? "1" : ""); 991 } catch (RemoteException e) { 992 // ignore 993 } 994 } 995 updateStrictModeVisualOptions()996 private void updateStrictModeVisualOptions() { 997 updateSwitchPreference(mStrictMode, currentStrictModeActiveIndex() == 1); 998 } 999 writePointerLocationOptions()1000 private void writePointerLocationOptions() { 1001 Settings.System.putInt(mContentResolver, 1002 Settings.System.POINTER_LOCATION, mPointerLocation.isChecked() ? 1 : 0); 1003 } 1004 updatePointerLocationOptions()1005 private void updatePointerLocationOptions() { 1006 updateSwitchPreference(mPointerLocation, 1007 Settings.System.getInt(mContentResolver, Settings.System.POINTER_LOCATION, 0) != 0); 1008 } 1009 writeShowTouchesOptions()1010 private void writeShowTouchesOptions() { 1011 Settings.System.putInt(mContentResolver, 1012 Settings.System.SHOW_TOUCHES, mShowTouches.isChecked() ? 1 : 0); 1013 } 1014 updateShowTouchesOptions()1015 private void updateShowTouchesOptions() { 1016 updateSwitchPreference(mShowTouches, 1017 Settings.System.getInt(mContentResolver, Settings.System.SHOW_TOUCHES, 0) != 0); 1018 } 1019 updateFlingerOptions()1020 private void updateFlingerOptions() { 1021 // magic communication with surface flinger. 1022 try { 1023 IBinder flinger = ServiceManager.getService("SurfaceFlinger"); 1024 if (flinger != null) { 1025 Parcel data = Parcel.obtain(); 1026 Parcel reply = Parcel.obtain(); 1027 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 1028 flinger.transact(1010, data, reply, 0); 1029 @SuppressWarnings("unused") 1030 int showCpu = reply.readInt(); 1031 @SuppressWarnings("unused") 1032 int enableGL = reply.readInt(); 1033 int showUpdates = reply.readInt(); 1034 updateSwitchPreference(mShowScreenUpdates, showUpdates != 0); 1035 @SuppressWarnings("unused") 1036 int showBackground = reply.readInt(); 1037 int disableOverlays = reply.readInt(); 1038 updateSwitchPreference(mDisableOverlays, disableOverlays != 0); 1039 reply.recycle(); 1040 data.recycle(); 1041 } 1042 } catch (RemoteException ex) { 1043 // ignore 1044 } 1045 } 1046 writeShowUpdatesOption()1047 private void writeShowUpdatesOption() { 1048 try { 1049 IBinder flinger = ServiceManager.getService("SurfaceFlinger"); 1050 if (flinger != null) { 1051 Parcel data = Parcel.obtain(); 1052 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 1053 final int showUpdates = mShowScreenUpdates.isChecked() ? 1 : 0; 1054 data.writeInt(showUpdates); 1055 flinger.transact(1002, data, null, 0); 1056 data.recycle(); 1057 1058 updateFlingerOptions(); 1059 } 1060 } catch (RemoteException ex) { 1061 // ignore 1062 } 1063 } 1064 writeDisableOverlaysOption()1065 private void writeDisableOverlaysOption() { 1066 try { 1067 IBinder flinger = ServiceManager.getService("SurfaceFlinger"); 1068 if (flinger != null) { 1069 Parcel data = Parcel.obtain(); 1070 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 1071 final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0; 1072 data.writeInt(disableOverlays); 1073 flinger.transact(1008, data, null, 0); 1074 data.recycle(); 1075 1076 updateFlingerOptions(); 1077 } 1078 } catch (RemoteException ex) { 1079 // ignore 1080 } 1081 } 1082 updateMsaaOptions()1083 private void updateMsaaOptions() { 1084 updateSwitchPreference(mForceMsaa, DisplayProperties.debug_force_msaa().orElse(false)); 1085 } 1086 writeMsaaOptions()1087 private void writeMsaaOptions() { 1088 DisplayProperties.debug_force_msaa(mForceMsaa.isChecked()); 1089 SystemPropPoker.getInstance().poke(); 1090 } 1091 updateTrackFrameTimeOptions()1092 private void updateTrackFrameTimeOptions() { 1093 String value = SystemProperties.get(ThreadedRenderer.PROFILE_PROPERTY); 1094 if (value == null) { 1095 value = ""; 1096 } 1097 1098 CharSequence[] values = mTrackFrameTime.getEntryValues(); 1099 for (int i = 0; i < values.length; i++) { 1100 if (value.contentEquals(values[i])) { 1101 mTrackFrameTime.setValueIndex(i); 1102 mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[i]); 1103 return; 1104 } 1105 } 1106 mTrackFrameTime.setValueIndex(0); 1107 mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[0]); 1108 } 1109 writeTrackFrameTimeOptions(Object newValue)1110 private void writeTrackFrameTimeOptions(Object newValue) { 1111 SystemProperties.set(ThreadedRenderer.PROFILE_PROPERTY, 1112 newValue == null ? "" : newValue.toString()); 1113 SystemPropPoker.getInstance().poke(); 1114 updateTrackFrameTimeOptions(); 1115 } 1116 updateShowNonRectClipOptions()1117 private void updateShowNonRectClipOptions() { 1118 String value = SystemProperties.get( 1119 ThreadedRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY); 1120 if (value == null) { 1121 value = "hide"; 1122 } 1123 1124 CharSequence[] values = mShowNonRectClip.getEntryValues(); 1125 for (int i = 0; i < values.length; i++) { 1126 if (value.contentEquals(values[i])) { 1127 mShowNonRectClip.setValueIndex(i); 1128 mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[i]); 1129 return; 1130 } 1131 } 1132 mShowNonRectClip.setValueIndex(0); 1133 mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[0]); 1134 } 1135 writeShowNonRectClipOptions(Object newValue)1136 private void writeShowNonRectClipOptions(Object newValue) { 1137 SystemProperties.set(ThreadedRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY, 1138 newValue == null ? "" : newValue.toString()); 1139 SystemPropPoker.getInstance().poke(); 1140 updateShowNonRectClipOptions(); 1141 } 1142 updateShowHwScreenUpdatesOptions()1143 private void updateShowHwScreenUpdatesOptions() { 1144 updateSwitchPreference(mShowHwScreenUpdates, 1145 SystemProperties.getBoolean(ThreadedRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, false)); 1146 } 1147 writeShowHwScreenUpdatesOptions()1148 private void writeShowHwScreenUpdatesOptions() { 1149 SystemProperties.set(ThreadedRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, 1150 mShowHwScreenUpdates.isChecked() ? "true" : null); 1151 SystemPropPoker.getInstance().poke(); 1152 } 1153 updateShowHwLayersUpdatesOptions()1154 private void updateShowHwLayersUpdatesOptions() { 1155 updateSwitchPreference(mShowHwLayersUpdates, SystemProperties.getBoolean( 1156 ThreadedRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY, false)); 1157 } 1158 writeShowHwLayersUpdatesOptions()1159 private void writeShowHwLayersUpdatesOptions() { 1160 SystemProperties.set(ThreadedRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY, 1161 mShowHwLayersUpdates.isChecked() ? "true" : null); 1162 SystemPropPoker.getInstance().poke(); 1163 } 1164 updateDebugHwOverdrawOptions()1165 private void updateDebugHwOverdrawOptions() { 1166 String value = SystemProperties.get(ThreadedRenderer.DEBUG_OVERDRAW_PROPERTY); 1167 if (value == null) { 1168 value = ""; 1169 } 1170 1171 CharSequence[] values = mDebugHwOverdraw.getEntryValues(); 1172 for (int i = 0; i < values.length; i++) { 1173 if (value.contentEquals(values[i])) { 1174 mDebugHwOverdraw.setValueIndex(i); 1175 mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[i]); 1176 return; 1177 } 1178 } 1179 mDebugHwOverdraw.setValueIndex(0); 1180 mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[0]); 1181 } 1182 writeDebugHwOverdrawOptions(Object newValue)1183 private void writeDebugHwOverdrawOptions(Object newValue) { 1184 SystemProperties.set(ThreadedRenderer.DEBUG_OVERDRAW_PROPERTY, 1185 newValue == null ? "" : newValue.toString()); 1186 SystemPropPoker.getInstance().poke(); 1187 updateDebugHwOverdrawOptions(); 1188 } 1189 updateDebugLayoutOptions()1190 private void updateDebugLayoutOptions() { 1191 updateSwitchPreference(mDebugLayout, 1192 DisplayProperties.debug_layout().orElse(false)); 1193 } 1194 writeDebugLayoutOptions()1195 private void writeDebugLayoutOptions() { 1196 DisplayProperties.debug_layout(mDebugLayout.isChecked()); 1197 SystemPropPoker.getInstance().poke(); 1198 } 1199 updateSimulateColorSpace()1200 private void updateSimulateColorSpace() { 1201 final boolean enabled = Settings.Secure.getInt( 1202 mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0; 1203 if (enabled) { 1204 final String mode = Integer.toString(Settings.Secure.getInt( 1205 mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, 1206 AccessibilityManager.DALTONIZER_DISABLED)); 1207 mSimulateColorSpace.setValue(mode); 1208 final int index = mSimulateColorSpace.findIndexOfValue(mode); 1209 if (index < 0) { 1210 // We're using a mode controlled by accessibility preferences. 1211 mSimulateColorSpace.setSummary(getString(R.string.daltonizer_type_overridden, 1212 getString(R.string.accessibility_display_daltonizer_preference_title))); 1213 } else { 1214 mSimulateColorSpace.setSummary("%s"); 1215 } 1216 } else { 1217 mSimulateColorSpace.setValue( 1218 Integer.toString(AccessibilityManager.DALTONIZER_DISABLED)); 1219 } 1220 } 1221 1222 /** 1223 * @return <code>true</code> if the color space preference is currently 1224 * controlled by development settings 1225 */ usingDevelopmentColorSpace()1226 private boolean usingDevelopmentColorSpace() { 1227 final boolean enabled = Settings.Secure.getInt( 1228 mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0; 1229 if (enabled) { 1230 final String mode = Integer.toString(Settings.Secure.getInt( 1231 mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, 1232 AccessibilityManager.DALTONIZER_DISABLED)); 1233 final int index = mSimulateColorSpace.findIndexOfValue(mode); 1234 // We're using a mode controlled by developer preferences. 1235 return index >= 0; 1236 } 1237 return false; 1238 } 1239 writeSimulateColorSpace(Object value)1240 private void writeSimulateColorSpace(Object value) { 1241 final int newMode = Integer.parseInt(value.toString()); 1242 if (newMode < 0) { 1243 Settings.Secure.putInt(mContentResolver, 1244 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0); 1245 } else { 1246 Settings.Secure.putInt(mContentResolver, 1247 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 1); 1248 Settings.Secure.putInt(mContentResolver, 1249 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, newMode); 1250 } 1251 } 1252 updateUSBAudioOptions()1253 private void updateUSBAudioOptions() { 1254 updateSwitchPreference(mUSBAudio, Settings.Secure.getInt(mContentResolver, 1255 Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0) != 0); 1256 } 1257 writeUSBAudioOptions()1258 private void writeUSBAudioOptions() { 1259 Settings.Secure.putInt(mContentResolver, 1260 Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 1261 mUSBAudio.isChecked() ? 1 : 0); 1262 } 1263 writeRecordAudioOptions()1264 private void writeRecordAudioOptions() { 1265 if (mRecordAudio.isChecked()) { 1266 mRecordAudioSource.setVisible(true); 1267 try { 1268 int recordAudioSource = Integer.parseInt(mRecordAudioSource.getValue()); 1269 mAudioDebug.startRecording(recordAudioSource); 1270 } catch (AudioReaderException e) { 1271 mRecordAudio.setChecked(false); 1272 Toast errorToast = Toast.makeText(getContext(), 1273 getString(R.string.show_audio_recording_start_failed), Toast.LENGTH_SHORT); 1274 errorToast.show(); 1275 Log.e(TAG, "Unable to start recording audio from the microphone", e); 1276 // Revert the audio source to one that must work. 1277 mRecordAudioSource.setValue(Integer.toString(AudioSource.DEFAULT)); 1278 updateAudioRecordingOptions(); 1279 } 1280 } else { 1281 mAudioDebug.stopRecording(); 1282 } 1283 } 1284 1285 /** Called when audio recording is finished. Updates UI component states. */ onAudioRecorded(boolean successful)1286 private void onAudioRecorded(boolean successful) { 1287 mPlayRecordedAudio.setVisible(successful); 1288 mSaveAudio.setVisible(successful); 1289 mRecordAudio.setChecked(false); 1290 1291 if (!successful) { 1292 Toast errorToast = Toast.makeText(getContext(), 1293 getString(R.string.show_audio_recording_failed), Toast.LENGTH_SHORT); 1294 errorToast.show(); 1295 } 1296 } 1297 1298 /** Updates displayed audio recording metrics */ updateAudioRecordingMetrics(AudioMetrics.Data data)1299 private void updateAudioRecordingMetrics(AudioMetrics.Data data) { 1300 updateAudioRecordingMetric(mTimeToStartRead, data.timeToStartReadMs); 1301 updateAudioRecordingMetric(mTimeToValidAudio, data.timeToValidAudioMs); 1302 updateAudioRecordingMetric(mEmptyAudioDuration, data.emptyAudioDurationMs); 1303 } 1304 updateAudioRecordingMetric(Preference preference, Optional<Long> ts)1305 private static void updateAudioRecordingMetric(Preference preference, Optional<Long> ts) { 1306 ts.ifPresent(x -> preference.setVisible(true)); 1307 if (preference.isVisible()) { 1308 preference.setSummary(AudioMetrics.msTimestampToString(ts)); 1309 } 1310 } 1311 updateAudioRecordingOptions()1312 private void updateAudioRecordingOptions() { 1313 // Keep the summary matching the selected source 1314 mRecordAudioSource.setSummary(mRecordAudioSource.getEntry()); 1315 } 1316 playRecordedAudio()1317 private void playRecordedAudio() { 1318 mAudioDebug.playAudio(); 1319 } 1320 saveRecordedAudio()1321 private void saveRecordedAudio() { 1322 mAudioDebug.writeAudioToFile(); 1323 } 1324 updateForceResizableOptions()1325 private void updateForceResizableOptions() { 1326 updateSwitchPreference(mForceResizable, 1327 Settings.Global.getInt(mContentResolver, 1328 Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0); 1329 } 1330 writeForceResizableOptions()1331 private void writeForceResizableOptions() { 1332 Settings.Global.putInt(mContentResolver, 1333 Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 1334 mForceResizable.isChecked() ? 1 : 0); 1335 } 1336 updateForceRtlOptions()1337 private void updateForceRtlOptions() { 1338 updateSwitchPreference(mForceRtlLayout, 1339 Settings.Global.getInt(mContentResolver, 1340 Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0); 1341 } 1342 writeForceRtlOptions()1343 private void writeForceRtlOptions() { 1344 boolean value = mForceRtlLayout.isChecked(); 1345 Settings.Global.putInt(mContentResolver, 1346 Settings.Global.DEVELOPMENT_FORCE_RTL, value ? 1 : 0); 1347 DisplayProperties.debug_force_rtl(value); 1348 LocalePicker.updateLocale( 1349 getActivity().getResources().getConfiguration().getLocales().get(0)); 1350 } 1351 updateWindowBlursOptions()1352 private void updateWindowBlursOptions() { 1353 if (!CROSS_WINDOW_BLUR_SUPPORTED) { 1354 mWindowBlurs.setVisible(false); 1355 } else { 1356 updateSwitchPreference(mWindowBlurs, 1357 Settings.Global.getInt(mContentResolver, 1358 Settings.Global.DISABLE_WINDOW_BLURS, 0) == 0); 1359 } 1360 } 1361 writeWindowBlursOptions()1362 private void writeWindowBlursOptions() { 1363 boolean value = mWindowBlurs.isChecked(); 1364 Settings.Global.putInt(mContentResolver, 1365 Settings.Global.DISABLE_WINDOW_BLURS, value ? 0 : 1); 1366 } 1367 updateWifiDisplayCertificationOptions()1368 private void updateWifiDisplayCertificationOptions() { 1369 updateSwitchPreference(mWifiDisplayCertification, Settings.Global.getInt( 1370 mContentResolver, Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0); 1371 } 1372 writeWifiDisplayCertificationOptions()1373 private void writeWifiDisplayCertificationOptions() { 1374 Settings.Global.putInt(mContentResolver, 1375 Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 1376 mWifiDisplayCertification.isChecked() ? 1 : 0); 1377 } 1378 updateWifiVerboseLoggingOptions()1379 private void updateWifiVerboseLoggingOptions() { 1380 boolean enabled = mWifiManager != null && mWifiManager.isVerboseLoggingEnabled(); 1381 updateSwitchPreference(mWifiVerboseLogging, enabled); 1382 } 1383 writeWifiVerboseLoggingOptions()1384 private void writeWifiVerboseLoggingOptions() { 1385 if (mWifiManager != null) { 1386 mWifiManager.setVerboseLoggingEnabled(mWifiVerboseLogging.isChecked()); 1387 } 1388 } 1389 updateMobileDataAlwaysOnOptions()1390 private void updateMobileDataAlwaysOnOptions() { 1391 updateSwitchPreference(mMobileDataAlwaysOn, Settings.Global.getInt(mContentResolver, 1392 Settings.Global.MOBILE_DATA_ALWAYS_ON, 0) != 0); 1393 } 1394 writeMobileDataAlwaysOnOptions()1395 private void writeMobileDataAlwaysOnOptions() { 1396 Settings.Global.putInt(mContentResolver, Settings.Global.MOBILE_DATA_ALWAYS_ON, 1397 mMobileDataAlwaysOn.isChecked() ? 1 : 0); 1398 } 1399 listOnlySettableUsbConfigurationValues()1400 private void listOnlySettableUsbConfigurationValues() { 1401 final UsbManager manager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE); 1402 mUsbConfiguration.updatePreference(p -> p.setVisible(manager != null)); 1403 if (manager != null) { 1404 final List<Pair<String, String>> usbConfigurationValueTitlePairs = 1405 getSettableUsbConfigurationValueTitlePairs(); 1406 final String[] usbConfigurationValues = usbConfigurationValueTitlePairs.stream() 1407 .map(usbConfigurationValueTitlePair -> usbConfigurationValueTitlePair.first) 1408 .toArray(String[]::new); 1409 final String[] usbConfigurationTitles = usbConfigurationValueTitlePairs.stream() 1410 .map(usbConfigurationValueTitlePair -> usbConfigurationValueTitlePair.second) 1411 .toArray(String[]::new); 1412 mUsbConfiguration.updatePreference(listPreference -> { 1413 listPreference.setEntryValues(usbConfigurationValues); 1414 listPreference.setEntries(usbConfigurationTitles); 1415 }); 1416 } 1417 } 1418 getSettableUsbConfigurationValueTitlePairs()1419 private List<Pair<String, String>> getSettableUsbConfigurationValueTitlePairs() { 1420 final String[] values = getResources().getStringArray(R.array.usb_configuration_values); 1421 final String[] titles = getResources().getStringArray(R.array.usb_configuration_titles); 1422 final List<Pair<String, String>> settableUsbConfigurationValueTitlePairs = 1423 new ArrayList<>(); 1424 for (int i = 0; i < values.length; i++) { 1425 if (UsbManager.areSettableFunctions(UsbManager.usbFunctionsFromString(values[i]))) { 1426 settableUsbConfigurationValueTitlePairs.add(Pair.create(values[i], titles[i])); 1427 } 1428 } 1429 return settableUsbConfigurationValueTitlePairs; 1430 } 1431 updateUsbConfigurationValues()1432 private void updateUsbConfigurationValues() { 1433 final UsbManager manager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE); 1434 if (mUsbConfiguration == null) { 1435 return; 1436 } 1437 mUsbConfiguration.updatePreference(p -> p.setVisible(manager != null)); 1438 if (manager != null) { 1439 final List<Pair<String, String>> usbConfigurationValueTitlePairs = 1440 getSettableUsbConfigurationValueTitlePairs(); 1441 int index = 0; 1442 long functions = manager.getCurrentFunctions(); 1443 for (int i = 0; i < usbConfigurationValueTitlePairs.size(); i++) { 1444 if ((functions & UsbManager.usbFunctionsFromString( 1445 usbConfigurationValueTitlePairs.get(i).first)) != 0) { 1446 index = i; 1447 break; 1448 } 1449 } 1450 final int updateIndex = index; 1451 mUsbConfiguration.updatePreference(listPreference -> { 1452 listPreference.setValue(usbConfigurationValueTitlePairs.get(updateIndex).first); 1453 listPreference.setSummary(usbConfigurationValueTitlePairs.get(updateIndex).second); 1454 listPreference.setOnPreferenceChangeListener(this); 1455 }); 1456 } 1457 } 1458 writeUsbConfigurationOption(Object newValue)1459 private void writeUsbConfigurationOption(Object newValue) { 1460 UsbManager manager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE); 1461 String function = newValue.toString(); 1462 manager.setCurrentFunctions(UsbManager.usbFunctionsFromString(function)); 1463 } 1464 writeImmediatelyDestroyActivitiesOptions()1465 private void writeImmediatelyDestroyActivitiesOptions() { 1466 try { 1467 ActivityManager.getService().setAlwaysFinish( 1468 mImmediatelyDestroyActivities.isChecked()); 1469 } catch (RemoteException ex) { 1470 // ignore 1471 } 1472 } 1473 updateImmediatelyDestroyActivitiesOptions()1474 private void updateImmediatelyDestroyActivitiesOptions() { 1475 updateSwitchPreference(mImmediatelyDestroyActivities, Settings.Global.getInt( 1476 mContentResolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0); 1477 } 1478 updateAnimationScaleValue(int which, ListPreference pref)1479 private void updateAnimationScaleValue(int which, ListPreference pref) { 1480 try { 1481 float scale = mWindowManager.getAnimationScale(which); 1482 if (scale != 1) { 1483 mHaveDebugSettings = true; 1484 } 1485 CharSequence[] values = pref.getEntryValues(); 1486 for (int i = 0; i < values.length; i++) { 1487 float val = Float.parseFloat(values[i].toString()); 1488 if (scale <= val) { 1489 pref.setValueIndex(i); 1490 pref.setSummary(pref.getEntries()[i]); 1491 return; 1492 } 1493 } 1494 pref.setValueIndex(values.length - 1); 1495 pref.setSummary(pref.getEntries()[0]); 1496 } catch (RemoteException e) { 1497 // ignore 1498 } 1499 } 1500 updateAnimationScaleOptions()1501 private void updateAnimationScaleOptions() { 1502 updateAnimationScaleValue(0, mWindowAnimationScale); 1503 updateAnimationScaleValue(1, mTransitionAnimationScale); 1504 updateAnimationScaleValue(2, mAnimatorDurationScale); 1505 } 1506 writeAnimationScaleOption(int which, ListPreference pref, Object newValue)1507 private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) { 1508 try { 1509 float scale = newValue != null ? Float.parseFloat(newValue.toString()) : 1; 1510 mWindowManager.setAnimationScale(which, scale); 1511 updateAnimationScaleValue(which, pref); 1512 } catch (RemoteException e) { 1513 // ignore 1514 } 1515 } 1516 updateOverlayDisplayDevicesOptions()1517 private void updateOverlayDisplayDevicesOptions() { 1518 String value = Settings.Global.getString(mContentResolver, 1519 Settings.Global.OVERLAY_DISPLAY_DEVICES); 1520 if (value == null) { 1521 value = ""; 1522 } 1523 1524 CharSequence[] values = mOverlayDisplayDevices.getEntryValues(); 1525 for (int i = 0; i < values.length; i++) { 1526 if (value.contentEquals(values[i])) { 1527 mOverlayDisplayDevices.setValueIndex(i); 1528 mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[i]); 1529 return; 1530 } 1531 } 1532 mOverlayDisplayDevices.setValueIndex(0); 1533 mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[0]); 1534 } 1535 writeOverlayDisplayDevicesOptions(Object newValue)1536 private void writeOverlayDisplayDevicesOptions(Object newValue) { 1537 Settings.Global.putString(mContentResolver, Settings.Global.OVERLAY_DISPLAY_DEVICES, 1538 (String) newValue); 1539 updateOverlayDisplayDevicesOptions(); 1540 } 1541 updateOpenGLTracesOptions()1542 private void updateOpenGLTracesOptions() { 1543 String value = DisplayProperties.debug_opengl_trace().orElse(""); 1544 1545 CharSequence[] values = mOpenGLTraces.getEntryValues(); 1546 for (int i = 0; i < values.length; i++) { 1547 if (value.contentEquals(values[i])) { 1548 mOpenGLTraces.setValueIndex(i); 1549 mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[i]); 1550 return; 1551 } 1552 } 1553 mOpenGLTraces.setValueIndex(0); 1554 mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[0]); 1555 } 1556 writeOpenGLTracesOptions(Object newValue)1557 private void writeOpenGLTracesOptions(Object newValue) { 1558 DisplayProperties.debug_opengl_trace(newValue == null ? "" : newValue.toString()); 1559 SystemPropPoker.getInstance().poke(); 1560 updateOpenGLTracesOptions(); 1561 } 1562 updateAppProcessLimitOptions()1563 private void updateAppProcessLimitOptions() { 1564 try { 1565 int limit = ActivityManager.getService().getProcessLimit(); 1566 CharSequence[] values = mAppProcessLimit.getEntryValues(); 1567 for (int i = 0; i < values.length; i++) { 1568 int val = Integer.parseInt(values[i].toString()); 1569 if (val >= limit) { 1570 if (i != 0) { 1571 mHaveDebugSettings = true; 1572 } 1573 mAppProcessLimit.setValueIndex(i); 1574 mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]); 1575 return; 1576 } 1577 } 1578 mAppProcessLimit.setValueIndex(0); 1579 mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]); 1580 } catch (RemoteException e) { 1581 // ignore 1582 } 1583 } 1584 writeAppProcessLimitOptions(Object newValue)1585 private void writeAppProcessLimitOptions(Object newValue) { 1586 try { 1587 int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1; 1588 ActivityManager.getService().setProcessLimit(limit); 1589 updateAppProcessLimitOptions(); 1590 } catch (RemoteException e) { 1591 // ignore 1592 } 1593 } 1594 writeShowAllANRsOptions()1595 private void writeShowAllANRsOptions() { 1596 Settings.Secure.putInt(mContentResolver, Settings.Secure.ANR_SHOW_BACKGROUND, 1597 mShowAllANRs.isChecked() ? 1 : 0); 1598 } 1599 updateShowAllANRsOptions()1600 private void updateShowAllANRsOptions() { 1601 updateSwitchPreference(mShowAllANRs, Settings.Secure.getInt( 1602 mContentResolver, Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0); 1603 } 1604 1605 @Override onOemUnlockConfirm()1606 public void onOemUnlockConfirm() { 1607 mEnableOemUnlock.onOemUnlockConfirm(); 1608 updateAllOptions(); 1609 } 1610 1611 @Override onEnableDevelopmentConfirm()1612 public void onEnableDevelopmentConfirm() { 1613 mEnableDeveloper.setChecked(true); 1614 DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), true); 1615 mLastEnabledState = true; 1616 setPrefsEnabledState(true); 1617 } 1618 1619 @Override onEnableAdbConfirm()1620 public void onEnableAdbConfirm() { 1621 Settings.Global.putInt(mContentResolver, Settings.Global.ADB_ENABLED, 1); 1622 mEnableAdb.setChecked(true); 1623 updateVerifyAppsOverUsbOptions(); 1624 } 1625 1626 @Override onActivityResult(int requestCode, int resultCode, Intent data)1627 public void onActivityResult(int requestCode, int resultCode, Intent data) { 1628 if (requestCode == RESULT_DEBUG_APP) { 1629 if (resultCode == Activity.RESULT_OK) { 1630 mDebugApp = data.getAction(); 1631 writeDebuggerOptions(); 1632 updateDebuggerOptions(); 1633 } 1634 } else if (requestCode == RESULT_MOCK_LOCATION_APP) { 1635 if (resultCode == Activity.RESULT_OK) { 1636 mMockLocationApp = data.getAction(); 1637 writeMockLocation(); 1638 updateMockLocation(); 1639 } 1640 } else { 1641 super.onActivityResult(requestCode, resultCode, data); 1642 } 1643 } 1644 1645 @Override onPreferenceTreeClick(Preference preference)1646 public boolean onPreferenceTreeClick(Preference preference) { 1647 if (ActivityManager.isUserAMonkey()) { 1648 return false; 1649 } 1650 1651 if (preference == mEnableDeveloper) { 1652 if (mEnableDeveloper.isChecked()) { 1653 // Pass to super to launch the dialog, then uncheck until the dialog 1654 // result comes back 1655 super.onPreferenceTreeClick(preference); 1656 mEnableDeveloper.setChecked(false); 1657 } else { 1658 resetDangerousOptions(); 1659 DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), false); 1660 mLastEnabledState = false; 1661 setPrefsEnabledState(false); 1662 } 1663 } else if (preference == mBugreport) { 1664 captureBugReport(this.getActivity()); 1665 } else if (preference == mEnableAdb) { 1666 if (mEnableAdb.isChecked()) { 1667 // Pass to super to launch the dialog, then uncheck until the dialog 1668 // result comes back 1669 super.onPreferenceTreeClick(preference); 1670 mEnableAdb.setChecked(false); 1671 } else { 1672 Settings.Global.putInt(mContentResolver, Settings.Global.ADB_ENABLED, 0); 1673 mVerifyAppsOverUsb.setEnabled(false); 1674 mVerifyAppsOverUsb.setChecked(false); 1675 } 1676 } else if (preference == mEnableTerminal) { 1677 final PackageManager pm = getActivity().getPackageManager(); 1678 pm.setApplicationEnabledSetting(TERMINAL_APP_PACKAGE, 1679 mEnableTerminal.isChecked() ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 1680 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0); 1681 } else if (preference == mKeepScreenOn) { 1682 Settings.Global.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 1683 mKeepScreenOn.isChecked() ? 1684 (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) 1685 : 0); 1686 } else if (preference == mEnableOemUnlock.getPreference()) { 1687 if (!mEnableOemUnlock.onPreferenceClick()) { 1688 // Pass to super to launch the confirmation dialog. 1689 super.onPreferenceTreeClick(preference); 1690 } 1691 } else if (preference == mMockLocationAppPref) { 1692 Intent intent = new Intent(getActivity(), AppPicker.class); 1693 intent.putExtra(AppPicker.EXTRA_REQUESTIING_PERMISSION, 1694 Manifest.permission.ACCESS_MOCK_LOCATION); 1695 startActivityForResult(intent, RESULT_MOCK_LOCATION_APP); 1696 } else if (preference == mDebugViewAttributes) { 1697 Settings.Global.putInt(mContentResolver, Settings.Global.DEBUG_VIEW_ATTRIBUTES, 1698 mDebugViewAttributes.isChecked() ? 1 : 0); 1699 } else if (preference == mForceAllowOnExternal) { 1700 Settings.Global.putInt(mContentResolver, Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 1701 mForceAllowOnExternal.isChecked() ? 1 : 0); 1702 } else if (preference == mDebugAppPref) { 1703 Intent intent = new Intent(getActivity(), AppPicker.class); 1704 intent.putExtra(AppPicker.EXTRA_DEBUGGABLE, true); 1705 startActivityForResult(intent, RESULT_DEBUG_APP); 1706 } else if (preference == mWaitForDebugger) { 1707 writeDebuggerOptions(); 1708 } else if (preference == mVerifyAppsOverUsb) { 1709 writeVerifyAppsOverUsbOptions(); 1710 } else if (preference == mStrictMode) { 1711 writeStrictModeVisualOptions(); 1712 } else if (preference == mPointerLocation) { 1713 writePointerLocationOptions(); 1714 } else if (preference == mShowTouches) { 1715 writeShowTouchesOptions(); 1716 } else if (preference == mShowScreenUpdates) { 1717 writeShowUpdatesOption(); 1718 } else if (preference == mDisableOverlays) { 1719 writeDisableOverlaysOption(); 1720 } else if (preference == mImmediatelyDestroyActivities) { 1721 writeImmediatelyDestroyActivitiesOptions(); 1722 } else if (preference == mShowAllANRs) { 1723 writeShowAllANRsOptions(); 1724 } else if (preference == mForceMsaa) { 1725 writeMsaaOptions(); 1726 } else if (preference == mShowHwScreenUpdates) { 1727 writeShowHwScreenUpdatesOptions(); 1728 } else if (preference == mShowHwLayersUpdates) { 1729 writeShowHwLayersUpdatesOptions(); 1730 } else if (preference == mDebugLayout) { 1731 writeDebugLayoutOptions(); 1732 } else if (preference == mForceRtlLayout) { 1733 writeForceRtlOptions(); 1734 } else if (preference == mWindowBlurs) { 1735 writeWindowBlursOptions(); 1736 } else if (preference == mWifiDisplayCertification) { 1737 writeWifiDisplayCertificationOptions(); 1738 } else if (preference == mWifiVerboseLogging) { 1739 writeWifiVerboseLoggingOptions(); 1740 } else if (preference == mMobileDataAlwaysOn) { 1741 writeMobileDataAlwaysOnOptions(); 1742 } else if (preference == mUSBAudio) { 1743 writeUSBAudioOptions(); 1744 } else if (preference == mForceResizable) { 1745 writeForceResizableOptions(); 1746 } else if (preference == mRecordAudio) { 1747 writeRecordAudioOptions(); 1748 } else if (preference == mSaveAudio) { 1749 saveRecordedAudio(); 1750 } else if (preference == mPlayRecordedAudio) { 1751 playRecordedAudio(); 1752 } else { 1753 return super.onPreferenceTreeClick(preference); 1754 } 1755 1756 return false; 1757 } 1758 1759 @Override onPreferenceChange(Preference preference, Object newValue)1760 public boolean onPreferenceChange(Preference preference, Object newValue) { 1761 if (HDCP_CHECKING_KEY.equals(preference.getKey())) { 1762 SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString()); 1763 updateHdcpValues(); 1764 SystemPropPoker.getInstance().poke(); 1765 return true; 1766 } else if (preference == mUsbConfiguration.getOriginalPreference()) { 1767 writeUsbConfigurationOption(newValue); 1768 return true; 1769 } else if (preference == mWindowAnimationScale) { 1770 writeAnimationScaleOption(0, mWindowAnimationScale, newValue); 1771 return true; 1772 } else if (preference == mTransitionAnimationScale) { 1773 writeAnimationScaleOption(1, mTransitionAnimationScale, newValue); 1774 return true; 1775 } else if (preference == mAnimatorDurationScale) { 1776 writeAnimationScaleOption(2, mAnimatorDurationScale, newValue); 1777 return true; 1778 } else if (preference == mOverlayDisplayDevices) { 1779 writeOverlayDisplayDevicesOptions(newValue); 1780 return true; 1781 } else if (preference == mOpenGLTraces) { 1782 writeOpenGLTracesOptions(newValue); 1783 return true; 1784 } else if (preference == mTrackFrameTime) { 1785 writeTrackFrameTimeOptions(newValue); 1786 return true; 1787 } else if (preference == mDebugHwOverdraw) { 1788 writeDebugHwOverdrawOptions(newValue); 1789 return true; 1790 } else if (preference == mShowNonRectClip) { 1791 writeShowNonRectClipOptions(newValue); 1792 return true; 1793 } else if (preference == mAppProcessLimit) { 1794 writeAppProcessLimitOptions(newValue); 1795 return true; 1796 } else if (preference == mSimulateColorSpace) { 1797 writeSimulateColorSpace(newValue); 1798 return true; 1799 } else if (preference == mBtHciSnoopLog) { 1800 writeBtHciSnoopLogOptions(newValue); 1801 return true; 1802 } else if (preference == mRecordAudioSource) { 1803 /* Just keep the value in the preference, but accept the change */ 1804 return true; 1805 } 1806 return false; 1807 } 1808 1809 /** 1810 * Iterates through preference controllers that show confirmation dialogs and returns the 1811 * preference key for the first currently showing dialog. Ideally there should only ever be one. 1812 * 1813 * @return Preference key, or null if no dialog is showing 1814 */ getKeyForShowingDialog()1815 private String getKeyForShowingDialog() { 1816 // TODO: iterate through a fragment-wide list of PreferenceControllers and just pick out the 1817 // ConfirmationDialogController objects 1818 final List<ConfirmationDialogController> dialogControllers = new ArrayList<>(2); 1819 dialogControllers.add(mLogpersistController); 1820 for (ConfirmationDialogController dialogController : dialogControllers) { 1821 if (dialogController.isConfirmationDialogShowing()) { 1822 return dialogController.getPreferenceKey(); 1823 } 1824 } 1825 return null; 1826 } 1827 1828 /** 1829 * Re-show the dialog we lost previously 1830 * 1831 * @param preferenceKey Key for the preference the dialog is for 1832 */ recreateDialogForKey(String preferenceKey)1833 private void recreateDialogForKey(String preferenceKey) { 1834 // TODO: iterate through a fragment-wide list of PreferenceControllers and just pick out the 1835 // ConfirmationDialogController objects 1836 final List<ConfirmationDialogController> dialogControllers = new ArrayList<>(2); 1837 dialogControllers.add(mLogpersistController); 1838 for (ConfirmationDialogController dialogController : dialogControllers) { 1839 if (TextUtils.equals(preferenceKey, dialogController.getPreferenceKey())) { 1840 dialogController.showConfirmationDialog(findPreference(preferenceKey)); 1841 } 1842 } 1843 } 1844 dismissDialogs()1845 private void dismissDialogs() { 1846 mLogpersistController.dismissConfirmationDialog(); 1847 } 1848 1849 private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { 1850 @Override 1851 public void onReceive(Context context, Intent intent) { 1852 updateUsbConfigurationValues(); 1853 } 1854 }; 1855 isPackageInstalled(Context context, String packageName)1856 private static boolean isPackageInstalled(Context context, String packageName) { 1857 try { 1858 return context.getPackageManager().getPackageInfo(packageName, 0) != null; 1859 } catch (PackageManager.NameNotFoundException e) { 1860 return false; 1861 } 1862 } 1863 updateWirelessDebuggingPreference()1864 private void updateWirelessDebuggingPreference() { 1865 if (mWirelessDebugging == null) { 1866 return; 1867 } 1868 1869 if (!isNetworkConnected()) { 1870 if (FlavorUtils.isTwoPanel(getContext())) { 1871 mWirelessDebugging.setFragment(WirelessDebuggingInfoFragment.class.getName()); 1872 } 1873 mWirelessDebugging.setSummary(R.string.connectivity_summary_no_network_connected); 1874 } else { 1875 if (FlavorUtils.isTwoPanel(getContext())) { 1876 mWirelessDebugging.setFragment(WirelessDebuggingFragment.class.getName()); 1877 } 1878 boolean enabled = Settings.Global.getInt(mContentResolver, 1879 Settings.Global.ADB_WIFI_ENABLED, 1) != 0; 1880 if (enabled) { 1881 mWirelessDebugging.setSummary(R.string.enabled); 1882 } else { 1883 mWirelessDebugging.setSummary(R.string.disabled); 1884 } 1885 } 1886 } 1887 isNetworkConnected()1888 private boolean isNetworkConnected() { 1889 NetworkInfo activeNetworkInfo = mConnectivityManager.getActiveNetworkInfo(); 1890 return activeNetworkInfo != null && activeNetworkInfo.isConnected(); 1891 } 1892 1893 private class NetworkCallback extends ConnectivityManager.NetworkCallback { 1894 @Override onAvailable(Network network)1895 public void onAvailable(Network network) { 1896 super.onAvailable(network); 1897 mHandler.post(() -> updateWirelessDebuggingPreference()); 1898 } 1899 1900 @Override onLost(Network network)1901 public void onLost(Network network) { 1902 super.onLost(network); 1903 mHandler.post(() -> updateWirelessDebuggingPreference()); 1904 } 1905 } 1906 } 1907