OSDN Git Service

ee81bcd63e150864885e2602d2129fa295cf13fc
[android-x86/packages-apps-Settings.git] / src / com / android / settings / ButtonSettings.java
1 /*
2  * Copyright (C) 2013 The CyanogenMod 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.content.ComponentName;
20 import android.content.ContentResolver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.content.pm.ResolveInfo;
25 import android.content.res.Resources;
26 import android.content.SharedPreferences;
27 import android.content.SharedPreferences.Editor;
28 import android.os.Bundle;
29 import android.os.RemoteException;
30 import android.os.Handler;
31 import android.preference.ListPreference;
32 import android.preference.Preference;
33 import android.preference.PreferenceCategory;
34 import android.preference.PreferenceManager;
35 import android.preference.PreferenceScreen;
36 import android.preference.SwitchPreference;
37 import android.provider.Settings;
38
39 import android.util.Log;
40 import android.view.IWindowManager;
41 import android.view.KeyCharacterMap;
42 import android.view.KeyEvent;
43 import android.view.WindowManagerGlobal;
44
45 import com.android.internal.logging.MetricsLogger;
46 import com.android.settings.R;
47 import com.android.settings.SettingsPreferenceFragment;
48 import com.android.settings.Utils;
49 import com.android.settings.cyanogenmod.ButtonBacklightBrightness;
50
51 import org.cyanogenmod.hardware.KeyDisabler;
52
53 public class ButtonSettings extends SettingsPreferenceFragment implements
54         Preference.OnPreferenceChangeListener {
55     private static final String TAG = "SystemSettings";
56
57     private static final String KEY_BUTTON_BACKLIGHT = "button_backlight";
58     private static final String KEY_HOME_LONG_PRESS = "hardware_keys_home_long_press";
59     private static final String KEY_HOME_DOUBLE_TAP = "hardware_keys_home_double_tap";
60     private static final String KEY_MENU_PRESS = "hardware_keys_menu_press";
61     private static final String KEY_MENU_LONG_PRESS = "hardware_keys_menu_long_press";
62     private static final String KEY_ASSIST_PRESS = "hardware_keys_assist_press";
63     private static final String KEY_ASSIST_LONG_PRESS = "hardware_keys_assist_long_press";
64     private static final String KEY_APP_SWITCH_PRESS = "hardware_keys_app_switch_press";
65     private static final String KEY_APP_SWITCH_LONG_PRESS = "hardware_keys_app_switch_long_press";
66     private static final String KEY_VOLUME_KEY_CURSOR_CONTROL = "volume_key_cursor_control";
67     private static final String KEY_SWAP_VOLUME_BUTTONS = "swap_volume_buttons";
68     private static final String DISABLE_NAV_KEYS = "disable_nav_keys";
69     private static final String KEY_NAVIGATION_BAR_LEFT = "navigation_bar_left";
70     private static final String KEY_NAVIGATION_RECENTS_LONG_PRESS = "navigation_recents_long_press";
71     private static final String KEY_POWER_END_CALL = "power_end_call";
72     private static final String KEY_HOME_ANSWER_CALL = "home_answer_call";
73     private static final String KEY_BLUETOOTH_INPUT_SETTINGS = "bluetooth_input_settings";
74
75     private static final String CATEGORY_POWER = "power_key";
76     private static final String CATEGORY_HOME = "home_key";
77     private static final String CATEGORY_BACK = "back_key";
78     private static final String CATEGORY_MENU = "menu_key";
79     private static final String CATEGORY_ASSIST = "assist_key";
80     private static final String CATEGORY_APPSWITCH = "app_switch_key";
81     private static final String CATEGORY_CAMERA = "camera_key";
82     private static final String CATEGORY_VOLUME = "volume_keys";
83     private static final String CATEGORY_BACKLIGHT = "key_backlight";
84     private static final String CATEGORY_NAVBAR = "navigation_bar";
85
86     // Available custom actions to perform on a key press.
87     // Must match values for KEY_HOME_LONG_PRESS_ACTION in:
88     // frameworks/base/core/java/android/provider/Settings.java
89     private static final int ACTION_NOTHING = 0;
90     private static final int ACTION_MENU = 1;
91     private static final int ACTION_APP_SWITCH = 2;
92     private static final int ACTION_SEARCH = 3;
93     private static final int ACTION_VOICE_SEARCH = 4;
94     private static final int ACTION_IN_APP_SEARCH = 5;
95     private static final int ACTION_LAUNCH_CAMERA = 6;
96     private static final int ACTION_SLEEP = 7;
97     private static final int ACTION_LAST_APP = 8;
98
99     // Masks for checking presence of hardware keys.
100     // Must match values in frameworks/base/core/res/res/values/config.xml
101     public static final int KEY_MASK_HOME = 0x01;
102     public static final int KEY_MASK_BACK = 0x02;
103     public static final int KEY_MASK_MENU = 0x04;
104     public static final int KEY_MASK_ASSIST = 0x08;
105     public static final int KEY_MASK_APP_SWITCH = 0x10;
106     public static final int KEY_MASK_CAMERA = 0x20;
107     public static final int KEY_MASK_VOLUME = 0x40;
108
109     private ListPreference mHomeLongPressAction;
110     private ListPreference mHomeDoubleTapAction;
111     private ListPreference mMenuPressAction;
112     private ListPreference mMenuLongPressAction;
113     private ListPreference mAssistPressAction;
114     private ListPreference mAssistLongPressAction;
115     private ListPreference mAppSwitchPressAction;
116     private ListPreference mAppSwitchLongPressAction;
117     private ListPreference mVolumeKeyCursorControl;
118     private SwitchPreference mSwapVolumeButtons;
119     private SwitchPreference mDisableNavigationKeys;
120     private SwitchPreference mNavigationBarLeftPref;
121     private ListPreference mNavigationRecentsLongPressAction;
122     private SwitchPreference mPowerEndCall;
123     private SwitchPreference mHomeAnswerCall;
124
125     private PreferenceCategory mNavigationPreferencesCat;
126
127     private Handler mHandler;
128
129     @Override
130     public void onCreate(Bundle savedInstanceState) {
131         super.onCreate(savedInstanceState);
132
133         addPreferencesFromResource(R.xml.button_settings);
134
135         final Resources res = getResources();
136         final ContentResolver resolver = getActivity().getContentResolver();
137         final PreferenceScreen prefScreen = getPreferenceScreen();
138
139         final int deviceKeys = getResources().getInteger(
140                 com.android.internal.R.integer.config_deviceHardwareKeys);
141         final int deviceWakeKeys = getResources().getInteger(
142                 com.android.internal.R.integer.config_deviceHardwareWakeKeys);
143
144         final boolean hasPowerKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER);
145         final boolean hasHomeKey = (deviceKeys & KEY_MASK_HOME) != 0;
146         final boolean hasBackKey = (deviceKeys & KEY_MASK_BACK) != 0;
147         final boolean hasMenuKey = (deviceKeys & KEY_MASK_MENU) != 0;
148         final boolean hasAssistKey = (deviceKeys & KEY_MASK_ASSIST) != 0;
149         final boolean hasAppSwitchKey = (deviceKeys & KEY_MASK_APP_SWITCH) != 0;
150         final boolean hasVolumeKeys = (deviceKeys & KEY_MASK_VOLUME) != 0;
151
152         final boolean showHomeWake = (deviceWakeKeys & KEY_MASK_HOME) != 0;
153         final boolean showBackWake = (deviceWakeKeys & KEY_MASK_BACK) != 0;
154         final boolean showMenuWake = (deviceWakeKeys & KEY_MASK_MENU) != 0;
155         final boolean showAssistWake = (deviceWakeKeys & KEY_MASK_ASSIST) != 0;
156         final boolean showAppSwitchWake = (deviceWakeKeys & KEY_MASK_APP_SWITCH) != 0;
157         final boolean showVolumeWake = (deviceWakeKeys & KEY_MASK_VOLUME) != 0;
158
159         boolean hasAnyBindableKey = false;
160         final PreferenceCategory powerCategory =
161                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_POWER);
162         final PreferenceCategory homeCategory =
163                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_HOME);
164         final PreferenceCategory backCategory =
165                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_BACK);
166         final PreferenceCategory menuCategory =
167                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_MENU);
168         final PreferenceCategory assistCategory =
169                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_ASSIST);
170         final PreferenceCategory appSwitchCategory =
171                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_APPSWITCH);
172         final PreferenceCategory volumeCategory =
173                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_VOLUME);
174
175         // Power button ends calls.
176         mPowerEndCall = (SwitchPreference) findPreference(KEY_POWER_END_CALL);
177
178         // Home button answers calls.
179         mHomeAnswerCall = (SwitchPreference) findPreference(KEY_HOME_ANSWER_CALL);
180
181         mHandler = new Handler();
182
183         // Force Navigation bar related options
184         mDisableNavigationKeys = (SwitchPreference) findPreference(DISABLE_NAV_KEYS);
185
186         mNavigationPreferencesCat = (PreferenceCategory) findPreference(CATEGORY_NAVBAR);
187
188         // Navigation bar left
189         mNavigationBarLeftPref = (SwitchPreference) findPreference(KEY_NAVIGATION_BAR_LEFT);
190
191         // Navigation bar recents long press activity needs custom setup
192         mNavigationRecentsLongPressAction =
193                 initRecentsLongPressAction(KEY_NAVIGATION_RECENTS_LONG_PRESS);
194
195         // Only visible on devices that does not have a navigation bar already,
196         // and don't even try unless the existing keys can be disabled
197         boolean needsNavigationBar = false;
198         if (isKeyDisablerSupported()) {
199             try {
200                 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
201                 needsNavigationBar = wm.needsNavigationBar();
202             } catch (RemoteException e) {
203             }
204
205             if (needsNavigationBar) {
206                 prefScreen.removePreference(mDisableNavigationKeys);
207             } else {
208                 // Remove keys that can be provided by the navbar
209                 updateDisableNavkeysOption();
210                 mNavigationPreferencesCat.setEnabled(mDisableNavigationKeys.isChecked());
211                 updateDisableNavkeysCategories(mDisableNavigationKeys.isChecked());
212             }
213         } else {
214             prefScreen.removePreference(mDisableNavigationKeys);
215         }
216
217         if (hasPowerKey) {
218             if (!Utils.isVoiceCapable(getActivity())) {
219                 powerCategory.removePreference(mPowerEndCall);
220                 mPowerEndCall = null;
221             }
222         } else {
223             prefScreen.removePreference(powerCategory);
224         }
225
226         if (hasHomeKey) {
227             if (!showHomeWake) {
228                 homeCategory.removePreference(findPreference(Settings.System.HOME_WAKE_SCREEN));
229             }
230
231             if (!Utils.isVoiceCapable(getActivity())) {
232                 homeCategory.removePreference(mHomeAnswerCall);
233                 mHomeAnswerCall = null;
234             }
235
236             int defaultLongPressAction = res.getInteger(
237                     com.android.internal.R.integer.config_longPressOnHomeBehavior);
238             if (defaultLongPressAction < ACTION_NOTHING ||
239                     defaultLongPressAction > ACTION_LAST_APP) {
240                 defaultLongPressAction = ACTION_NOTHING;
241             }
242
243             int defaultDoubleTapAction = res.getInteger(
244                     com.android.internal.R.integer.config_doubleTapOnHomeBehavior);
245             if (defaultDoubleTapAction < ACTION_NOTHING ||
246                     defaultDoubleTapAction > ACTION_LAST_APP) {
247                 defaultDoubleTapAction = ACTION_NOTHING;
248             }
249
250             int longPressAction = Settings.System.getInt(resolver,
251                     Settings.System.KEY_HOME_LONG_PRESS_ACTION,
252                     defaultLongPressAction);
253             mHomeLongPressAction = initActionList(KEY_HOME_LONG_PRESS, longPressAction);
254
255             int doubleTapAction = Settings.System.getInt(resolver,
256                     Settings.System.KEY_HOME_DOUBLE_TAP_ACTION,
257                     defaultDoubleTapAction);
258             mHomeDoubleTapAction = initActionList(KEY_HOME_DOUBLE_TAP, doubleTapAction);
259
260             hasAnyBindableKey = true;
261         } else {
262             prefScreen.removePreference(homeCategory);
263         }
264
265         if (hasBackKey) {
266             if (!showBackWake) {
267                 backCategory.removePreference(findPreference(Settings.System.BACK_WAKE_SCREEN));
268                 prefScreen.removePreference(backCategory);
269             }
270         } else {
271             prefScreen.removePreference(backCategory);
272         }
273
274         if (hasMenuKey) {
275             if (!showMenuWake) {
276                 menuCategory.removePreference(findPreference(Settings.System.MENU_WAKE_SCREEN));
277             }
278
279             int pressAction = Settings.System.getInt(resolver,
280                     Settings.System.KEY_MENU_ACTION, ACTION_MENU);
281             mMenuPressAction = initActionList(KEY_MENU_PRESS, pressAction);
282
283             int longPressAction = Settings.System.getInt(resolver,
284                         Settings.System.KEY_MENU_LONG_PRESS_ACTION,
285                         hasAssistKey ? ACTION_NOTHING : ACTION_SEARCH);
286             mMenuLongPressAction = initActionList(KEY_MENU_LONG_PRESS, longPressAction);
287
288             hasAnyBindableKey = true;
289         } else {
290             prefScreen.removePreference(menuCategory);
291         }
292
293         if (hasAssistKey) {
294             if (!showAssistWake) {
295                 assistCategory.removePreference(findPreference(Settings.System.ASSIST_WAKE_SCREEN));
296             }
297
298             int pressAction = Settings.System.getInt(resolver,
299                     Settings.System.KEY_ASSIST_ACTION, ACTION_SEARCH);
300             mAssistPressAction = initActionList(KEY_ASSIST_PRESS, pressAction);
301
302             int longPressAction = Settings.System.getInt(resolver,
303                     Settings.System.KEY_ASSIST_LONG_PRESS_ACTION, ACTION_VOICE_SEARCH);
304             mAssistLongPressAction = initActionList(KEY_ASSIST_LONG_PRESS, longPressAction);
305
306             hasAnyBindableKey = true;
307         } else {
308             prefScreen.removePreference(assistCategory);
309         }
310
311         if (hasAppSwitchKey) {
312             if (!showAppSwitchWake) {
313                 appSwitchCategory.removePreference(findPreference(
314                         Settings.System.APP_SWITCH_WAKE_SCREEN));
315             }
316
317             int pressAction = Settings.System.getInt(resolver,
318                     Settings.System.KEY_APP_SWITCH_ACTION, ACTION_APP_SWITCH);
319             mAppSwitchPressAction = initActionList(KEY_APP_SWITCH_PRESS, pressAction);
320
321             int longPressAction = Settings.System.getInt(resolver,
322                     Settings.System.KEY_APP_SWITCH_LONG_PRESS_ACTION, ACTION_NOTHING);
323             mAppSwitchLongPressAction = initActionList(KEY_APP_SWITCH_LONG_PRESS, longPressAction);
324
325             hasAnyBindableKey = true;
326         } else {
327             prefScreen.removePreference(appSwitchCategory);
328         }
329
330         if (Utils.hasVolumeRocker(getActivity())) {
331             if (!showVolumeWake) {
332                 volumeCategory.removePreference(findPreference(Settings.System.VOLUME_WAKE_SCREEN));
333             }
334
335             int cursorControlAction = Settings.System.getInt(resolver,
336                     Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0);
337             mVolumeKeyCursorControl = initActionList(KEY_VOLUME_KEY_CURSOR_CONTROL,
338                     cursorControlAction);
339
340             int swapVolumeKeys = Settings.System.getInt(getContentResolver(),
341                     Settings.System.SWAP_VOLUME_KEYS_ON_ROTATION, 0);
342             mSwapVolumeButtons = (SwitchPreference)
343                     prefScreen.findPreference(KEY_SWAP_VOLUME_BUTTONS);
344             mSwapVolumeButtons.setChecked(swapVolumeKeys > 0);
345         } else {
346             prefScreen.removePreference(volumeCategory);
347         }
348
349         try {
350             // Only show the navigation bar category on devices that have a navigation bar
351             // unless we are forcing it via development settings
352             boolean forceNavbar = android.provider.Settings.System.getInt(getContentResolver(),
353                     android.provider.Settings.System.DEV_FORCE_SHOW_NAVBAR, 0) == 1;
354             boolean hasNavBar = WindowManagerGlobal.getWindowManagerService().hasNavigationBar()
355                     || forceNavbar;
356
357             if (!Utils.isPhone(getActivity())) {
358                 mNavigationPreferencesCat.removePreference(mNavigationBarLeftPref);
359             }
360
361             if ((!hasNavBar && (needsNavigationBar || !isKeyDisablerSupported())) ||
362                 (mNavigationPreferencesCat.getPreferenceCount() == 0)
363             ) {
364                 // Hide navigation bar category
365                 prefScreen.removePreference(mNavigationPreferencesCat);
366             }
367         } catch (RemoteException e) {
368             Log.e(TAG, "Error getting navigation bar status");
369         }
370
371         final ButtonBacklightBrightness backlight =
372                 (ButtonBacklightBrightness) findPreference(KEY_BUTTON_BACKLIGHT);
373         if (!backlight.isButtonSupported() && !backlight.isKeyboardSupported()) {
374             prefScreen.removePreference(backlight);
375         }
376
377         Utils.updatePreferenceToSpecificActivityFromMetaDataOrRemove(getActivity(),
378                 getPreferenceScreen(), KEY_BLUETOOTH_INPUT_SETTINGS);
379     }
380
381     @Override
382     public void onResume() {
383         super.onResume();
384
385         // Power button ends calls.
386         if (mPowerEndCall != null) {
387             final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
388                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
389                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
390             final boolean powerButtonEndsCall =
391                     (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
392             mPowerEndCall.setChecked(powerButtonEndsCall);
393         }
394
395         // Home button answers calls.
396         if (mHomeAnswerCall != null) {
397             final int incallHomeBehavior = Settings.Secure.getInt(getContentResolver(),
398                     Settings.Secure.RING_HOME_BUTTON_BEHAVIOR,
399                     Settings.Secure.RING_HOME_BUTTON_BEHAVIOR_DEFAULT);
400             final boolean homeButtonAnswersCall =
401                 (incallHomeBehavior == Settings.Secure.RING_HOME_BUTTON_BEHAVIOR_ANSWER);
402             mHomeAnswerCall.setChecked(homeButtonAnswersCall);
403         }
404
405     }
406
407     private ListPreference initActionList(String key, int value) {
408         ListPreference list = (ListPreference) getPreferenceScreen().findPreference(key);
409         list.setValue(Integer.toString(value));
410         list.setSummary(list.getEntry());
411         list.setOnPreferenceChangeListener(this);
412         return list;
413     }
414
415     private ListPreference initRecentsLongPressAction(String key) {
416         ListPreference list = (ListPreference) getPreferenceScreen().findPreference(key);
417         list.setOnPreferenceChangeListener(this);
418
419         // Read the componentName from Settings.Secure, this is the user's prefered setting
420         String componentString = Settings.Secure.getString(getContentResolver(),
421                 Settings.Secure.RECENTS_LONG_PRESS_ACTIVITY);
422         ComponentName targetComponent = null;
423         if (componentString == null) {
424             list.setSummary(getString(R.string.hardware_keys_action_last_app));
425         } else {
426             targetComponent = ComponentName.unflattenFromString(componentString);
427         }
428
429         // Dyanamically generate the list array,
430         // query PackageManager for all Activites that are registered for ACTION_RECENTS_LONG_PRESS
431         PackageManager pm = getPackageManager();
432         Intent intent = new Intent(Intent.ACTION_RECENTS_LONG_PRESS);
433         List<ResolveInfo> recentsActivities = pm.queryIntentActivities(intent,
434                 PackageManager.MATCH_DEFAULT_ONLY);
435         if (recentsActivities.size() == 0) {
436             // No entries available, disable
437             list.setSummary(getString(R.string.hardware_keys_action_last_app));
438             Settings.Secure.putString(getContentResolver(),
439                     Settings.Secure.RECENTS_LONG_PRESS_ACTIVITY, null);
440             list.setEnabled(false);
441             return list;
442         }
443
444         CharSequence[] entries = new CharSequence[recentsActivities.size() + 1];
445         CharSequence[] values = new CharSequence[recentsActivities.size() + 1];
446         // First entry is always default last app
447         entries[0] = getString(R.string.hardware_keys_action_last_app);
448         values[0] = "";
449         list.setValue(values[0].toString());
450         int i = 1;
451         for (ResolveInfo info : recentsActivities) {
452             try {
453                 // Use pm.getApplicationInfo for the label,
454                 // we cannot rely on ResolveInfo that comes back from queryIntentActivities.
455                 entries[i] = pm.getApplicationInfo(info.activityInfo.packageName, 0).loadLabel(pm);
456             } catch (PackageManager.NameNotFoundException e) {
457                 Log.e(TAG, "Error package not found: " + info.activityInfo.packageName, e);
458                 // Fallback to package name
459                 entries[i] = info.activityInfo.packageName;
460             }
461
462             // Set the value to the ComponentName that will handle this intent
463             ComponentName entryComponent = new ComponentName(info.activityInfo.packageName,
464                     info.activityInfo.name);
465             values[i] = entryComponent.flattenToString();
466             if (targetComponent != null) {
467                 if (entryComponent.equals(targetComponent)) {
468                     // Update the selected value and the preference summary
469                     list.setSummary(entries[i]);
470                     list.setValue(values[i].toString());
471                 }
472             }
473             i++;
474         }
475         list.setEntries(entries);
476         list.setEntryValues(values);
477         return list;
478     }
479
480     private void handleActionListChange(ListPreference pref, Object newValue, String setting) {
481         String value = (String) newValue;
482         int index = pref.findIndexOfValue(value);
483         pref.setSummary(pref.getEntries()[index]);
484         Settings.System.putInt(getContentResolver(), setting, Integer.valueOf(value));
485     }
486
487     @Override
488     protected int getMetricsCategory() {
489         return MetricsLogger.DONT_TRACK_ME_BRO;
490     }
491
492     @Override
493     public boolean onPreferenceChange(Preference preference, Object newValue) {
494         if (preference == mHomeLongPressAction) {
495             handleActionListChange(mHomeLongPressAction, newValue,
496                     Settings.System.KEY_HOME_LONG_PRESS_ACTION);
497             return true;
498         } else if (preference == mHomeDoubleTapAction) {
499             handleActionListChange(mHomeDoubleTapAction, newValue,
500                     Settings.System.KEY_HOME_DOUBLE_TAP_ACTION);
501             return true;
502         } else if (preference == mMenuPressAction) {
503             handleActionListChange(mMenuPressAction, newValue,
504                     Settings.System.KEY_MENU_ACTION);
505             return true;
506         } else if (preference == mMenuLongPressAction) {
507             handleActionListChange(mMenuLongPressAction, newValue,
508                     Settings.System.KEY_MENU_LONG_PRESS_ACTION);
509             return true;
510         } else if (preference == mAssistPressAction) {
511             handleActionListChange(mAssistPressAction, newValue,
512                     Settings.System.KEY_ASSIST_ACTION);
513             return true;
514         } else if (preference == mAssistLongPressAction) {
515             handleActionListChange(mAssistLongPressAction, newValue,
516                     Settings.System.KEY_ASSIST_LONG_PRESS_ACTION);
517             return true;
518         } else if (preference == mAppSwitchPressAction) {
519             handleActionListChange(mAppSwitchPressAction, newValue,
520                     Settings.System.KEY_APP_SWITCH_ACTION);
521             return true;
522         } else if (preference == mAppSwitchLongPressAction) {
523             handleActionListChange(mAppSwitchLongPressAction, newValue,
524                     Settings.System.KEY_APP_SWITCH_LONG_PRESS_ACTION);
525             return true;
526         } else if (preference == mVolumeKeyCursorControl) {
527             handleActionListChange(mVolumeKeyCursorControl, newValue,
528                     Settings.System.VOLUME_KEY_CURSOR_CONTROL);
529             return true;
530         } else if (preference == mNavigationRecentsLongPressAction) {
531             // RecentsLongPressAction is handled differently because it intentionally uses
532             // Settings.System
533             String putString = (String) newValue;
534             int index = mNavigationRecentsLongPressAction.findIndexOfValue(putString);
535             CharSequence summary = mNavigationRecentsLongPressAction.getEntries()[index];
536             // Update the summary
537             mNavigationRecentsLongPressAction.setSummary(summary);
538             if (putString.length() == 0) {
539                 putString = null;
540             }
541             Settings.Secure.putString(getContentResolver(),
542                     Settings.Secure.RECENTS_LONG_PRESS_ACTIVITY, putString);
543             return true;
544         }
545         return false;
546     }
547
548     private static void writeDisableNavkeysOption(Context context, boolean enabled) {
549         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
550         final int defaultBrightness = context.getResources().getInteger(
551                 com.android.internal.R.integer.config_buttonBrightnessSettingDefault);
552
553         Settings.System.putInt(context.getContentResolver(),
554                 Settings.System.DEV_FORCE_SHOW_NAVBAR, enabled ? 1 : 0);
555         KeyDisabler.setActive(enabled);
556
557         /* Save/restore button timeouts to disable them in softkey mode */
558         Editor editor = prefs.edit();
559
560         if (enabled) {
561             int currentBrightness = Settings.System.getInt(context.getContentResolver(),
562                     Settings.System.BUTTON_BRIGHTNESS, defaultBrightness);
563             if (!prefs.contains("pre_navbar_button_backlight")) {
564                 editor.putInt("pre_navbar_button_backlight", currentBrightness);
565             }
566             Settings.System.putInt(context.getContentResolver(),
567                     Settings.System.BUTTON_BRIGHTNESS, 0);
568         } else {
569             int oldBright = prefs.getInt("pre_navbar_button_backlight", -1);
570             if (oldBright != -1) {
571                 Settings.System.putInt(context.getContentResolver(),
572                         Settings.System.BUTTON_BRIGHTNESS, oldBright);
573                 editor.remove("pre_navbar_button_backlight");
574             }
575         }
576         editor.commit();
577     }
578
579     private void updateDisableNavkeysOption() {
580         boolean enabled = Settings.System.getInt(getActivity().getContentResolver(),
581                 Settings.System.DEV_FORCE_SHOW_NAVBAR, 0) != 0;
582
583         mDisableNavigationKeys.setChecked(enabled);
584     }
585
586     private void updateDisableNavkeysCategories(boolean navbarEnabled) {
587         final PreferenceScreen prefScreen = getPreferenceScreen();
588
589         /* Disable hw-key options if they're disabled */
590         final PreferenceCategory homeCategory =
591                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_HOME);
592         final PreferenceCategory backCategory =
593                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_BACK);
594         final PreferenceCategory menuCategory =
595                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_MENU);
596         final PreferenceCategory assistCategory =
597                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_ASSIST);
598         final PreferenceCategory appSwitchCategory =
599                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_APPSWITCH);
600         final ButtonBacklightBrightness backlight =
601                 (ButtonBacklightBrightness) prefScreen.findPreference(KEY_BUTTON_BACKLIGHT);
602
603         /* Toggle backlight control depending on navbar state, force it to
604            off if enabling */
605         if (backlight != null) {
606             backlight.setEnabled(!navbarEnabled);
607             backlight.updateSummary();
608         }
609
610         /* Toggle hardkey control availability depending on navbar state */
611         if (homeCategory != null) {
612             homeCategory.setEnabled(!navbarEnabled);
613         }
614         if (backCategory != null) {
615             backCategory.setEnabled(!navbarEnabled);
616         }
617         if (menuCategory != null) {
618             menuCategory.setEnabled(!navbarEnabled);
619         }
620         if (assistCategory != null) {
621             assistCategory.setEnabled(!navbarEnabled);
622         }
623         if (appSwitchCategory != null) {
624             appSwitchCategory.setEnabled(!navbarEnabled);
625         }
626     }
627
628     public static void restoreKeyDisabler(Context context) {
629         if (!isKeyDisablerSupported()) {
630             return;
631         }
632
633         writeDisableNavkeysOption(context, Settings.System.getInt(context.getContentResolver(),
634                 Settings.System.DEV_FORCE_SHOW_NAVBAR, 0) != 0);
635     }
636
637
638     @Override
639     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
640         if (preference == mSwapVolumeButtons) {
641             int value = mSwapVolumeButtons.isChecked()
642                     ? (Utils.isTablet(getActivity()) ? 2 : 1) : 0;
643             Settings.System.putInt(getActivity().getContentResolver(),
644                     Settings.System.SWAP_VOLUME_KEYS_ON_ROTATION, value);
645         } else if (preference == mDisableNavigationKeys) {
646             mDisableNavigationKeys.setEnabled(false);
647             mNavigationPreferencesCat.setEnabled(false);
648             writeDisableNavkeysOption(getActivity(), mDisableNavigationKeys.isChecked());
649             updateDisableNavkeysOption();
650             updateDisableNavkeysCategories(true);
651             mHandler.postDelayed(new Runnable() {
652                 @Override
653                 public void run() {
654                     mDisableNavigationKeys.setEnabled(true);
655                     mNavigationPreferencesCat.setEnabled(mDisableNavigationKeys.isChecked());
656                     updateDisableNavkeysCategories(mDisableNavigationKeys.isChecked());
657                 }
658             }, 1000);
659         } else if (preference == mPowerEndCall) {
660             handleTogglePowerButtonEndsCallPreferenceClick();
661             return true;
662         } else if (preference == mHomeAnswerCall) {
663             handleToggleHomeButtonAnswersCallPreferenceClick();
664             return true;
665         }
666
667         return super.onPreferenceTreeClick(preferenceScreen, preference);
668     }
669
670     private static boolean isKeyDisablerSupported() {
671         try {
672             return KeyDisabler.isSupported();
673         } catch (NoClassDefFoundError e) {
674             // Hardware abstraction framework not installed
675             return false;
676         }
677     }
678
679     private void handleTogglePowerButtonEndsCallPreferenceClick() {
680         Settings.Secure.putInt(getContentResolver(),
681                 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, (mPowerEndCall.isChecked()
682                         ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
683                         : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
684     }
685
686     private void handleToggleHomeButtonAnswersCallPreferenceClick() {
687         Settings.Secure.putInt(getContentResolver(),
688                 Settings.Secure.RING_HOME_BUTTON_BEHAVIOR, (mHomeAnswerCall.isChecked()
689                         ? Settings.Secure.RING_HOME_BUTTON_BEHAVIOR_ANSWER
690                         : Settings.Secure.RING_HOME_BUTTON_BEHAVIOR_DO_NOTHING));
691     }
692 }