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