Add "Power button ends call" accessibility setting.

This is part 3 of the fix for bug 2364220 "Accessibility improvements for
ending calls".

This change adds a checkbox under "Accessibility settings" to control the
new Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR value, which allows the
user to specify that the Power button should hang up while in-call
(instead of just turning off the screen.)  The checkbox is only shown on
devices that actually have a POWER button.

Yeah, it's a little strange having this under Accessibility (since it's not
that obvious *why* this feature is accessibility-related), but there's no
obvious better place.  See discussion in the bug for more info.

Bug: 2364220

Change-Id: I0fd7cf357972519b390575b9c06a4bbe46ff1c9b
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 3606f04..7beab15 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -25,4 +25,13 @@
     <PreferenceCategory android:key="accessibility_services_category"
             android:title="@string/accessibility_services_category" />
 
+    <PreferenceCategory android:key="power_button_category"
+            android:title="@string/accessibility_power_button_category">
+        <CheckBoxPreference
+                android:key="power_button_ends_call"
+                android:title="@string/accessibility_power_button_ends_call"
+                android:summary="@string/accessibility_power_button_ends_call_summary"
+                android:persistent="false" />
+    </PreferenceCategory>
+
 </PreferenceScreen>
diff --git a/src/com/android/settings/AccessibilitySettings.java b/src/com/android/settings/AccessibilitySettings.java
index b2debd2..d78d2d8 100644
--- a/src/com/android/settings/AccessibilitySettings.java
+++ b/src/com/android/settings/AccessibilitySettings.java
@@ -30,10 +30,13 @@
 import android.preference.CheckBoxPreference;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
 import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
 import android.view.accessibility.AccessibilityManager;
 
 import java.util.HashSet;
@@ -54,8 +57,17 @@
     private static final String ACCESSIBILITY_SERVICES_CATEGORY =
         "accessibility_services_category";
 
+    private static final String POWER_BUTTON_CATEGORY =
+        "power_button_category";
+
+    private final String POWER_BUTTON_ENDS_CALL_CHECKBOX =
+        "power_button_ends_call";
+
     private CheckBoxPreference mToggleCheckBox;
 
+    private PreferenceCategory mPowerButtonCategory;
+    private CheckBoxPreference mPowerButtonEndsCallCheckBox;
+
     private Map<String, ServiceInfo> mAccessibilityServices =
         new LinkedHashMap<String, ServiceInfo>();
 
@@ -72,6 +84,10 @@
         mToggleCheckBox = (CheckBoxPreference) findPreference(
             TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX);
 
+        mPowerButtonCategory = (PreferenceCategory) findPreference(POWER_BUTTON_CATEGORY);
+        mPowerButtonEndsCallCheckBox = (CheckBoxPreference) findPreference(
+            POWER_BUTTON_ENDS_CALL_CHECKBOX);
+
         addAccessibilitServicePreferences();
     }
 
@@ -120,6 +136,22 @@
             // installed and direct them to Market to get TalkBack
             displayNoAppsAlert();
         }
+
+        if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)) {
+            int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
+                    Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
+                    Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
+            // The checkbox is labeled "Power button ends call"; thus the in-call
+            // Power button behavior is INCALL_POWER_BUTTON_BEHAVIOR_HANGUP if
+            // checked, and INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF if unchecked.
+            boolean powerButtonCheckboxEnabled =
+                    (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
+            mPowerButtonEndsCallCheckBox.setChecked(powerButtonCheckboxEnabled);
+            mPowerButtonEndsCallCheckBox.setEnabled(true);
+        } else {
+            // No POWER key on the current device; this entire category is irrelevant.
+            getPreferenceScreen().removePreference(mPowerButtonCategory);
+        }
     }
 
     @Override
@@ -154,6 +186,15 @@
         if (TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX.equals(key)) {
             boolean isChecked = ((CheckBoxPreference) preference).isChecked();
             handleEnableAccessibilityStateChange((CheckBoxPreference) preference);
+        } else if (POWER_BUTTON_ENDS_CALL_CHECKBOX.equals(key)) {
+            boolean isChecked = ((CheckBoxPreference) preference).isChecked();
+            // The checkbox is labeled "Power button ends call"; thus the in-call
+            // Power button behavior is INCALL_POWER_BUTTON_BEHAVIOR_HANGUP if
+            // checked, and INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF if unchecked.
+            Settings.Secure.putInt(getContentResolver(),
+                    Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
+                    (isChecked ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
+                            : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
         } else if (preference instanceof CheckBoxPreference) {
             handleEnableAccessibilityServiceStateChange((CheckBoxPreference) preference);
         }
@@ -290,12 +331,12 @@
      * reader) from Market.
      */
     private void displayNoAppsAlert() {
-        try {

-            PackageManager pm = getPackageManager();

-            ApplicationInfo info = pm.getApplicationInfo("com.android.vending", 0);

+        try {
+            PackageManager pm = getPackageManager();
+            ApplicationInfo info = pm.getApplicationInfo("com.android.vending", 0);
         } catch (NameNotFoundException e) {
-            // This is a no-op if the user does not have Android Market

-            return;

+            // This is a no-op if the user does not have Android Market
+            return;
         }
         AlertDialog.Builder noAppsAlert = new AlertDialog.Builder(this);
         noAppsAlert.setTitle(R.string.accessibility_service_no_apps_title);
@@ -305,7 +346,8 @@
             new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int which) {
                     String screenreaderMarketLink =
-                        SystemProperties.get("ro.screenreader.market", DEFAULT_SCREENREADER_MARKET_LINK);
+                        SystemProperties.get("ro.screenreader.market",
+                                DEFAULT_SCREENREADER_MARKET_LINK);
                     Uri marketUri = Uri.parse(screenreaderMarketLink);
                     Intent marketIntent = new Intent(Intent.ACTION_VIEW, marketUri);
                     startActivity(marketIntent);