OSDN Git Service

am b7e865ee: (-s ours) am 0431bc18: am e7e0c03f: DO NOT MERGE - Backport of ag/748147...
[android-x86/packages-apps-Settings.git] / src / com / android / settings / DevelopmentSettings.java
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.settings;
18
19 import android.app.Activity;
20 import android.app.ActivityManagerNative;
21 import android.app.AlertDialog;
22 import android.app.Dialog;
23 import android.app.admin.DevicePolicyManager;
24 import android.app.backup.IBackupManager;
25 import android.bluetooth.BluetoothAdapter;
26 import android.content.ContentResolver;
27 import android.content.Context;
28 import android.content.DialogInterface;
29 import android.content.Intent;
30 import android.content.pm.ApplicationInfo;
31 import android.content.pm.PackageManager;
32 import android.content.pm.PackageManager.NameNotFoundException;
33 import android.content.pm.ResolveInfo;
34 import android.hardware.usb.IUsbManager;
35 import android.net.wifi.WifiManager;
36 import android.os.AsyncTask;
37 import android.os.BatteryManager;
38 import android.os.Build;
39 import android.os.Bundle;
40 import android.os.IBinder;
41 import android.os.Parcel;
42 import android.os.RemoteException;
43 import android.os.ServiceManager;
44 import android.os.StrictMode;
45 import android.os.SystemProperties;
46 import android.os.UserHandle;
47 import android.os.UserManager;
48 import android.preference.CheckBoxPreference;
49 import android.preference.ListPreference;
50 import android.preference.Preference;
51 import android.preference.Preference.OnPreferenceChangeListener;
52 import android.preference.PreferenceGroup;
53 import android.preference.PreferenceScreen;
54 import android.provider.SearchIndexableResource;
55 import android.provider.Settings;
56 import android.text.TextUtils;
57 import android.util.Log;
58 import android.view.HardwareRenderer;
59 import android.view.IWindowManager;
60 import android.view.View;
61 import android.view.accessibility.AccessibilityManager;
62 import android.widget.Switch;
63 import android.widget.TextView;
64
65 import com.android.settings.search.BaseSearchIndexProvider;
66 import com.android.settings.search.Indexable;
67 import com.android.settings.widget.SwitchBar;
68 import dalvik.system.VMRuntime;
69
70 import java.util.ArrayList;
71 import java.util.Arrays;
72 import java.util.HashSet;
73 import java.util.List;
74
75 /*
76  * Displays preferences for application developers.
77  */
78 public class DevelopmentSettings extends SettingsPreferenceFragment
79         implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
80                 OnPreferenceChangeListener, SwitchBar.OnSwitchChangeListener, Indexable {
81     private static final String TAG = "DevelopmentSettings";
82
83     /**
84      * Preference file were development settings prefs are stored.
85      */
86     public static final String PREF_FILE = "development";
87
88     /**
89      * Whether to show the development settings to the user.  Default is false.
90      */
91     public static final String PREF_SHOW = "show";
92
93     private static final String ENABLE_ADB = "enable_adb";
94     private static final String CLEAR_ADB_KEYS = "clear_adb_keys";
95     private static final String ENABLE_TERMINAL = "enable_terminal";
96     private static final String KEEP_SCREEN_ON = "keep_screen_on";
97     private static final String BT_HCI_SNOOP_LOG = "bt_hci_snoop_log";
98     private static final String ENABLE_OEM_UNLOCK = "oem_unlock_enable";
99     private static final String ALLOW_MOCK_LOCATION = "allow_mock_location";
100     private static final String HDCP_CHECKING_KEY = "hdcp_checking";
101     private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking";
102     private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password";
103     private static final String HARDWARE_UI_PROPERTY = "persist.sys.ui.hw";
104     private static final String MSAA_PROPERTY = "debug.egl.force_msaa";
105     private static final String BUGREPORT = "bugreport";
106     private static final String BUGREPORT_IN_POWER_KEY = "bugreport_in_power";
107     private static final String OPENGL_TRACES_PROPERTY = "debug.egl.trace";
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 VERIFY_APPS_OVER_USB_KEY = "verify_apps_over_usb";
112     private static final String DEBUG_VIEW_ATTRIBUTES =  "debug_view_attributes";
113     private static final String STRICT_MODE_KEY = "strict_mode";
114     private static final String POINTER_LOCATION_KEY = "pointer_location";
115     private static final String SHOW_TOUCHES_KEY = "show_touches";
116     private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates";
117     private static final String DISABLE_OVERLAYS_KEY = "disable_overlays";
118     private static final String SIMULATE_COLOR_SPACE = "simulate_color_space";
119     private static final String USE_NUPLAYER_KEY = "use_nuplayer";
120     private static final String USB_AUDIO_KEY = "usb_audio";
121     private static final String USE_AWESOMEPLAYER_PROPERTY = "persist.sys.media.use-awesome";
122     private static final String SHOW_CPU_USAGE_KEY = "show_cpu_usage";
123     private static final String FORCE_HARDWARE_UI_KEY = "force_hw_ui";
124     private static final String FORCE_MSAA_KEY = "force_msaa";
125     private static final String TRACK_FRAME_TIME_KEY = "track_frame_time";
126     private static final String SHOW_NON_RECTANGULAR_CLIP_KEY = "show_non_rect_clip";
127     private static final String SHOW_HW_SCREEN_UPDATES_KEY = "show_hw_screen_udpates";
128     private static final String SHOW_HW_LAYERS_UPDATES_KEY = "show_hw_layers_udpates";
129     private static final String DEBUG_HW_OVERDRAW_KEY = "debug_hw_overdraw";
130     private static final String DEBUG_LAYOUT_KEY = "debug_layout";
131     private static final String FORCE_RTL_LAYOUT_KEY = "force_rtl_layout_all_locales";
132     private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale";
133     private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale";
134     private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale";
135     private static final String OVERLAY_DISPLAY_DEVICES_KEY = "overlay_display_devices";
136     private static final String DEBUG_DEBUGGING_CATEGORY_KEY = "debug_debugging_category";
137     private static final String DEBUG_APPLICATIONS_CATEGORY_KEY = "debug_applications_category";
138     private static final String WIFI_DISPLAY_CERTIFICATION_KEY = "wifi_display_certification";
139     private static final String WIFI_VERBOSE_LOGGING_KEY = "wifi_verbose_logging";
140     private static final String WIFI_AGGRESSIVE_HANDOVER_KEY = "wifi_aggressive_handover";
141     private static final String WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY = "wifi_allow_scan_with_traffic";
142     private static final String SELECT_LOGD_SIZE_KEY = "select_logd_size";
143     private static final String SELECT_LOGD_SIZE_PROPERTY = "persist.logd.size";
144     private static final String SELECT_LOGD_DEFAULT_SIZE_PROPERTY = "ro.logd.size";
145
146     private static final String OPENGL_TRACES_KEY = "enable_opengl_traces";
147
148     private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY
149             = "immediately_destroy_activities";
150     private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit";
151
152     private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs";
153
154     private static final String PROCESS_STATS = "proc_stats";
155
156     private static final String TAG_CONFIRM_ENFORCE = "confirm_enforce";
157
158     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
159
160     private static final String TERMINAL_APP_PACKAGE = "com.android.terminal";
161
162     private static final int RESULT_DEBUG_APP = 1000;
163
164     private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
165
166     private static String DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES = "262144"; // 256K
167
168     private IWindowManager mWindowManager;
169     private IBackupManager mBackupManager;
170     private DevicePolicyManager mDpm;
171     private UserManager mUm;
172     private WifiManager mWifiManager;
173
174     private SwitchBar mSwitchBar;
175     private boolean mLastEnabledState;
176     private boolean mHaveDebugSettings;
177     private boolean mDontPokeProperties;
178
179     private CheckBoxPreference mEnableAdb;
180     private Preference mClearAdbKeys;
181     private CheckBoxPreference mEnableTerminal;
182     private Preference mBugreport;
183     private CheckBoxPreference mBugreportInPower;
184     private CheckBoxPreference mKeepScreenOn;
185     private CheckBoxPreference mBtHciSnoopLog;
186     private CheckBoxPreference mEnableOemUnlock;
187     private CheckBoxPreference mAllowMockLocation;
188     private CheckBoxPreference mDebugViewAttributes;
189
190     private PreferenceScreen mPassword;
191     private String mDebugApp;
192     private Preference mDebugAppPref;
193     private CheckBoxPreference mWaitForDebugger;
194     private CheckBoxPreference mVerifyAppsOverUsb;
195     private CheckBoxPreference mWifiDisplayCertification;
196     private CheckBoxPreference mWifiVerboseLogging;
197     private CheckBoxPreference mWifiAggressiveHandover;
198
199     private CheckBoxPreference mWifiAllowScansWithTraffic;
200     private CheckBoxPreference mStrictMode;
201     private CheckBoxPreference mPointerLocation;
202     private CheckBoxPreference mShowTouches;
203     private CheckBoxPreference mShowScreenUpdates;
204     private CheckBoxPreference mDisableOverlays;
205     private CheckBoxPreference mShowCpuUsage;
206     private CheckBoxPreference mForceHardwareUi;
207     private CheckBoxPreference mForceMsaa;
208     private CheckBoxPreference mShowHwScreenUpdates;
209     private CheckBoxPreference mShowHwLayersUpdates;
210     private CheckBoxPreference mDebugLayout;
211     private CheckBoxPreference mForceRtlLayout;
212     private ListPreference mDebugHwOverdraw;
213     private ListPreference mLogdSize;
214     private ListPreference mTrackFrameTime;
215     private ListPreference mShowNonRectClip;
216     private ListPreference mWindowAnimationScale;
217     private ListPreference mTransitionAnimationScale;
218     private ListPreference mAnimatorDurationScale;
219     private ListPreference mOverlayDisplayDevices;
220     private ListPreference mOpenGLTraces;
221
222     private ListPreference mSimulateColorSpace;
223
224     private CheckBoxPreference mUseNuplayer;
225     private CheckBoxPreference mUSBAudio;
226     private CheckBoxPreference mImmediatelyDestroyActivities;
227
228     private ListPreference mAppProcessLimit;
229
230     private CheckBoxPreference mShowAllANRs;
231
232     private PreferenceScreen mProcessStats;
233     private final ArrayList<Preference> mAllPrefs = new ArrayList<Preference>();
234
235     private final ArrayList<CheckBoxPreference> mResetCbPrefs
236             = new ArrayList<CheckBoxPreference>();
237
238     private final HashSet<Preference> mDisabledPrefs = new HashSet<Preference>();
239     // To track whether a confirmation dialog was clicked.
240     private boolean mDialogClicked;
241     private Dialog mEnableDialog;
242     private Dialog mAdbDialog;
243
244     private Dialog mAdbKeysDialog;
245     private boolean mUnavailable;
246
247     @Override
248     public void onCreate(Bundle icicle) {
249         super.onCreate(icicle);
250
251         mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
252         mBackupManager = IBackupManager.Stub.asInterface(
253                 ServiceManager.getService(Context.BACKUP_SERVICE));
254         mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
255         mUm = (UserManager) getSystemService(Context.USER_SERVICE);
256
257         mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
258
259         if (android.os.Process.myUserHandle().getIdentifier() != UserHandle.USER_OWNER
260                 || mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
261             mUnavailable = true;
262             setPreferenceScreen(new PreferenceScreen(getActivity(), null));
263             return;
264         }
265
266         addPreferencesFromResource(R.xml.development_prefs);
267
268         final PreferenceGroup debugDebuggingCategory = (PreferenceGroup)
269                 findPreference(DEBUG_DEBUGGING_CATEGORY_KEY);
270
271         mEnableAdb = findAndInitCheckboxPref(ENABLE_ADB);
272         mClearAdbKeys = findPreference(CLEAR_ADB_KEYS);
273         if (!SystemProperties.getBoolean("ro.adb.secure", false)) {
274             if (debugDebuggingCategory != null) {
275                 debugDebuggingCategory.removePreference(mClearAdbKeys);
276             }
277         }
278         mAllPrefs.add(mClearAdbKeys);
279         mEnableTerminal = findAndInitCheckboxPref(ENABLE_TERMINAL);
280         if (!isPackageInstalled(getActivity(), TERMINAL_APP_PACKAGE)) {
281             debugDebuggingCategory.removePreference(mEnableTerminal);
282             mEnableTerminal = null;
283         }
284
285         mBugreport = findPreference(BUGREPORT);
286         mBugreportInPower = findAndInitCheckboxPref(BUGREPORT_IN_POWER_KEY);
287         mKeepScreenOn = findAndInitCheckboxPref(KEEP_SCREEN_ON);
288         mBtHciSnoopLog = findAndInitCheckboxPref(BT_HCI_SNOOP_LOG);
289         mEnableOemUnlock = findAndInitCheckboxPref(ENABLE_OEM_UNLOCK);
290         if (!showEnableOemUnlockPreference()) {
291             removePreference(mEnableOemUnlock);
292             mEnableOemUnlock = null;
293         }
294         mAllowMockLocation = findAndInitCheckboxPref(ALLOW_MOCK_LOCATION);
295         mDebugViewAttributes = findAndInitCheckboxPref(DEBUG_VIEW_ATTRIBUTES);
296         mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD);
297         mAllPrefs.add(mPassword);
298
299
300         if (!android.os.Process.myUserHandle().equals(UserHandle.OWNER)) {
301             disableForUser(mEnableAdb);
302             disableForUser(mClearAdbKeys);
303             disableForUser(mEnableTerminal);
304             disableForUser(mPassword);
305         }
306
307         mDebugAppPref = findPreference(DEBUG_APP_KEY);
308         mAllPrefs.add(mDebugAppPref);
309         mWaitForDebugger = findAndInitCheckboxPref(WAIT_FOR_DEBUGGER_KEY);
310         mVerifyAppsOverUsb = findAndInitCheckboxPref(VERIFY_APPS_OVER_USB_KEY);
311         if (!showVerifierSetting()) {
312             if (debugDebuggingCategory != null) {
313                 debugDebuggingCategory.removePreference(mVerifyAppsOverUsb);
314             } else {
315                 mVerifyAppsOverUsb.setEnabled(false);
316             }
317         }
318         mStrictMode = findAndInitCheckboxPref(STRICT_MODE_KEY);
319         mPointerLocation = findAndInitCheckboxPref(POINTER_LOCATION_KEY);
320         mShowTouches = findAndInitCheckboxPref(SHOW_TOUCHES_KEY);
321         mShowScreenUpdates = findAndInitCheckboxPref(SHOW_SCREEN_UPDATES_KEY);
322         mDisableOverlays = findAndInitCheckboxPref(DISABLE_OVERLAYS_KEY);
323         mShowCpuUsage = findAndInitCheckboxPref(SHOW_CPU_USAGE_KEY);
324         mForceHardwareUi = findAndInitCheckboxPref(FORCE_HARDWARE_UI_KEY);
325         mForceMsaa = findAndInitCheckboxPref(FORCE_MSAA_KEY);
326         mTrackFrameTime = addListPreference(TRACK_FRAME_TIME_KEY);
327         mShowNonRectClip = addListPreference(SHOW_NON_RECTANGULAR_CLIP_KEY);
328         mShowHwScreenUpdates = findAndInitCheckboxPref(SHOW_HW_SCREEN_UPDATES_KEY);
329         mShowHwLayersUpdates = findAndInitCheckboxPref(SHOW_HW_LAYERS_UPDATES_KEY);
330         mDebugLayout = findAndInitCheckboxPref(DEBUG_LAYOUT_KEY);
331         mForceRtlLayout = findAndInitCheckboxPref(FORCE_RTL_LAYOUT_KEY);
332         mDebugHwOverdraw = addListPreference(DEBUG_HW_OVERDRAW_KEY);
333         mWifiDisplayCertification = findAndInitCheckboxPref(WIFI_DISPLAY_CERTIFICATION_KEY);
334         mWifiVerboseLogging = findAndInitCheckboxPref(WIFI_VERBOSE_LOGGING_KEY);
335         mWifiAggressiveHandover = findAndInitCheckboxPref(WIFI_AGGRESSIVE_HANDOVER_KEY);
336         mWifiAllowScansWithTraffic = findAndInitCheckboxPref(WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY);
337         mLogdSize = addListPreference(SELECT_LOGD_SIZE_KEY);
338
339         mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY);
340         mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY);
341         mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY);
342         mOverlayDisplayDevices = addListPreference(OVERLAY_DISPLAY_DEVICES_KEY);
343         mOpenGLTraces = addListPreference(OPENGL_TRACES_KEY);
344         mSimulateColorSpace = addListPreference(SIMULATE_COLOR_SPACE);
345         mUseNuplayer = findAndInitCheckboxPref(USE_NUPLAYER_KEY);
346         mUSBAudio = findAndInitCheckboxPref(USB_AUDIO_KEY);
347
348         mImmediatelyDestroyActivities = (CheckBoxPreference) findPreference(
349                 IMMEDIATELY_DESTROY_ACTIVITIES_KEY);
350         mAllPrefs.add(mImmediatelyDestroyActivities);
351         mResetCbPrefs.add(mImmediatelyDestroyActivities);
352
353         mAppProcessLimit = addListPreference(APP_PROCESS_LIMIT_KEY);
354
355         mShowAllANRs = (CheckBoxPreference) findPreference(
356                 SHOW_ALL_ANRS_KEY);
357         mAllPrefs.add(mShowAllANRs);
358         mResetCbPrefs.add(mShowAllANRs);
359
360         Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY);
361         if (hdcpChecking != null) {
362             mAllPrefs.add(hdcpChecking);
363             removePreferenceForProduction(hdcpChecking);
364         }
365
366         mProcessStats = (PreferenceScreen) findPreference(PROCESS_STATS);
367         mAllPrefs.add(mProcessStats);
368     }
369
370     private ListPreference addListPreference(String prefKey) {
371         ListPreference pref = (ListPreference) findPreference(prefKey);
372         mAllPrefs.add(pref);
373         pref.setOnPreferenceChangeListener(this);
374         return pref;
375     }
376
377     private void disableForUser(Preference pref) {
378         if (pref != null) {
379             pref.setEnabled(false);
380             mDisabledPrefs.add(pref);
381         }
382     }
383
384     private CheckBoxPreference findAndInitCheckboxPref(String key) {
385         CheckBoxPreference pref = (CheckBoxPreference) findPreference(key);
386         if (pref == null) {
387             throw new IllegalArgumentException("Cannot find preference with key = " + key);
388         }
389         mAllPrefs.add(pref);
390         mResetCbPrefs.add(pref);
391         return pref;
392     }
393
394     @Override
395     public void onActivityCreated(Bundle savedInstanceState) {
396         super.onActivityCreated(savedInstanceState);
397
398         final SettingsActivity activity = (SettingsActivity) getActivity();
399
400         mSwitchBar = activity.getSwitchBar();
401        if (mUnavailable) {
402             mSwitchBar.setEnabled(false);
403             return;
404         }
405
406         mSwitchBar.addOnSwitchChangeListener(this);
407     }
408
409     private boolean removePreferenceForProduction(Preference preference) {
410         if ("user".equals(Build.TYPE)) {
411             removePreference(preference);
412             return true;
413         }
414         return false;
415     }
416
417     private void removePreference(Preference preference) {
418         getPreferenceScreen().removePreference(preference);
419         mAllPrefs.remove(preference);
420     }
421
422     private void setPrefsEnabledState(boolean enabled) {
423         for (int i = 0; i < mAllPrefs.size(); i++) {
424             Preference pref = mAllPrefs.get(i);
425             pref.setEnabled(enabled && !mDisabledPrefs.contains(pref));
426         }
427         updateAllOptions();
428     }
429
430     @Override
431     public void onResume() {
432         super.onResume();
433
434         if (mUnavailable) {
435             // Show error message
436             TextView emptyView = (TextView) getView().findViewById(android.R.id.empty);
437             getListView().setEmptyView(emptyView);
438             if (emptyView != null) {
439                 emptyView.setText(R.string.development_settings_not_available);
440             }
441             return;
442         }
443
444         if (mDpm.getMaximumTimeToLock(null) > 0) {
445             // A DeviceAdmin has specified a maximum time until the device
446             // will lock...  in this case we can't allow the user to turn
447             // on "stay awake when plugged in" because that would defeat the
448             // restriction.
449             mDisabledPrefs.add(mKeepScreenOn);
450         } else {
451             mDisabledPrefs.remove(mKeepScreenOn);
452         }
453
454         final ContentResolver cr = getActivity().getContentResolver();
455         mLastEnabledState = Settings.Global.getInt(cr,
456                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
457         mSwitchBar.setChecked(mLastEnabledState);
458         setPrefsEnabledState(mLastEnabledState);
459
460         if (mHaveDebugSettings && !mLastEnabledState) {
461             // Overall debugging is disabled, but there are some debug
462             // settings that are enabled.  This is an invalid state.  Switch
463             // to debug settings being enabled, so the user knows there is
464             // stuff enabled and can turn it all off if they want.
465             Settings.Global.putInt(getActivity().getContentResolver(),
466                     Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
467             mLastEnabledState = true;
468             mSwitchBar.setChecked(mLastEnabledState);
469             setPrefsEnabledState(mLastEnabledState);
470         }
471         mSwitchBar.show();
472     }
473
474     @Override
475     public void onDestroyView() {
476         super.onDestroyView();
477
478         if (mUnavailable) {
479             return;
480         }
481         mSwitchBar.removeOnSwitchChangeListener(this);
482         mSwitchBar.hide();
483     }
484
485     void updateCheckBox(CheckBoxPreference checkBox, boolean value) {
486         checkBox.setChecked(value);
487         mHaveDebugSettings |= value;
488     }
489
490     private void updateAllOptions() {
491         final Context context = getActivity();
492         final ContentResolver cr = context.getContentResolver();
493         mHaveDebugSettings = false;
494         updateCheckBox(mEnableAdb, Settings.Global.getInt(cr,
495                 Settings.Global.ADB_ENABLED, 0) != 0);
496         if (mEnableTerminal != null) {
497             updateCheckBox(mEnableTerminal,
498                     context.getPackageManager().getApplicationEnabledSetting(TERMINAL_APP_PACKAGE)
499                     == PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
500         }
501         updateCheckBox(mBugreportInPower, Settings.Secure.getInt(cr,
502                 Settings.Secure.BUGREPORT_IN_POWER_MENU, 0) != 0);
503         updateCheckBox(mKeepScreenOn, Settings.Global.getInt(cr,
504                 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
505         updateCheckBox(mBtHciSnoopLog, Settings.Secure.getInt(cr,
506                 Settings.Secure.BLUETOOTH_HCI_LOG, 0) != 0);
507         if (mEnableOemUnlock != null) {
508             updateCheckBox(mEnableOemUnlock, Utils.isOemUnlockEnabled(getActivity()));
509         }
510         updateCheckBox(mAllowMockLocation, Settings.Secure.getInt(cr,
511                 Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0);
512         updateCheckBox(mDebugViewAttributes, Settings.Global.getInt(cr,
513                 Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0);
514         updateHdcpValues();
515         updatePasswordSummary();
516         updateDebuggerOptions();
517         updateStrictModeVisualOptions();
518         updatePointerLocationOptions();
519         updateShowTouchesOptions();
520         updateFlingerOptions();
521         updateCpuUsageOptions();
522         updateHardwareUiOptions();
523         updateMsaaOptions();
524         updateTrackFrameTimeOptions();
525         updateShowNonRectClipOptions();
526         updateShowHwScreenUpdatesOptions();
527         updateShowHwLayersUpdatesOptions();
528         updateDebugHwOverdrawOptions();
529         updateDebugLayoutOptions();
530         updateAnimationScaleOptions();
531         updateOverlayDisplayDevicesOptions();
532         updateOpenGLTracesOptions();
533         updateImmediatelyDestroyActivitiesOptions();
534         updateAppProcessLimitOptions();
535         updateShowAllANRsOptions();
536         updateVerifyAppsOverUsbOptions();
537         updateBugreportOptions();
538         updateForceRtlOptions();
539         updateLogdSizeValues();
540         updateWifiDisplayCertificationOptions();
541         updateWifiVerboseLoggingOptions();
542         updateWifiAggressiveHandoverOptions();
543         updateWifiAllowScansWithTrafficOptions();
544         updateSimulateColorSpace();
545         updateUseNuplayerOptions();
546         updateUSBAudioOptions();
547     }
548
549     private void resetDangerousOptions() {
550         mDontPokeProperties = true;
551         for (int i=0; i<mResetCbPrefs.size(); i++) {
552             CheckBoxPreference cb = mResetCbPrefs.get(i);
553             if (cb.isChecked()) {
554                 cb.setChecked(false);
555                 onPreferenceTreeClick(null, cb);
556             }
557         }
558         resetDebuggerOptions();
559         writeLogdSizeOption(null);
560         writeAnimationScaleOption(0, mWindowAnimationScale, null);
561         writeAnimationScaleOption(1, mTransitionAnimationScale, null);
562         writeAnimationScaleOption(2, mAnimatorDurationScale, null);
563         // Only poke the color space setting if we control it.
564         if (usingDevelopmentColorSpace()) {
565             writeSimulateColorSpace(-1);
566         }
567         writeOverlayDisplayDevicesOptions(null);
568         writeAppProcessLimitOptions(null);
569         mHaveDebugSettings = false;
570         updateAllOptions();
571         mDontPokeProperties = false;
572         pokeSystemProperties();
573     }
574
575     private void updateHdcpValues() {
576         ListPreference hdcpChecking = (ListPreference) findPreference(HDCP_CHECKING_KEY);
577         if (hdcpChecking != null) {
578             String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY);
579             String[] values = getResources().getStringArray(R.array.hdcp_checking_values);
580             String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries);
581             int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values
582             for (int i = 0; i < values.length; i++) {
583                 if (currentValue.equals(values[i])) {
584                     index = i;
585                     break;
586                 }
587             }
588             hdcpChecking.setValue(values[index]);
589             hdcpChecking.setSummary(summaries[index]);
590             hdcpChecking.setOnPreferenceChangeListener(this);
591         }
592     }
593
594     private void updatePasswordSummary() {
595         try {
596             if (mBackupManager.hasBackupPassword()) {
597                 mPassword.setSummary(R.string.local_backup_password_summary_change);
598             } else {
599                 mPassword.setSummary(R.string.local_backup_password_summary_none);
600             }
601         } catch (RemoteException e) {
602             // Not much we can do here
603         }
604     }
605
606     private void writeBtHciSnoopLogOptions() {
607         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
608         adapter.configHciSnoopLog(mBtHciSnoopLog.isChecked());
609         Settings.Secure.putInt(getActivity().getContentResolver(),
610                 Settings.Secure.BLUETOOTH_HCI_LOG,
611                 mBtHciSnoopLog.isChecked() ? 1 : 0);
612     }
613
614     private void writeDebuggerOptions() {
615         try {
616             ActivityManagerNative.getDefault().setDebugApp(
617                 mDebugApp, mWaitForDebugger.isChecked(), true);
618         } catch (RemoteException ex) {
619         }
620     }
621
622     private static void resetDebuggerOptions() {
623         try {
624             ActivityManagerNative.getDefault().setDebugApp(
625                     null, false, true);
626         } catch (RemoteException ex) {
627         }
628     }
629
630     private void updateDebuggerOptions() {
631         mDebugApp = Settings.Global.getString(
632                 getActivity().getContentResolver(), Settings.Global.DEBUG_APP);
633         updateCheckBox(mWaitForDebugger, Settings.Global.getInt(
634                 getActivity().getContentResolver(), Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0);
635         if (mDebugApp != null && mDebugApp.length() > 0) {
636             String label;
637             try {
638                 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(mDebugApp,
639                         PackageManager.GET_DISABLED_COMPONENTS);
640                 CharSequence lab = getActivity().getPackageManager().getApplicationLabel(ai);
641                 label = lab != null ? lab.toString() : mDebugApp;
642             } catch (PackageManager.NameNotFoundException e) {
643                 label = mDebugApp;
644             }
645             mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_set, label));
646             mWaitForDebugger.setEnabled(true);
647             mHaveDebugSettings = true;
648         } else {
649             mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_not_set));
650             mWaitForDebugger.setEnabled(false);
651         }
652     }
653
654     private void updateVerifyAppsOverUsbOptions() {
655         updateCheckBox(mVerifyAppsOverUsb, Settings.Global.getInt(getActivity().getContentResolver(),
656                 Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0);
657         mVerifyAppsOverUsb.setEnabled(enableVerifierSetting());
658     }
659
660     private void writeVerifyAppsOverUsbOptions() {
661         Settings.Global.putInt(getActivity().getContentResolver(),
662               Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, mVerifyAppsOverUsb.isChecked() ? 1 : 0);
663     }
664
665     private boolean enableVerifierSetting() {
666         final ContentResolver cr = getActivity().getContentResolver();
667         if (Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) == 0) {
668             return false;
669         }
670         if (Settings.Global.getInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 0) {
671             return false;
672         } else {
673             final PackageManager pm = getActivity().getPackageManager();
674             final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
675             verification.setType(PACKAGE_MIME_TYPE);
676             verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
677             final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(verification, 0);
678             if (receivers.size() == 0) {
679                 return false;
680             }
681         }
682         return true;
683     }
684
685     private boolean showVerifierSetting() {
686         return Settings.Global.getInt(getActivity().getContentResolver(),
687                 Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0;
688     }
689
690     private static boolean showEnableOemUnlockPreference() {
691         return !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
692     }
693
694     private void updateBugreportOptions() {
695         if ("user".equals(Build.TYPE)) {
696             final ContentResolver resolver = getActivity().getContentResolver();
697             final boolean adbEnabled = Settings.Global.getInt(
698                     resolver, Settings.Global.ADB_ENABLED, 0) != 0;
699             if (adbEnabled) {
700                 mBugreport.setEnabled(true);
701                 mBugreportInPower.setEnabled(true);
702             } else {
703                 mBugreport.setEnabled(false);
704                 mBugreportInPower.setEnabled(false);
705                 mBugreportInPower.setChecked(false);
706                 Settings.Secure.putInt(resolver, Settings.Secure.BUGREPORT_IN_POWER_MENU, 0);
707             }
708         } else {
709             mBugreportInPower.setEnabled(true);
710         }
711     }
712
713     // Returns the current state of the system property that controls
714     // strictmode flashes.  One of:
715     //    0: not explicitly set one way or another
716     //    1: on
717     //    2: off
718     private static int currentStrictModeActiveIndex() {
719         if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) {
720             return 0;
721         }
722         boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false);
723         return enabled ? 1 : 2;
724     }
725
726     private void writeStrictModeVisualOptions() {
727         try {
728             mWindowManager.setStrictModeVisualIndicatorPreference(mStrictMode.isChecked()
729                     ? "1" : "");
730         } catch (RemoteException e) {
731         }
732     }
733
734     private void updateStrictModeVisualOptions() {
735         updateCheckBox(mStrictMode, currentStrictModeActiveIndex() == 1);
736     }
737
738     private void writePointerLocationOptions() {
739         Settings.System.putInt(getActivity().getContentResolver(),
740                 Settings.System.POINTER_LOCATION, mPointerLocation.isChecked() ? 1 : 0);
741     }
742
743     private void updatePointerLocationOptions() {
744         updateCheckBox(mPointerLocation, Settings.System.getInt(getActivity().getContentResolver(),
745                 Settings.System.POINTER_LOCATION, 0) != 0);
746     }
747
748     private void writeShowTouchesOptions() {
749         Settings.System.putInt(getActivity().getContentResolver(),
750                 Settings.System.SHOW_TOUCHES, mShowTouches.isChecked() ? 1 : 0);
751     }
752
753     private void updateShowTouchesOptions() {
754         updateCheckBox(mShowTouches, Settings.System.getInt(getActivity().getContentResolver(),
755                 Settings.System.SHOW_TOUCHES, 0) != 0);
756     }
757
758     private void updateFlingerOptions() {
759         // magic communication with surface flinger.
760         try {
761             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
762             if (flinger != null) {
763                 Parcel data = Parcel.obtain();
764                 Parcel reply = Parcel.obtain();
765                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
766                 flinger.transact(1010, data, reply, 0);
767                 @SuppressWarnings("unused")
768                 int showCpu = reply.readInt();
769                 @SuppressWarnings("unused")
770                 int enableGL = reply.readInt();
771                 int showUpdates = reply.readInt();
772                 updateCheckBox(mShowScreenUpdates, showUpdates != 0);
773                 @SuppressWarnings("unused")
774                 int showBackground = reply.readInt();
775                 int disableOverlays = reply.readInt();
776                 updateCheckBox(mDisableOverlays, disableOverlays != 0);
777                 reply.recycle();
778                 data.recycle();
779             }
780         } catch (RemoteException ex) {
781         }
782     }
783
784     private void writeShowUpdatesOption() {
785         try {
786             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
787             if (flinger != null) {
788                 Parcel data = Parcel.obtain();
789                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
790                 final int showUpdates = mShowScreenUpdates.isChecked() ? 1 : 0;
791                 data.writeInt(showUpdates);
792                 flinger.transact(1002, data, null, 0);
793                 data.recycle();
794
795                 updateFlingerOptions();
796             }
797         } catch (RemoteException ex) {
798         }
799     }
800
801     private void writeDisableOverlaysOption() {
802         try {
803             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
804             if (flinger != null) {
805                 Parcel data = Parcel.obtain();
806                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
807                 final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0;
808                 data.writeInt(disableOverlays);
809                 flinger.transact(1008, data, null, 0);
810                 data.recycle();
811
812                 updateFlingerOptions();
813             }
814         } catch (RemoteException ex) {
815         }
816     }
817
818     private void updateHardwareUiOptions() {
819         updateCheckBox(mForceHardwareUi, SystemProperties.getBoolean(HARDWARE_UI_PROPERTY, false));
820     }
821
822     private void writeHardwareUiOptions() {
823         SystemProperties.set(HARDWARE_UI_PROPERTY, mForceHardwareUi.isChecked() ? "true" : "false");
824         pokeSystemProperties();
825     }
826
827     private void updateMsaaOptions() {
828         updateCheckBox(mForceMsaa, SystemProperties.getBoolean(MSAA_PROPERTY, false));
829     }
830
831     private void writeMsaaOptions() {
832         SystemProperties.set(MSAA_PROPERTY, mForceMsaa.isChecked() ? "true" : "false");
833         pokeSystemProperties();
834     }
835
836     private void updateTrackFrameTimeOptions() {
837         String value = SystemProperties.get(HardwareRenderer.PROFILE_PROPERTY);
838         if (value == null) {
839             value = "";
840         }
841
842         CharSequence[] values = mTrackFrameTime.getEntryValues();
843         for (int i = 0; i < values.length; i++) {
844             if (value.contentEquals(values[i])) {
845                 mTrackFrameTime.setValueIndex(i);
846                 mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[i]);
847                 return;
848             }
849         }
850         mTrackFrameTime.setValueIndex(0);
851         mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[0]);
852     }
853
854     private void writeTrackFrameTimeOptions(Object newValue) {
855         SystemProperties.set(HardwareRenderer.PROFILE_PROPERTY,
856                 newValue == null ? "" : newValue.toString());
857         pokeSystemProperties();
858         updateTrackFrameTimeOptions();
859     }
860
861     private void updateShowNonRectClipOptions() {
862         String value = SystemProperties.get(
863                 HardwareRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY);
864         if (value == null) {
865             value = "hide";
866         }
867
868         CharSequence[] values = mShowNonRectClip.getEntryValues();
869         for (int i = 0; i < values.length; i++) {
870             if (value.contentEquals(values[i])) {
871                 mShowNonRectClip.setValueIndex(i);
872                 mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[i]);
873                 return;
874             }
875         }
876         mShowNonRectClip.setValueIndex(0);
877         mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[0]);
878     }
879
880     private void writeShowNonRectClipOptions(Object newValue) {
881         SystemProperties.set(HardwareRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY,
882                 newValue == null ? "" : newValue.toString());
883         pokeSystemProperties();
884         updateShowNonRectClipOptions();
885     }
886
887     private void updateShowHwScreenUpdatesOptions() {
888         updateCheckBox(mShowHwScreenUpdates,
889                 SystemProperties.getBoolean(HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, false));
890     }
891
892     private void writeShowHwScreenUpdatesOptions() {
893         SystemProperties.set(HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY,
894                 mShowHwScreenUpdates.isChecked() ? "true" : null);
895         pokeSystemProperties();
896     }
897
898     private void updateShowHwLayersUpdatesOptions() {
899         updateCheckBox(mShowHwLayersUpdates, SystemProperties.getBoolean(
900                 HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY, false));
901     }
902
903     private void writeShowHwLayersUpdatesOptions() {
904         SystemProperties.set(HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY,
905                 mShowHwLayersUpdates.isChecked() ? "true" : null);
906         pokeSystemProperties();
907     }
908
909     private void updateDebugHwOverdrawOptions() {
910         String value = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
911         if (value == null) {
912             value = "";
913         }
914
915         CharSequence[] values = mDebugHwOverdraw.getEntryValues();
916         for (int i = 0; i < values.length; i++) {
917             if (value.contentEquals(values[i])) {
918                 mDebugHwOverdraw.setValueIndex(i);
919                 mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[i]);
920                 return;
921             }
922         }
923         mDebugHwOverdraw.setValueIndex(0);
924         mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[0]);
925     }
926
927     private void writeDebugHwOverdrawOptions(Object newValue) {
928         SystemProperties.set(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY,
929                 newValue == null ? "" : newValue.toString());
930         pokeSystemProperties();
931         updateDebugHwOverdrawOptions();
932     }
933
934     private void updateDebugLayoutOptions() {
935         updateCheckBox(mDebugLayout,
936                 SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false));
937     }
938
939     private void writeDebugLayoutOptions() {
940         SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY,
941                 mDebugLayout.isChecked() ? "true" : "false");
942         pokeSystemProperties();
943     }
944
945     private void updateSimulateColorSpace() {
946         final ContentResolver cr = getContentResolver();
947         final boolean enabled = Settings.Secure.getInt(
948                 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
949         if (enabled) {
950             final String mode = Integer.toString(Settings.Secure.getInt(
951                     cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
952                     AccessibilityManager.DALTONIZER_DISABLED));
953             mSimulateColorSpace.setValue(mode);
954             final int index = mSimulateColorSpace.findIndexOfValue(mode);
955             if (index < 0) {
956                 // We're using a mode controlled by accessibility preferences.
957                 mSimulateColorSpace.setSummary(getString(R.string.daltonizer_type_overridden,
958                         getString(R.string.accessibility_display_daltonizer_preference_title)));
959             } else {
960                 mSimulateColorSpace.setSummary("%s");
961             }
962         } else {
963             mSimulateColorSpace.setValue(
964                     Integer.toString(AccessibilityManager.DALTONIZER_DISABLED));
965         }
966     }
967
968     /**
969      * @return <code>true</code> if the color space preference is currently
970      *         controlled by development settings
971      */
972     private boolean usingDevelopmentColorSpace() {
973         final ContentResolver cr = getContentResolver();
974         final boolean enabled = Settings.Secure.getInt(
975                 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
976         if (enabled) {
977             final String mode = Integer.toString(Settings.Secure.getInt(
978                     cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
979                     AccessibilityManager.DALTONIZER_DISABLED));
980             final int index = mSimulateColorSpace.findIndexOfValue(mode);
981             if (index >= 0) {
982                 // We're using a mode controlled by developer preferences.
983                 return true;
984             }
985         }
986         return false;
987     }
988
989     private void writeSimulateColorSpace(Object value) {
990         final ContentResolver cr = getContentResolver();
991         final int newMode = Integer.parseInt(value.toString());
992         if (newMode < 0) {
993             Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0);
994         } else {
995             Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 1);
996             Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, newMode);
997         }
998     }
999
1000     private void updateUseNuplayerOptions() {
1001         updateCheckBox(
1002                 mUseNuplayer, !SystemProperties.getBoolean(USE_AWESOMEPLAYER_PROPERTY, false));
1003     }
1004
1005     private void writeUseNuplayerOptions() {
1006         SystemProperties.set(
1007                 USE_AWESOMEPLAYER_PROPERTY, mUseNuplayer.isChecked() ? "false" : "true");
1008         pokeSystemProperties();
1009     }
1010
1011     private void updateUSBAudioOptions() {
1012         updateCheckBox(mUSBAudio, Settings.Secure.getInt(getContentResolver(),
1013                 Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0) != 0);
1014     }
1015
1016     private void writeUSBAudioOptions() {
1017         Settings.Secure.putInt(getContentResolver(),
1018                 Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED,
1019                 mUSBAudio.isChecked() ? 1 : 0);
1020     }
1021
1022     private void updateForceRtlOptions() {
1023         updateCheckBox(mForceRtlLayout, Settings.Global.getInt(getActivity().getContentResolver(),
1024                 Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0);
1025     }
1026
1027     private void writeForceRtlOptions() {
1028         boolean value = mForceRtlLayout.isChecked();
1029         Settings.Global.putInt(getActivity().getContentResolver(),
1030                 Settings.Global.DEVELOPMENT_FORCE_RTL, value ? 1 : 0);
1031         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, value ? "1" : "0");
1032         LocalePicker.updateLocale(getActivity().getResources().getConfiguration().locale);
1033     }
1034
1035     private void updateWifiDisplayCertificationOptions() {
1036         updateCheckBox(mWifiDisplayCertification, Settings.Global.getInt(
1037                 getActivity().getContentResolver(),
1038                 Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0);
1039     }
1040
1041     private void writeWifiDisplayCertificationOptions() {
1042         Settings.Global.putInt(getActivity().getContentResolver(),
1043                 Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON,
1044                 mWifiDisplayCertification.isChecked() ? 1 : 0);
1045     }
1046
1047     private void updateWifiVerboseLoggingOptions() {
1048         boolean enabled = mWifiManager.getVerboseLoggingLevel() > 0;
1049         updateCheckBox(mWifiVerboseLogging, enabled);
1050     }
1051
1052     private void writeWifiVerboseLoggingOptions() {
1053         mWifiManager.enableVerboseLogging(mWifiVerboseLogging.isChecked() ? 1 : 0);
1054     }
1055
1056     private void updateWifiAggressiveHandoverOptions() {
1057         boolean enabled = mWifiManager.getAggressiveHandover() > 0;
1058         updateCheckBox(mWifiAggressiveHandover, enabled);
1059     }
1060
1061     private void writeWifiAggressiveHandoverOptions() {
1062         mWifiManager.enableAggressiveHandover(mWifiAggressiveHandover.isChecked() ? 1 : 0);
1063     }
1064
1065     private void updateWifiAllowScansWithTrafficOptions() {
1066         boolean enabled = mWifiManager.getAllowScansWithTraffic() > 0;
1067         updateCheckBox(mWifiAllowScansWithTraffic, enabled);
1068     }
1069
1070     private void writeWifiAllowScansWithTrafficOptions() {
1071         mWifiManager.setAllowScansWithTraffic(mWifiAllowScansWithTraffic.isChecked() ? 1 : 0);
1072     }
1073
1074     private void updateLogdSizeValues() {
1075         if (mLogdSize != null) {
1076             String currentValue = SystemProperties.get(SELECT_LOGD_SIZE_PROPERTY);
1077             if (currentValue == null) {
1078                 currentValue = SystemProperties.get(SELECT_LOGD_DEFAULT_SIZE_PROPERTY);
1079                 if (currentValue == null) {
1080                     currentValue = "256K";
1081                 }
1082             }
1083             String[] values = getResources().getStringArray(R.array.select_logd_size_values);
1084             String[] titles = getResources().getStringArray(R.array.select_logd_size_titles);
1085             if (SystemProperties.get("ro.config.low_ram").equals("true")) {
1086                 mLogdSize.setEntries(R.array.select_logd_size_lowram_titles);
1087                 titles = getResources().getStringArray(R.array.select_logd_size_lowram_titles);
1088             }
1089             String[] summaries = getResources().getStringArray(R.array.select_logd_size_summaries);
1090             int index = 1; // punt to second entry if not found
1091             for (int i = 0; i < titles.length; i++) {
1092                 if (currentValue.equals(values[i])
1093                         || currentValue.equals(titles[i])) {
1094                     index = i;
1095                     break;
1096                 }
1097             }
1098             mLogdSize.setValue(values[index]);
1099             mLogdSize.setSummary(summaries[index]);
1100             mLogdSize.setOnPreferenceChangeListener(this);
1101         }
1102     }
1103
1104     private void writeLogdSizeOption(Object newValue) {
1105         String currentValue = SystemProperties.get(SELECT_LOGD_DEFAULT_SIZE_PROPERTY);
1106         if (currentValue != null) {
1107             DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES = currentValue;
1108         }
1109         final String size = (newValue != null) ?
1110                 newValue.toString() : DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES;
1111         SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, size);
1112         pokeSystemProperties();
1113         try {
1114             Process p = Runtime.getRuntime().exec("logcat -b all -G " + size);
1115             p.waitFor();
1116             Log.i(TAG, "Logcat ring buffer sizes set to: " + size);
1117         } catch (Exception e) {
1118             Log.w(TAG, "Cannot set logcat ring buffer sizes", e);
1119         }
1120         updateLogdSizeValues();
1121     }
1122
1123     private void updateCpuUsageOptions() {
1124         updateCheckBox(mShowCpuUsage, Settings.Global.getInt(getActivity().getContentResolver(),
1125                 Settings.Global.SHOW_PROCESSES, 0) != 0);
1126     }
1127
1128     private void writeCpuUsageOptions() {
1129         boolean value = mShowCpuUsage.isChecked();
1130         Settings.Global.putInt(getActivity().getContentResolver(),
1131                 Settings.Global.SHOW_PROCESSES, value ? 1 : 0);
1132         Intent service = (new Intent())
1133                 .setClassName("com.android.systemui", "com.android.systemui.LoadAverageService");
1134         if (value) {
1135             getActivity().startService(service);
1136         } else {
1137             getActivity().stopService(service);
1138         }
1139     }
1140
1141     private void writeImmediatelyDestroyActivitiesOptions() {
1142         try {
1143             ActivityManagerNative.getDefault().setAlwaysFinish(
1144                     mImmediatelyDestroyActivities.isChecked());
1145         } catch (RemoteException ex) {
1146         }
1147     }
1148
1149     private void updateImmediatelyDestroyActivitiesOptions() {
1150         updateCheckBox(mImmediatelyDestroyActivities, Settings.Global.getInt(
1151             getActivity().getContentResolver(), Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0);
1152     }
1153
1154     private void updateAnimationScaleValue(int which, ListPreference pref) {
1155         try {
1156             float scale = mWindowManager.getAnimationScale(which);
1157             if (scale != 1) {
1158                 mHaveDebugSettings = true;
1159             }
1160             CharSequence[] values = pref.getEntryValues();
1161             for (int i=0; i<values.length; i++) {
1162                 float val = Float.parseFloat(values[i].toString());
1163                 if (scale <= val) {
1164                     pref.setValueIndex(i);
1165                     pref.setSummary(pref.getEntries()[i]);
1166                     return;
1167                 }
1168             }
1169             pref.setValueIndex(values.length-1);
1170             pref.setSummary(pref.getEntries()[0]);
1171         } catch (RemoteException e) {
1172         }
1173     }
1174
1175     private void updateAnimationScaleOptions() {
1176         updateAnimationScaleValue(0, mWindowAnimationScale);
1177         updateAnimationScaleValue(1, mTransitionAnimationScale);
1178         updateAnimationScaleValue(2, mAnimatorDurationScale);
1179     }
1180
1181     private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) {
1182         try {
1183             float scale = newValue != null ? Float.parseFloat(newValue.toString()) : 1;
1184             mWindowManager.setAnimationScale(which, scale);
1185             updateAnimationScaleValue(which, pref);
1186         } catch (RemoteException e) {
1187         }
1188     }
1189
1190     private void updateOverlayDisplayDevicesOptions() {
1191         String value = Settings.Global.getString(getActivity().getContentResolver(),
1192                 Settings.Global.OVERLAY_DISPLAY_DEVICES);
1193         if (value == null) {
1194             value = "";
1195         }
1196
1197         CharSequence[] values = mOverlayDisplayDevices.getEntryValues();
1198         for (int i = 0; i < values.length; i++) {
1199             if (value.contentEquals(values[i])) {
1200                 mOverlayDisplayDevices.setValueIndex(i);
1201                 mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[i]);
1202                 return;
1203             }
1204         }
1205         mOverlayDisplayDevices.setValueIndex(0);
1206         mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[0]);
1207     }
1208
1209     private void writeOverlayDisplayDevicesOptions(Object newValue) {
1210         Settings.Global.putString(getActivity().getContentResolver(),
1211                 Settings.Global.OVERLAY_DISPLAY_DEVICES, (String)newValue);
1212         updateOverlayDisplayDevicesOptions();
1213     }
1214
1215     private void updateOpenGLTracesOptions() {
1216         String value = SystemProperties.get(OPENGL_TRACES_PROPERTY);
1217         if (value == null) {
1218             value = "";
1219         }
1220
1221         CharSequence[] values = mOpenGLTraces.getEntryValues();
1222         for (int i = 0; i < values.length; i++) {
1223             if (value.contentEquals(values[i])) {
1224                 mOpenGLTraces.setValueIndex(i);
1225                 mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[i]);
1226                 return;
1227             }
1228         }
1229         mOpenGLTraces.setValueIndex(0);
1230         mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[0]);
1231     }
1232
1233     private void writeOpenGLTracesOptions(Object newValue) {
1234         SystemProperties.set(OPENGL_TRACES_PROPERTY, newValue == null ? "" : newValue.toString());
1235         pokeSystemProperties();
1236         updateOpenGLTracesOptions();
1237     }
1238
1239     private void updateAppProcessLimitOptions() {
1240         try {
1241             int limit = ActivityManagerNative.getDefault().getProcessLimit();
1242             CharSequence[] values = mAppProcessLimit.getEntryValues();
1243             for (int i=0; i<values.length; i++) {
1244                 int val = Integer.parseInt(values[i].toString());
1245                 if (val >= limit) {
1246                     if (i != 0) {
1247                         mHaveDebugSettings = true;
1248                     }
1249                     mAppProcessLimit.setValueIndex(i);
1250                     mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]);
1251                     return;
1252                 }
1253             }
1254             mAppProcessLimit.setValueIndex(0);
1255             mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]);
1256         } catch (RemoteException e) {
1257         }
1258     }
1259
1260     private void writeAppProcessLimitOptions(Object newValue) {
1261         try {
1262             int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1;
1263             ActivityManagerNative.getDefault().setProcessLimit(limit);
1264             updateAppProcessLimitOptions();
1265         } catch (RemoteException e) {
1266         }
1267     }
1268
1269     private void writeShowAllANRsOptions() {
1270         Settings.Secure.putInt(getActivity().getContentResolver(),
1271                 Settings.Secure.ANR_SHOW_BACKGROUND,
1272                 mShowAllANRs.isChecked() ? 1 : 0);
1273     }
1274
1275     private void updateShowAllANRsOptions() {
1276         updateCheckBox(mShowAllANRs, Settings.Secure.getInt(
1277             getActivity().getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0);
1278     }
1279
1280     @Override
1281     public void onSwitchChanged(Switch switchView, boolean isChecked) {
1282         if (switchView != mSwitchBar.getSwitch()) {
1283             return;
1284         }
1285         if (isChecked != mLastEnabledState) {
1286             if (isChecked) {
1287                 mDialogClicked = false;
1288                 if (mEnableDialog != null) dismissDialogs();
1289                 mEnableDialog = new AlertDialog.Builder(getActivity()).setMessage(
1290                         getActivity().getResources().getString(
1291                                 R.string.dev_settings_warning_message))
1292                         .setTitle(R.string.dev_settings_warning_title)
1293                         .setPositiveButton(android.R.string.yes, this)
1294                         .setNegativeButton(android.R.string.no, this)
1295                         .show();
1296                 mEnableDialog.setOnDismissListener(this);
1297             } else {
1298                 resetDangerousOptions();
1299                 Settings.Global.putInt(getActivity().getContentResolver(),
1300                         Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
1301                 mLastEnabledState = isChecked;
1302                 setPrefsEnabledState(mLastEnabledState);
1303             }
1304         }
1305     }
1306
1307     @Override
1308     public void onActivityResult(int requestCode, int resultCode, Intent data) {
1309         if (requestCode == RESULT_DEBUG_APP) {
1310             if (resultCode == Activity.RESULT_OK) {
1311                 mDebugApp = data.getAction();
1312                 writeDebuggerOptions();
1313                 updateDebuggerOptions();
1314             }
1315         } else {
1316             super.onActivityResult(requestCode, resultCode, data);
1317         }
1318     }
1319
1320     @Override
1321     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
1322         if (Utils.isMonkeyRunning()) {
1323             return false;
1324         }
1325
1326         if (preference == mEnableAdb) {
1327             if (mEnableAdb.isChecked()) {
1328                 mDialogClicked = false;
1329                 if (mAdbDialog != null) dismissDialogs();
1330                 mAdbDialog = new AlertDialog.Builder(getActivity()).setMessage(
1331                         getActivity().getResources().getString(R.string.adb_warning_message))
1332                         .setTitle(R.string.adb_warning_title)
1333                         .setPositiveButton(android.R.string.yes, this)
1334                         .setNegativeButton(android.R.string.no, this)
1335                         .show();
1336                 mAdbDialog.setOnDismissListener(this);
1337             } else {
1338                 Settings.Global.putInt(getActivity().getContentResolver(),
1339                         Settings.Global.ADB_ENABLED, 0);
1340                 mVerifyAppsOverUsb.setEnabled(false);
1341                 mVerifyAppsOverUsb.setChecked(false);
1342                 updateBugreportOptions();
1343             }
1344         } else if (preference == mClearAdbKeys) {
1345             if (mAdbKeysDialog != null) dismissDialogs();
1346             mAdbKeysDialog = new AlertDialog.Builder(getActivity())
1347                         .setMessage(R.string.adb_keys_warning_message)
1348                         .setPositiveButton(android.R.string.ok, this)
1349                         .setNegativeButton(android.R.string.cancel, null)
1350                         .show();
1351         } else if (preference == mEnableTerminal) {
1352             final PackageManager pm = getActivity().getPackageManager();
1353             pm.setApplicationEnabledSetting(TERMINAL_APP_PACKAGE,
1354                     mEnableTerminal.isChecked() ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1355                             : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
1356         } else if (preference == mBugreportInPower) {
1357             Settings.Secure.putInt(getActivity().getContentResolver(),
1358                     Settings.Secure.BUGREPORT_IN_POWER_MENU,
1359                     mBugreportInPower.isChecked() ? 1 : 0);
1360         } else if (preference == mKeepScreenOn) {
1361             Settings.Global.putInt(getActivity().getContentResolver(),
1362                     Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
1363                     mKeepScreenOn.isChecked() ?
1364                             (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) : 0);
1365         } else if (preference == mBtHciSnoopLog) {
1366             writeBtHciSnoopLogOptions();
1367         } else if (preference == mEnableOemUnlock) {
1368             Utils.setOemUnlockEnabled(getActivity(), mEnableOemUnlock.isChecked());
1369         } else if (preference == mAllowMockLocation) {
1370             Settings.Secure.putInt(getActivity().getContentResolver(),
1371                     Settings.Secure.ALLOW_MOCK_LOCATION,
1372                     mAllowMockLocation.isChecked() ? 1 : 0);
1373         } else if (preference == mDebugViewAttributes) {
1374             Settings.Global.putInt(getActivity().getContentResolver(),
1375                     Settings.Global.DEBUG_VIEW_ATTRIBUTES,
1376                     mDebugViewAttributes.isChecked() ? 1 : 0);
1377         } else if (preference == mDebugAppPref) {
1378             startActivityForResult(new Intent(getActivity(), AppPicker.class), RESULT_DEBUG_APP);
1379         } else if (preference == mWaitForDebugger) {
1380             writeDebuggerOptions();
1381         } else if (preference == mVerifyAppsOverUsb) {
1382             writeVerifyAppsOverUsbOptions();
1383         } else if (preference == mStrictMode) {
1384             writeStrictModeVisualOptions();
1385         } else if (preference == mPointerLocation) {
1386             writePointerLocationOptions();
1387         } else if (preference == mShowTouches) {
1388             writeShowTouchesOptions();
1389         } else if (preference == mShowScreenUpdates) {
1390             writeShowUpdatesOption();
1391         } else if (preference == mDisableOverlays) {
1392             writeDisableOverlaysOption();
1393         } else if (preference == mShowCpuUsage) {
1394             writeCpuUsageOptions();
1395         } else if (preference == mImmediatelyDestroyActivities) {
1396             writeImmediatelyDestroyActivitiesOptions();
1397         } else if (preference == mShowAllANRs) {
1398             writeShowAllANRsOptions();
1399         } else if (preference == mForceHardwareUi) {
1400             writeHardwareUiOptions();
1401         } else if (preference == mForceMsaa) {
1402             writeMsaaOptions();
1403         } else if (preference == mShowHwScreenUpdates) {
1404             writeShowHwScreenUpdatesOptions();
1405         } else if (preference == mShowHwLayersUpdates) {
1406             writeShowHwLayersUpdatesOptions();
1407         } else if (preference == mDebugLayout) {
1408             writeDebugLayoutOptions();
1409         } else if (preference == mForceRtlLayout) {
1410             writeForceRtlOptions();
1411         } else if (preference == mWifiDisplayCertification) {
1412             writeWifiDisplayCertificationOptions();
1413         } else if (preference == mWifiVerboseLogging) {
1414             writeWifiVerboseLoggingOptions();
1415         } else if (preference == mWifiAggressiveHandover) {
1416             writeWifiAggressiveHandoverOptions();
1417         } else if (preference == mWifiAllowScansWithTraffic) {
1418             writeWifiAllowScansWithTrafficOptions();
1419         } else if (preference == mUseNuplayer) {
1420             writeUseNuplayerOptions();
1421         } else if (preference == mUSBAudio) {
1422             writeUSBAudioOptions();
1423         } else {
1424             return super.onPreferenceTreeClick(preferenceScreen, preference);
1425         }
1426
1427         return false;
1428     }
1429
1430     @Override
1431     public boolean onPreferenceChange(Preference preference, Object newValue) {
1432         if (HDCP_CHECKING_KEY.equals(preference.getKey())) {
1433             SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString());
1434             updateHdcpValues();
1435             pokeSystemProperties();
1436             return true;
1437         } else if (preference == mLogdSize) {
1438             writeLogdSizeOption(newValue);
1439             return true;
1440         } else if (preference == mWindowAnimationScale) {
1441             writeAnimationScaleOption(0, mWindowAnimationScale, newValue);
1442             return true;
1443         } else if (preference == mTransitionAnimationScale) {
1444             writeAnimationScaleOption(1, mTransitionAnimationScale, newValue);
1445             return true;
1446         } else if (preference == mAnimatorDurationScale) {
1447             writeAnimationScaleOption(2, mAnimatorDurationScale, newValue);
1448             return true;
1449         } else if (preference == mOverlayDisplayDevices) {
1450             writeOverlayDisplayDevicesOptions(newValue);
1451             return true;
1452         } else if (preference == mOpenGLTraces) {
1453             writeOpenGLTracesOptions(newValue);
1454             return true;
1455         } else if (preference == mTrackFrameTime) {
1456             writeTrackFrameTimeOptions(newValue);
1457             return true;
1458         } else if (preference == mDebugHwOverdraw) {
1459             writeDebugHwOverdrawOptions(newValue);
1460             return true;
1461         } else if (preference == mShowNonRectClip) {
1462             writeShowNonRectClipOptions(newValue);
1463             return true;
1464         } else if (preference == mAppProcessLimit) {
1465             writeAppProcessLimitOptions(newValue);
1466             return true;
1467         } else if (preference == mSimulateColorSpace) {
1468             writeSimulateColorSpace(newValue);
1469             return true;
1470         }
1471         return false;
1472     }
1473
1474     private void dismissDialogs() {
1475         if (mAdbDialog != null) {
1476             mAdbDialog.dismiss();
1477             mAdbDialog = null;
1478         }
1479         if (mAdbKeysDialog != null) {
1480             mAdbKeysDialog.dismiss();
1481             mAdbKeysDialog = null;
1482         }
1483         if (mEnableDialog != null) {
1484             mEnableDialog.dismiss();
1485             mEnableDialog = null;
1486         }
1487     }
1488
1489     public void onClick(DialogInterface dialog, int which) {
1490         if (dialog == mAdbDialog) {
1491             if (which == DialogInterface.BUTTON_POSITIVE) {
1492                 mDialogClicked = true;
1493                 Settings.Global.putInt(getActivity().getContentResolver(),
1494                         Settings.Global.ADB_ENABLED, 1);
1495                 mVerifyAppsOverUsb.setEnabled(true);
1496                 updateVerifyAppsOverUsbOptions();
1497                 updateBugreportOptions();
1498             } else {
1499                 // Reset the toggle
1500                 mEnableAdb.setChecked(false);
1501             }
1502         } else if (dialog == mAdbKeysDialog) {
1503             if (which == DialogInterface.BUTTON_POSITIVE) {
1504                 try {
1505                     IBinder b = ServiceManager.getService(Context.USB_SERVICE);
1506                     IUsbManager service = IUsbManager.Stub.asInterface(b);
1507                     service.clearUsbDebuggingKeys();
1508                 } catch (RemoteException e) {
1509                     Log.e(TAG, "Unable to clear adb keys", e);
1510                 }
1511             }
1512         } else if (dialog == mEnableDialog) {
1513             if (which == DialogInterface.BUTTON_POSITIVE) {
1514                 mDialogClicked = true;
1515                 Settings.Global.putInt(getActivity().getContentResolver(),
1516                         Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
1517                 mLastEnabledState = true;
1518                 setPrefsEnabledState(mLastEnabledState);
1519             } else {
1520                 // Reset the toggle
1521                 mSwitchBar.setChecked(false);
1522             }
1523         }
1524     }
1525
1526     public void onDismiss(DialogInterface dialog) {
1527         // Assuming that onClick gets called first
1528         if (dialog == mAdbDialog) {
1529             if (!mDialogClicked) {
1530                 mEnableAdb.setChecked(false);
1531             }
1532             mAdbDialog = null;
1533         } else if (dialog == mEnableDialog) {
1534             if (!mDialogClicked) {
1535                 mSwitchBar.setChecked(false);
1536             }
1537             mEnableDialog = null;
1538         }
1539     }
1540
1541     @Override
1542     public void onDestroy() {
1543         dismissDialogs();
1544         super.onDestroy();
1545     }
1546
1547     void pokeSystemProperties() {
1548         if (!mDontPokeProperties) {
1549             //noinspection unchecked
1550             (new SystemPropPoker()).execute();
1551         }
1552     }
1553
1554     static class SystemPropPoker extends AsyncTask<Void, Void, Void> {
1555         @Override
1556         protected Void doInBackground(Void... params) {
1557             String[] services;
1558             try {
1559                 services = ServiceManager.listServices();
1560             } catch (RemoteException e) {
1561                 return null;
1562             }
1563             for (String service : services) {
1564                 IBinder obj = ServiceManager.checkService(service);
1565                 if (obj != null) {
1566                     Parcel data = Parcel.obtain();
1567                     try {
1568                         obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0);
1569                     } catch (RemoteException e) {
1570                     } catch (Exception e) {
1571                         Log.i(TAG, "Someone wrote a bad service '" + service
1572                                 + "' that doesn't like to be poked: " + e);
1573                     }
1574                     data.recycle();
1575                 }
1576             }
1577             return null;
1578         }
1579     }
1580
1581     private static boolean isPackageInstalled(Context context, String packageName) {
1582         try {
1583             return context.getPackageManager().getPackageInfo(packageName, 0) != null;
1584         } catch (NameNotFoundException e) {
1585             return false;
1586         }
1587     }
1588
1589     /**
1590      * For Search.
1591      */
1592     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
1593             new BaseSearchIndexProvider() {
1594
1595                 private boolean isShowingDeveloperOptions(Context context) {
1596                     return context.getSharedPreferences(DevelopmentSettings.PREF_FILE,
1597                             Context.MODE_PRIVATE).getBoolean(
1598                                     DevelopmentSettings.PREF_SHOW,
1599                                     android.os.Build.TYPE.equals("eng"));
1600                 }
1601
1602                 @Override
1603                 public List<SearchIndexableResource> getXmlResourcesToIndex(
1604                         Context context, boolean enabled) {
1605
1606                     if (!isShowingDeveloperOptions(context)) {
1607                         return null;
1608                     }
1609
1610                     final SearchIndexableResource sir = new SearchIndexableResource(context);
1611                     sir.xmlResId = R.xml.development_prefs;
1612                     return Arrays.asList(sir);
1613                 }
1614
1615                 @Override
1616                 public List<String> getNonIndexableKeys(Context context) {
1617                     if (!isShowingDeveloperOptions(context)) {
1618                         return null;
1619                     }
1620
1621                     final List<String> keys = new ArrayList<String>();
1622                     if (!showEnableOemUnlockPreference()) {
1623                         keys.add(ENABLE_OEM_UNLOCK);
1624                     }
1625                     return keys;
1626                 }
1627             };
1628 }