Cherish:Add some button settings

Hardware key: Customization support[2/2]

Volume Rocker Wake [2/2]

Volume key cursor control (2/2)

Co-authored-by: jhenrique09 <jhsv09@gmail.com>
Co-authored-by: Max <xyyx@mail.ru>
Co-authored-by: bigrushdog <randall.rushing@gmail.com>
Signed-off-by: Hưng Phan <phandinhhungvp2001@gmail.com>
This commit is contained in:
Hưng Phan
2022-09-05 23:10:11 +07:00
parent 6689c20b18
commit 7c3bcc8509
13 changed files with 1671 additions and 83 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="?android:attr/colorAccent" />
</shape>

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2006 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Layout for a Preference in a PreferenceActivity. The
Preference is able to place a specific widget for its particular
type in the "widget_frame" layout. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/widget_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/selectableItemBackground">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dip"
android:padding="2dp"
android:maxWidth="36dip"
android:maxHeight="36dip"
android:adjustViewBounds="true"
android:layout_gravity="center" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dip"
android:layout_marginEnd="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
<TextView android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
android:textColor="?android:attr/textColorPrimary"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
android:layout_alignStart="@android:id/title"
android:textAppearance="@android:style/TextAppearance.Material.Body1"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="2" />
</RelativeLayout>
</LinearLayout>

View File

@@ -186,5 +186,51 @@
<item>0</item> <item>0</item>
<item>1</item> <item>1</item>
</string-array> </string-array>
<!--- Volume key cursor control -->
<string-array name="volume_key_cursor_control_entries">
<item>@string/volume_key_cursor_control_off</item>
<item>@string/volume_key_cursor_control_on</item>
<item>@string/volume_key_cursor_control_on_reverse</item>
</string-array>
<string-array name="volume_key_cursor_control_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
<!-- HW Keys customization -->
<string-array name="action_dialog_entries">
<item>@string/action_entry_default_action</item>
<item>@string/action_entry_custom_action</item>
<item>@string/action_entry_select_app</item>
</string-array>
<string-array name="action_dialog_values" translatable="false">
<item>@string/action_value_default_action</item>
<item>@string/action_value_custom_action</item>
<item>@string/action_value_select_app</item>
</string-array>
<string-array name="action_dialog_no_default_entries">
<item>@string/action_entry_custom_action</item>
<item>@string/action_entry_select_app</item>
</string-array>
<string-array name="action_dialog_no_default_values" translatable="false">
<item>@string/action_value_custom_action</item>
<item>@string/action_value_select_app</item>
</string-array>
<!-- Volume step options. -->
<string-array name="volume_steps_entries" translatable="false">
<item>60</item>
<item>45</item>
<item>30</item>
<item>15</item>
<item>7</item>
<item>5</item>
</string-array>
</resources> </resources>

View File

@@ -113,9 +113,6 @@
<string name="notification_light_settings">Notifications light</string> <string name="notification_light_settings">Notifications light</string>
<!-- Volume rocker wake -->
<string name="volume_rocker_wake_title">Volume rocker wake</string>
<string name="search">Search</string> <string name="search">Search</string>
<string name="search_apps">Search apps</string> <string name="search_apps">Search apps</string>
@@ -328,4 +325,119 @@
<!-- Power menu on lockscreen --> <!-- Power menu on lockscreen -->
<string name="power_menu_hide_on_secure_title">Hide power menu on lock screen</string> <string name="power_menu_hide_on_secure_title">Hide power menu on lock screen</string>
<string name="power_menu_hide_on_secure_summary">This will hide the power menu only on a secure lock screen</string> <string name="power_menu_hide_on_secure_summary">This will hide the power menu only on a secure lock screen</string>
<!-- Hide Status bar on lock screen -->
<string name="hide_lockscreen_status_bar_title">Hide status bar</string>
<string name="hide_lockscreen_status_bar_summary">Touch status bar to toggle visibility</string>
<!-- Navigation bar -->
<string name="navigation_bar_category">Navigation bar</string>
<string name="navigation_bar_title">On-screen navigation bar</string>
<string name="navigation_bar_summary">Enable on-screen navigation keys</string>
<string name="navigation_bar_arrow_keys_title">Show arrow keys while typing</string>
<string name="navigation_bar_arrow_keys_summary">Display left and right cursor buttons in navigation bar while typing</string>
<string name="navigation_bar_compact_layout_title">Compact layout</string>
<string name="navigation_bar_compact_layout_summary">Use a compact layout in the navigation bar</string>
<string name="system_navigation_summary">Choose which system navigation style to use</string>
<!-- Volume rocker wake -->
<string name="volume_rocker_wake_title">Volume rocker wake</string>
<string name="volume_rocker_wake_summary">Pressing the volume keys will wake your device</string>
<string name="volume_category">Volume rocker</string>
<!-- Volume Steps Fragment -->
<string name="volume_steps_fragment_title">Volume steps</string>
<string name="volume_steps_summary">Customize volume steps</string>
<string name="volume_steps_alarm_title">Volume steps: Alarm</string>
<string name="volume_steps_dtmf_title">Volume steps: DTMF</string>
<string name="volume_steps_music_title">Volume steps: Media</string>
<string name="volume_steps_notification_title">Volume steps: Notification</string>
<string name="volume_steps_ring_title">Volume steps: Ringer</string>
<string name="volume_steps_system_title">Volume steps: System</string>
<string name="volume_steps_voice_call_title">Volume steps: Voice Call</string>
<string name="volume_steps_reset">Reset</string>
<!-- Buttons - Enable navbar -->
<string name="disable_navkeys_title">Enable on-screen nav bar</string>
<string name="disable_navkeys_summary">Enable on-screen navigation bar and disable hardware buttons</string>
<!-- Buttons - Swap capacitive keys -->
<string name="swap_capacitive_keys_title">Swap capacitive buttons</string>
<string name="swap_capacitive_keys_summary">Swap the order of recents and back buttons</string>
<!-- HW keys -->
<string name="hardware_keys_title">Buttons</string>
<string name="hardware_keys_category">Hardware navigation buttons</string>
<string name="hardware_keys_disable_title">Disable hardware buttons</string>
<string name="hardware_keys_disable_summary">Use the device hardware keys for navigation</string>
<string name="hardware_keys_volume_keys_title">Volume rocker</string>
<!-- Hardware button navigation -->
<string name="action_value_default_action" translatable="false">default</string>
<string name="action_value_select_app" translatable="false">app</string>
<string name="action_value_custom_action" translatable="false">custom</string>
<string name="action_value_back" translatable="false">task_back</string>
<string name="action_value_home" translatable="false">task_home</string>
<string name="action_value_search_assist" translatable="false">task_assist</string>
<string name="action_value_recent_apps" translatable="false">task_recents</string>
<string name="action_value_voice_search" translatable="false">task_voice_search</string>
<string name="action_value_menu" translatable="false">task_menu</string>
<string name="picker_activities">Activities</string>
<string name="select_custom_app_title">Select custom app</string>
<string name="select_custom_activity_title">Select custom activity</string>
<string name="profile_applist_title">Applications</string>
<string name="choose_action_title">Choose action</string>
<string name="action_entry_default_action">Default settings</string>
<string name="action_entry_select_app">Select application</string>
<string name="action_entry_custom_action">Select custom action</string>
<string name="hardware_keys_home_key_title">Home button</string>
<string name="hardware_keys_back_key_title">Back button</string>
<string name="hardware_keys_menu_key_title">Menu button</string>
<string name="hardware_keys_assist_key_title">Search button</string>
<string name="hardware_keys_appswitch_key_title">Recents button</string>
<string name="hardware_keys_camera_key_title">Camera button</string>
<string name="hardware_keys_short_press_title">Short press action</string>
<string name="hardware_keys_double_tap_summary">Set double tap action</string>
<string name="hardware_keys_single_tap_summary">Set single tap action</string>
<string name="hardware_keys_long_press_summary">Set long press action</string>
<string name="hardware_keys_single_tap_title">Single tap action</string>
<string name="hardware_keys_long_press_title">Long press action</string>
<string name="hardware_keys_double_tap_title">Double tap action</string>
<string name="hardware_keys_action_nothing">No action</string>
<string name="hardware_keys_action_menu">Open/close menu</string>
<string name="hardware_keys_action_app_switch">Recent apps switcher</string>
<string name="hardware_keys_action_search">Search assistant</string>
<string name="hardware_keys_action_voice_search">Voice search</string>
<string name="hardware_keys_action_in_app_search">In-app search</string>
<string name="hardware_keys_action_launch_camera">Launch camera</string>
<string name="hardware_keys_action_sleep">Turn screen off</string>
<string name="hardware_keys_action_split_screen">Split screen</string>
<string name="hardware_keys_action_close_app">Kill app</string>
<string name="hardware_keys_action_torch">Flashlight</string>
<string name="hardware_keys_action_screenshot">Screenshot</string>
<string name="hardware_keys_action_volume_panel">Toggle volume panel</string>
<string name="hardware_keys_action_clear_all_notifications">Clear all notifications</string>
<string name="hardware_keys_action_notifications_panel">Toggle notifications panel</string>
<string name="hardware_keys_action_toggle_qs_panel">Toggle QS panel</string>
<string name="hardware_keys_action_ringer_modes">Ringer modes</string>
<string name="hardware_keys_swipe_right_key_title">Swipe right</string>
<string name="hardware_keys_swipe_left_key_title">Swipe left</string>
<string name="hardware_keys_long_tap_key_title">Long tap</string>
<string name="hardware_keys_swipe_tap_title">Swipe action</string>
<string name="hardware_keys_long_tap_title">Long tap action</string>
<string name="button_wake_title">Wake device</string>
<string name="button_wake_summary">Wake device by pressing the button</string>
<string name="camera_sleep_on_release_title">Screen peek</string>
<string name="camera_sleep_on_release_summary">A half press will keep the screen on only while the button is held down</string>
<string name="camera_launch_title">Launch camera</string>
<string name="camera_launch_summary">A longpress and release will launch camera</string>
<string name="cursor_section_header">Cursor</string>
<string name="volume_key_cursor_control_title">Keyboard cursor control</string>
<string name="volume_key_cursor_control_off">Disabled</string>
<string name="volume_key_cursor_control_on">Volume Up/Down - Cursor Left/Right</string>
<string name="volume_key_cursor_control_on_reverse">Volume Up/Down - Cursor Right/Left</string>
<string name="swap_volume_buttons_title">Reorient</string>
<string name="swap_volume_buttons_summary">Swap volume buttons when the screen is rotated</string>
<string name="volume_panel_on_left_title">Show volume panel on left</string>
<string name="volume_panel_on_left_summary">Display volume panel on the left side of the screen</string>
</resources> </resources>

View File

@@ -18,10 +18,28 @@
android:title="@string/button_title" android:title="@string/button_title"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"> xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<PreferenceCategory <!-- SwitchPreference
android:key="navbar_visibility"
android:title="@string/navigation_bar_title"
android:summary="@string/navigation_bar_summary" />-->
<PreferenceCategory
android:key="navigation_keys" android:key="navigation_keys"
android:title="@string/navigation_bar_category"> android:title="@string/navigation_bar_category">
<Preference
android:key="gesture_system_navigation_input_summary"
android:title="@string/system_navigation_title"
android:fragment="com.android.settings.gestures.SystemNavigationGestureSettings"
settings:controller="com.android.settings.gestures.SystemNavigationPreferenceController"
settings:keywords="@string/keywords_system_navigation" />
<!-- com.cherish.settings.preferences.SystemSettingSwitchPreference
android:key="navigation_bar_menu_arrow_keys"
android:title="@string/navigation_bar_arrow_keys_title"
android:summary="@string/navigation_bar_arrow_keys_summary"
android:defaultValue="false" />-->
<com.cherish.settings.preferences.SystemSettingSwitchPreference <com.cherish.settings.preferences.SystemSettingSwitchPreference
android:key="navigation_bar_compact_layout" android:key="navigation_bar_compact_layout"
android:title="@string/navigation_bar_compact_layout_title" android:title="@string/navigation_bar_compact_layout_title"
@@ -36,5 +54,210 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory
android:key="volume_category"
android:title="@string/volume_category">
<com.cherish.settings.preferences.SecureSettingSwitchPreference
android:key="volume_panel_on_left"
android:title="@string/volume_panel_on_left_title"
android:summary="@string/volume_panel_on_left_summary"
android:defaultValue="false" />
<Preference
android:key="vol_steps"
android:title="@string/volume_steps_fragment_title"
android:summary="@string/volume_steps_summary"
android:fragment="com.cherish.settings.fragments.VolumeRockerSettings" />
<com.cherish.settings.preferences.SystemSettingSwitchPreference
android:key="volume_rocker_wake"
android:summary="@string/volume_rocker_wake_summary"
android:title="@string/volume_rocker_wake_title"
android:defaultValue="false" />
<com.cherish.settings.preferences.SystemSettingListPreference
android:key="volume_key_cursor_control"
android:summary="%s"
android:title="@string/volume_key_cursor_control_title"
android:dialogTitle="@string/volume_key_cursor_control_title"
android:entries="@array/volume_key_cursor_control_entries"
android:entryValues="@array/volume_key_cursor_control_values"
android:defaultValue="0" />
</PreferenceCategory>
<PreferenceCategory
android:key="hardware_keys"
android:title="@string/hardware_keys_category">
<SwitchPreference
android:key="hardware_keys_disable"
android:title="@string/hardware_keys_disable_title" />
<com.cherish.settings.preferences.SecureSettingSwitchPreference
android:key="swap_capacitive_keys"
android:title="@string/swap_capacitive_keys_title"
android:summary="@string/swap_capacitive_keys_summary"
android:defaultValue="false" />
</PreferenceCategory>
<!-- PreferenceCategory
android:key="button_backlight_options_category"
android:title="@string/button_backlight_options_category">
<com.cherish.settings.preferences.SystemSettingSwitchPreference
android:key="button_backlight_enable"
android:title="@string/button_backlight_enable_title"
android:defaultValue="true" />
<com.cherish.settings.preferences.SystemSettingSwitchPreference
android:key="custom_button_use_screen_brightness"
android:title="@string/button_link_brightness"
android:summary="@string/button_link_brightness_summary"
android:defaultValue="false"
android:dependency="button_backlight_enable"
android:disableDependentsState="true" />
<com.cherish.settings.preferences.CustomSeekBarPreference
android:key="button_manual_brightness_new"
android:title="@string/button_manual_brightness"
android:max="255"
settings:min="1"
android:persistent="false"
android:dependency="custom_button_use_screen_brightness" />
<com.cherish.settings.preferences.CustomSeekBarPreference
android:key="button_timeout"
android:title="@string/button_timeout_title"
android:max="30"
settings:min="0"
android:persistent="false"
android:dependency="button_backlight_enable" />
<com.cherish.settings.preferences.SystemSettingSwitchPreference
android:key="button_backlight_on_touch_only"
android:title="@string/button_backlight_on_touch_only_title"
android:summary="@string/button_backlight_on_touch_only_summary"
android:defaultValue="false"
android:dependency="button_backlight_enable" />
</PreferenceCategory>-->
<PreferenceCategory
android:key="back_key"
android:title="@string/hardware_keys_back_key_title">
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_back_single_tap"
android:summary="@string/hardware_keys_single_tap_summary"
android:title="@string/hardware_keys_single_tap_title">
</com.cherish.settings.preferences.ActionPreference>
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_back_long_press"
android:summary="@string/hardware_keys_long_press_summary"
android:title="@string/hardware_keys_long_press_title">
</com.cherish.settings.preferences.ActionPreference>
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_back_double_tap"
android:summary="@string/hardware_keys_double_tap_summary"
android:title="@string/hardware_keys_double_tap_title">
</com.cherish.settings.preferences.ActionPreference>
</PreferenceCategory>
<PreferenceCategory
android:key="home_key"
android:title="@string/hardware_keys_home_key_title">
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_home_single_tap"
android:summary="@string/hardware_keys_single_tap_summary"
android:title="@string/hardware_keys_single_tap_title">
</com.cherish.settings.preferences.ActionPreference>
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_home_long_press"
android:summary="@string/hardware_keys_long_press_summary"
android:title="@string/hardware_keys_long_press_title">
</com.cherish.settings.preferences.ActionPreference>
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_home_double_tap"
android:summary="@string/hardware_keys_double_tap_summary"
android:title="@string/hardware_keys_double_tap_title">
</com.cherish.settings.preferences.ActionPreference>
</PreferenceCategory>
<PreferenceCategory
android:key="app_switch_key"
android:title="@string/hardware_keys_appswitch_key_title">
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_overview_single_tap"
android:summary="@string/hardware_keys_single_tap_summary"
android:title="@string/hardware_keys_single_tap_title">
</com.cherish.settings.preferences.ActionPreference>
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_overview_long_press"
android:summary="@string/hardware_keys_long_press_summary"
android:title="@string/hardware_keys_long_press_title">
</com.cherish.settings.preferences.ActionPreference>
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_overview_double_tap"
android:summary="@string/hardware_keys_double_tap_summary"
android:title="@string/hardware_keys_double_tap_title">
</com.cherish.settings.preferences.ActionPreference>
</PreferenceCategory>
<PreferenceCategory
android:key="menu_key"
android:title="@string/hardware_keys_menu_key_title">
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_menu_single_tap"
android:summary="@string/hardware_keys_single_tap_summary"
android:title="@string/hardware_keys_single_tap_title">
</com.cherish.settings.preferences.ActionPreference>
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_menu_long_press"
android:summary="@string/hardware_keys_long_press_summary"
android:title="@string/hardware_keys_long_press_title">
</com.cherish.settings.preferences.ActionPreference>
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_menu_double_tap"
android:summary="@string/hardware_keys_double_tap_summary"
android:title="@string/hardware_keys_double_tap_title">
</com.cherish.settings.preferences.ActionPreference>
</PreferenceCategory>
<PreferenceCategory
android:key="assist_key"
android:title="@string/hardware_keys_assist_key_title">
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_assist_single_tap"
android:summary="@string/hardware_keys_single_tap_summary"
android:title="@string/hardware_keys_single_tap_title">
</com.cherish.settings.preferences.ActionPreference>
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_assist_long_press"
android:summary="@string/hardware_keys_long_press_summary"
android:title="@string/hardware_keys_long_press_title">
</com.cherish.settings.preferences.ActionPreference>
<com.cherish.settings.preferences.ActionPreference
android:key="hwkeys_button_assist_double_tap"
android:summary="@string/hardware_keys_double_tap_summary"
android:title="@string/hardware_keys_double_tap_title">
</com.cherish.settings.preferences.ActionPreference>
</PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@@ -15,6 +15,49 @@
--> -->
<PreferenceScreen <PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"> xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/volume_steps_fragment_title">
<ListPreference
android:key="volume_steps_alarm"
android:title="@string/volume_steps_alarm_title"
android:entries="@array/volume_steps_entries"
android:entryValues="@array/volume_steps_entries" />
<ListPreference
android:key="volume_steps_dtmf"
android:title="@string/volume_steps_dtmf_title"
android:entries="@array/volume_steps_entries"
android:entryValues="@array/volume_steps_entries" />
<ListPreference
android:key="volume_steps_music"
android:title="@string/volume_steps_music_title"
android:entries="@array/volume_steps_entries"
android:entryValues="@array/volume_steps_entries" />
<ListPreference
android:key="volume_steps_notification"
android:title="@string/volume_steps_notification_title"
android:entries="@array/volume_steps_entries"
android:entryValues="@array/volume_steps_entries" />
<ListPreference
android:key="volume_steps_ring"
android:title="@string/volume_steps_ring_title"
android:entries="@array/volume_steps_entries"
android:entryValues="@array/volume_steps_entries" />
<ListPreference
android:key="volume_steps_system"
android:title="@string/volume_steps_system_title"
android:entries="@array/volume_steps_entries"
android:entryValues="@array/volume_steps_entries" />
<ListPreference
android:key="volume_steps_voice_call"
android:title="@string/volume_steps_voice_call_title"
android:entries="@array/volume_steps_entries"
android:entryValues="@array/volume_steps_entries" />
</PreferenceScreen> </PreferenceScreen>

View File

@@ -18,44 +18,76 @@
package com.cherish.settings.fragments; package com.cherish.settings.fragments;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.res.Resources;
import android.content.Context; import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.SystemProperties;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.Vibrator; import android.provider.Settings;
import androidx.preference.PreferenceCategory; import android.view.View;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.preference.Preference.OnPreferenceChangeListener; import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.SwitchPreference; import androidx.preference.SwitchPreference;
import android.provider.Settings;
import com.android.internal.lineage.hardware.LineageHardwareManager;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.cherish.CherishUtils;
import com.android.internal.util.hwkeys.ActionConstants;
import com.android.internal.util.hwkeys.ActionUtils;
import com.android.settings.R; import com.android.settings.R;
import com.cherish.settings.preferences.SystemSettingSwitchPreference;
import com.cherish.settings.preferences.SecureSettingSwitchPreference;
import com.android.internal.logging.nano.MetricsProto;
import com.cherish.settings.preferences.CustomSeekBarPreference;
import com.android.settings.SettingsPreferenceFragment; import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexable;
import android.provider.SearchIndexableResource;
import com.cherish.settings.preferences.ActionFragment;
import com.cherish.settings.preferences.SecureSettingSwitchPreference;
import com.cherish.settings.preferences.SystemSettingSwitchPreference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class ButtonSettings extends SettingsPreferenceFragment implements
Preference.OnPreferenceChangeListener {
private static final String KEY_NAVBAR_INVERSE = "navigation_bar_inverse";
private static final String KEY_NAVIGATION_COMPACT_LAYOUT = "navigation_bar_compact_layout";
private SystemSettingSwitchPreference mNavbarInverse;
private SystemSettingSwitchPreference mNavigationCompactLayout;
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class ButtonSettings extends ActionFragment implements
Preference.OnPreferenceChangeListener {
private static final String HWKEY_DISABLE = "hardware_keys_disable";
private static final String KEY_NAVBAR_INVERSE = "navigation_bar_inverse";
private static final String KEY_NAVIGATION_COMPACT_LAYOUT = "navigation_bar_compact_layout";
private static final String KEY_SWAP_CAPACITIVE_KEYS = "swap_capacitive_keys";
// category keys
private static final String CATEGORY_HWKEY = "hardware_keys";
private static final String CATEGORY_BACK = "back_key";
private static final String CATEGORY_HOME = "home_key";
private static final String CATEGORY_MENU = "menu_key";
private static final String CATEGORY_ASSIST = "assist_key";
private static final String CATEGORY_APPSWITCH = "app_switch_key";
private static final String CATEGORY_VOLUME = "volume_keys";
private static final String CATEGORY_POWER = "power_key";
// Masks for checking presence of hardware keys.
// Must match values in frameworks/base/core/res/res/values/config.xml
public static final int KEY_MASK_HOME = 0x01;
public static final int KEY_MASK_BACK = 0x02;
public static final int KEY_MASK_MENU = 0x04;
public static final int KEY_MASK_ASSIST = 0x08;
public static final int KEY_MASK_APP_SWITCH = 0x10;
public static final int KEY_MASK_CAMERA = 0x20;
public static final int KEY_MASK_VOLUME = 0x40;
private PreferenceCategory mButtonBackLightCategory;
private PreferenceCategory mHwKeyCategory;
private SecureSettingSwitchPreference mSwapCapacitiveKeys;
private SwitchPreference mHwKeyDisable;
private SystemSettingSwitchPreference mNavbarInverse;
private SystemSettingSwitchPreference mNavigationCompactLayout;
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
@@ -65,47 +97,133 @@ public class ButtonSettings extends SettingsPreferenceFragment implements
final Resources res = getResources(); final Resources res = getResources();
final ContentResolver resolver = getActivity().getContentResolver(); final ContentResolver resolver = getActivity().getContentResolver();
final PreferenceScreen prefScreen = getPreferenceScreen(); final PreferenceScreen prefScreen = getPreferenceScreen();
final boolean isThreeButtonNavbarEnabled = EvolutionUtils.isThemeEnabled("com.android.internal.systemui.navbar.threebutton"); mSwapCapacitiveKeys = findPreference(KEY_SWAP_CAPACITIVE_KEYS);
if (mSwapCapacitiveKeys != null && !isKeySwapperSupported(getActivity())) {
prefScreen.removePreference(mSwapCapacitiveKeys);
mSwapCapacitiveKeys = null;
}
final boolean needsNavbar = ActionUtils.hasNavbarByDefault(getActivity());
mHwKeyCategory = (PreferenceCategory) prefScreen
.findPreference(CATEGORY_HWKEY);
int keysDisabled = 0;
if (!needsNavbar) {
mHwKeyDisable = (SwitchPreference) findPreference(HWKEY_DISABLE);
keysDisabled = Settings.System.getIntForUser(getContentResolver(),
Settings.System.HARDWARE_KEYS_DISABLE, 0,
UserHandle.USER_CURRENT);
mHwKeyDisable.setChecked(keysDisabled != 0);
mHwKeyDisable.setOnPreferenceChangeListener(this);
} else {
prefScreen.removePreference(mHwKeyCategory);
}
// bits for hardware keys present on device
final int deviceKeys = getResources().getInteger(
com.android.internal.R.integer.config_deviceHardwareKeys);
// read bits for present hardware keys
final boolean hasHomeKey = (deviceKeys & KEY_MASK_HOME) != 0;
final boolean hasBackKey = (deviceKeys & KEY_MASK_BACK) != 0;
final boolean hasMenuKey = (deviceKeys & KEY_MASK_MENU) != 0;
final boolean hasAssistKey = (deviceKeys & KEY_MASK_ASSIST) != 0;
final boolean hasAppSwitchKey = (deviceKeys & KEY_MASK_APP_SWITCH) != 0;
// load categories and init/remove preferences based on device
// configuration
final PreferenceCategory backCategory = (PreferenceCategory) prefScreen
.findPreference(CATEGORY_BACK);
final PreferenceCategory homeCategory = (PreferenceCategory) prefScreen
.findPreference(CATEGORY_HOME);
final PreferenceCategory menuCategory = (PreferenceCategory) prefScreen
.findPreference(CATEGORY_MENU);
final PreferenceCategory assistCategory = (PreferenceCategory) prefScreen
.findPreference(CATEGORY_ASSIST);
final PreferenceCategory appSwitchCategory = (PreferenceCategory) prefScreen
.findPreference(CATEGORY_APPSWITCH);
// back key
if (!hasBackKey) {
prefScreen.removePreference(backCategory);
}
// home key
if (!hasHomeKey) {
prefScreen.removePreference(homeCategory);
}
// App switch key (recents)
if (!hasAppSwitchKey) {
prefScreen.removePreference(appSwitchCategory);
}
// menu key
if (!hasMenuKey) {
prefScreen.removePreference(menuCategory);
}
// search/assist key
if (!hasAssistKey) {
prefScreen.removePreference(assistCategory);
}
// let super know we can load ActionPreferences
onPreferenceScreenLoaded(ActionConstants.getDefaults(ActionConstants.HWKEYS));
// load preferences first
setActionPreferencesEnabled(keysDisabled == 0);
final boolean isThreeButtonNavbarEnabled = CherishUtils.isThemeEnabled("com.android.internal.systemui.navbar.threebutton");
mNavbarInverse = (SystemSettingSwitchPreference) findPreference(KEY_NAVBAR_INVERSE); mNavbarInverse = (SystemSettingSwitchPreference) findPreference(KEY_NAVBAR_INVERSE);
mNavbarInverse.setEnabled(isThreeButtonNavbarEnabled); mNavbarInverse.setEnabled(isThreeButtonNavbarEnabled);
mNavigationCompactLayout = (SystemSettingSwitchPreference) findPreference(KEY_NAVIGATION_COMPACT_LAYOUT); mNavigationCompactLayout = (SystemSettingSwitchPreference) findPreference(KEY_NAVIGATION_COMPACT_LAYOUT);
mNavigationCompactLayout.setEnabled(isThreeButtonNavbarEnabled); mNavigationCompactLayout.setEnabled(isThreeButtonNavbarEnabled);
} }
private static boolean isKeyDisablerSupported(Context context) {
final LineageHardwareManager hardware = LineageHardwareManager.getInstance(context);
return hardware.isSupported(LineageHardwareManager.FEATURE_KEY_DISABLE);
}
private static boolean isKeySwapperSupported(Context context) {
final LineageHardwareManager hardware = LineageHardwareManager.getInstance(context);
return hardware.isSupported(LineageHardwareManager.FEATURE_KEY_SWAP);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) { public boolean onPreferenceChange(Preference preference, Object newValue) {
ContentResolver resolver = getActivity().getContentResolver(); ContentResolver resolver = getActivity().getContentResolver();
if (preference == mHwKeyDisable) {
boolean value = (Boolean) newValue;
Settings.System.putInt(getContentResolver(), Settings.System.HARDWARE_KEYS_DISABLE,
value ? 1 : 0);
setActionPreferencesEnabled(!value);
return true;
}
return false; return false;
} }
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return MetricsProto.MetricsEvent.CHERISH_SETTINGS; return MetricsEvent.CHERISH_SETTINGS;
} }
/** /**
* For Search. * For Search.
*/ */
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider(R.xml.cherish_settings_button) {
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
ArrayList<SearchIndexableResource> result =
new ArrayList<SearchIndexableResource>();
SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.cherish_settings_button;
result.add(sir);
return result;
}
@Override @Override
public List<String> getNonIndexableKeys(Context context) { public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context); List<String> keys = super.getNonIndexableKeys(context);
LineageHardwareManager mLineageHardware = LineageHardwareManager.getInstance(context);
if (!isKeyDisablerSupported(context)) {
keys.add(HWKEY_DISABLE);
keys.add(CATEGORY_HWKEY);
keys.add(CATEGORY_BACK);
keys.add(CATEGORY_HOME);
keys.add(CATEGORY_MENU);
keys.add(CATEGORY_ASSIST);
keys.add(CATEGORY_APPSWITCH);
}
return keys; return keys;
} }
}; };
}
}

View File

@@ -1,67 +1,194 @@
package com.cherish.settings.fragments; package com.cherish.settings.fragments;
import com.android.internal.logging.nano.MetricsProto;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.os.Bundle; import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
import androidx.preference.Preference; import androidx.preference.Preference;
import android.preference.SwitchPreference; import androidx.preference.Preference.OnPreferenceChangeListener;
import android.provider.Settings; import androidx.preference.PreferenceScreen;
import android.provider.Settings.SettingNotFoundException; import androidx.preference.PreferenceFragment;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexable;
import android.provider.SearchIndexableResource; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class VolumeRockerSettings extends SettingsPreferenceFragment implements public class VolumeRockerSettings extends SettingsPreferenceFragment implements
Preference.OnPreferenceChangeListener { Preference.OnPreferenceChangeListener {
@Override private static final String TAG = "VolumeSteps";
public void onCreate(Bundle icicle) { private static final String VOLUME_STEP_DEFAULTS = "volume_step_defaults";
super.onCreate(icicle); private static final String FIRST_RUN_KEY = "first_run";
// base map of all preference keys and the associated stream
private static final Map<String, Integer> volume_map = new HashMap<String, Integer>();
static {
volume_map.put("volume_steps_alarm", new Integer(AudioManager.STREAM_ALARM));
volume_map.put("volume_steps_dtmf", new Integer(AudioManager.STREAM_DTMF));
volume_map.put("volume_steps_music", new Integer(AudioManager.STREAM_MUSIC));
volume_map.put("volume_steps_notification", new Integer(AudioManager.STREAM_NOTIFICATION));
volume_map.put("volume_steps_ring", new Integer(AudioManager.STREAM_RING));
volume_map.put("volume_steps_system", new Integer(AudioManager.STREAM_SYSTEM));
volume_map.put("volume_steps_voice_call", new Integer(AudioManager.STREAM_VOICE_CALL));
}
// entries to remove on non-telephony devices
private static final Set<String> telephony_set = new HashSet<String>();
static {
telephony_set.add("volume_steps_dtmf");
telephony_set.add("volume_steps_ring");
telephony_set.add("volume_steps_voice_call");
}
// set of available pref keys after device configuration filter
private Set<String> mAvailableKeys = new HashSet<String>();
private AudioManager mAudioManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.cherish_settings_volume); addPreferencesFromResource(R.xml.cherish_settings_volume);
mAudioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
final PreferenceScreen prefScreen = getPreferenceScreen();
mAvailableKeys = volume_map.keySet();
// remove invalid audio stream prefs
boolean isPhone = TelephonyManager.getDefault().getCurrentPhoneType() != TelephonyManager.PHONE_TYPE_NONE;
if (!isPhone) {
// remove telephony keys from available set
mAvailableKeys.removeAll(telephony_set);
for (String key : telephony_set) {
Preference toRemove = prefScreen.findPreference(key);
if (toRemove != null) {
prefScreen.removePreference(toRemove);
}
}
}
// check prefs for initial run of this fragment
final boolean firstRun = checkForFirstRun();
// entries array isn't translatable ugh
final String defEntry = getString(R.string.volume_steps_reset);
// initialize prefs: set defaults if first run, set listeners and update values
for (String key : mAvailableKeys) {
Preference pref = prefScreen.findPreference(key);
if (pref == null || !(pref instanceof ListPreference)) {
continue;
}
final ListPreference listPref = (ListPreference) pref;
int steps = mAudioManager.getStreamMaxVolume(volume_map.get(key));
if (firstRun) {
saveDefaultSteps(listPref, steps);
}
final int defSteps = getDefaultSteps(listPref);
CharSequence[] entries = new CharSequence[listPref.getEntries().length + 1];
CharSequence[] values = new CharSequence[listPref.getEntryValues().length + 1];
for (int i = 0; i < entries.length; i++) {
if (i == 0) {
entries[i] = defEntry;
values[i] = String.valueOf(defSteps);
continue;
}
entries[i] = listPref.getEntries()[i - 1];
values[i] = listPref.getEntryValues()[i - 1];
}
listPref.setEntries(entries);
listPref.setEntryValues(values);
updateVolumeStepPrefs(listPref, steps);
listPref.setOnPreferenceChangeListener(this);
}
} }
@Override @Override
public boolean onPreferenceChange(Preference preference, Object value) { public boolean onPreferenceChange(Preference preference, Object objValue) {
if (preference.hasKey() && mAvailableKeys.contains(preference.getKey())) {
commitVolumeSteps(preference, Integer.parseInt(objValue.toString()));
}
return true;
}
private SharedPreferences getDefaultStepsPrefs() {
return getActivity().getSharedPreferences(VOLUME_STEP_DEFAULTS,
Context.MODE_PRIVATE);
}
// test for initial run of this fragment
private boolean checkForFirstRun() {
String isFirstRun = getDefaultStepsPrefs().getString(FIRST_RUN_KEY, null);
if (isFirstRun == null) {
getDefaultStepsPrefs().edit().putString(FIRST_RUN_KEY, "first_run_initialized").commit();
return true;
}
return false; return false;
} }
private int getDefaultSteps(Preference pref) {
if (pref == null || !(pref instanceof ListPreference)) {
// unlikely
return -1;
}
String key = pref.getKey();
String value = getDefaultStepsPrefs().getString(key, null);
if (value == null) {
// unlikely
return -1;
}
return Integer.parseInt(value);
}
// on the initial run, let's store true device defaults in sharedPrefs
private void saveDefaultSteps(Preference volPref, int defaultSteps) {
String key = volPref.getKey();
getDefaultStepsPrefs().edit().putString(key, String.valueOf(defaultSteps)).commit();
}
private void updateVolumeStepPrefs(Preference pref, int steps) {
if (pref == null || !(pref instanceof ListPreference)) {
return;
}
final ListPreference listPref = (ListPreference) pref;
listPref.setSummary(String.valueOf(steps));
listPref.setValue(String.valueOf(steps));
}
private void commitVolumeSteps(Preference pref, int steps) {
Settings.System.putInt(getActivity().getContentResolver(), pref.getKey(), steps);
mAudioManager.setStreamMaxVolume(volume_map.get(pref.getKey()), steps);
updateVolumeStepPrefs(pref, steps);
Log.i(TAG, "Volume steps:" + pref.getKey() + "" + String.valueOf(steps));
}
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return MetricsProto.MetricsEvent.CHERISH_SETTINGS; return MetricsEvent.CHERISH_SETTINGS;
} }
/** /**
* For Search. * For Search.
*/ */
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider(R.xml.cherish_settings_volume);
new BaseSearchIndexProvider() { }
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
ArrayList<SearchIndexableResource> result =
new ArrayList<SearchIndexableResource>();
SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.cherish_settings_volume;
result.add(sir);
return result;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
return keys;
}
};
}

View File

@@ -0,0 +1,261 @@
/*
* Copyright (C) 2015 TeamEos project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Handle assignable action dialogs and instances of the ActionPreference
* class that holds target widget state
*/
package com.cherish.settings.preferences;
import java.util.ArrayList;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.util.hwkeys.ActionConstants.Defaults;
import com.android.internal.util.hwkeys.ActionHandler;
import com.android.internal.util.hwkeys.Config;
import com.android.internal.util.hwkeys.Config.ActionConfig;
import com.android.internal.util.hwkeys.Config.ButtonConfig;
import com.cherish.settings.preferences.ShortcutPickHelper;
import com.cherish.settings.preferences.ActionPreference;
import com.cherish.settings.preferences.CustomActionListAdapter;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
public class ActionFragment extends SettingsPreferenceFragment implements
ShortcutPickHelper.OnPickListener {
private static final int DIALOG_CATEGORY = 69;
private static final int DIALOG_CUSTOM_ACTIONS = 70;
private static final String KEY_FOCUSED_PREFERENCE = "key_focused_preference";
private ShortcutPickHelper mPicker;
protected ArrayList<ActionPreference> mPrefHolder;
private String mHolderTag;
private Defaults mDefaults;
private ArrayList<ButtonConfig> mButtons;
private ArrayList<ButtonConfig> mDefaultButtons;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
if (icicle != null) {
String holderTag = icicle.getString(KEY_FOCUSED_PREFERENCE);
if (holderTag != null) {
mHolderTag = holderTag;
}
}
mPicker = new ShortcutPickHelper(getActivity(), this);
mPrefHolder = new ArrayList<ActionPreference>();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
mPicker.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}
@Override
public void shortcutPicked(String uri, String friendlyName, boolean isApplication) {
// activity dialogs pass null here if they are dismissed
// if null, do nothing, no harm
if (uri == null) {
return;
}
findAndUpdatePreference(new ActionConfig(getActivity(), uri), mHolderTag);
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (preference instanceof ActionPreference) {
mHolderTag = ((ActionPreference)preference).getTag();
showDialog(DIALOG_CATEGORY);
return true;
}
return super.onPreferenceTreeClick(preference);
}
@Override
public void onStart() {
super.onStart();
if (mDefaults != null) {
loadAndSetConfigs();
onActionPolicyEnforced(mPrefHolder);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mHolderTag != null) {
outState.putString(KEY_FOCUSED_PREFERENCE, mHolderTag);
}
}
@Override
public Dialog onCreateDialog(int dialogId) {
switch (dialogId) {
case DIALOG_CATEGORY: {
Dialog dialog;
final DialogInterface.OnClickListener categoryClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
onTargetChange(getResources().getStringArray(R.array.action_dialog_values)[item]);
dialog.dismiss();
}
};
dialog = new AlertDialog.Builder(getActivity())
.setTitle(R.string.choose_action_title)
.setItems(getResources().getStringArray(R.array.action_dialog_entries),
categoryClickListener)
.setNegativeButton(getString(android.R.string.cancel), null)
.create();
return dialog;
}
case DIALOG_CUSTOM_ACTIONS: {
Dialog dialog;
final CustomActionListAdapter adapter = new CustomActionListAdapter(getActivity());
if (!usesExtendedActionsList()) {
adapter.removeAction(ActionHandler.SYSTEMUI_TASK_HOME);
adapter.removeAction(ActionHandler.SYSTEMUI_TASK_BACK);
}
final DialogInterface.OnClickListener customActionClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
findAndUpdatePreference(adapter.getItem(item), mHolderTag);
dialog.dismiss();
}
};
dialog = new AlertDialog.Builder(getActivity())
.setTitle(getString(R.string.action_entry_custom_action))
.setAdapter(adapter, customActionClickListener)
.setNegativeButton(getString(android.R.string.cancel), null)
.create();
return dialog;
}
}
return super.onCreateDialog(dialogId);
}
@Override
public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) {
case DIALOG_CATEGORY:
case DIALOG_CUSTOM_ACTIONS:
return MetricsEvent.CHERISH_SETTINGS;
default:
return 0;
}
}
// subclass overrides to include back and home actions
protected boolean usesExtendedActionsList() {
return false;
}
protected void onActionPolicyEnforced(ArrayList<ActionPreference> prefs) {
}
protected void setActionPreferencesEnabled(boolean enabled) {
for (ActionPreference pref : mPrefHolder) {
pref.setEnabled(enabled);
}
}
/**
* load our button lists and ActionPreferences map button action targets from preference keys
* and defaults config maps subclass is required to set desired Defaults interface int
* ActionContants
*/
protected void onPreferenceScreenLoaded(Defaults defaults) {
mDefaults = defaults;
final PreferenceScreen prefScreen = getPreferenceScreen();
for (int i = 0; i < prefScreen.getPreferenceCount(); i++) {
Preference pref = prefScreen.getPreference(i);
if (pref instanceof PreferenceCategory) {
PreferenceCategory cat = (PreferenceCategory) pref;
for (int j = 0; j < cat.getPreferenceCount(); j++) {
Preference child = cat.getPreference(j);
if (child instanceof ActionPreference) {
mPrefHolder.add((ActionPreference) child);
}
}
} else if (pref instanceof ActionPreference) {
mPrefHolder.add((ActionPreference) pref);
}
}
loadAndSetConfigs();
}
protected void loadAndSetConfigs() {
mButtons = Config.getConfig(getActivity(), mDefaults);
mDefaultButtons = Config.getDefaultConfig(getActivity(), mDefaults);
for (ActionPreference pref : mPrefHolder) {
pref.setDefaults(mDefaults);
ButtonConfig button = mButtons.get(pref.getConfigMap().button);
ActionConfig action = button.getActionConfig(pref.getConfigMap().action);
pref.setActionConfig(action);
ButtonConfig defButton = mDefaultButtons.get(pref.getConfigMap().button);
ActionConfig defAction = defButton.getActionConfig(pref.getConfigMap().action);
pref.setDefaultActionConfig(defAction);
}
}
private void onTargetChange(String uri) {
if (uri == null) {
return;
} else if (uri.equals(getString(R.string.action_value_default_action))) {
findAndUpdatePreference(null, mHolderTag);
} else if (uri.equals(getString(R.string.action_value_select_app))) {
mPicker.pickShortcut(null, null, getId());
} else if (uri.equals(getString(R.string.action_value_custom_action))) {
showDialog(DIALOG_CUSTOM_ACTIONS);
}
}
protected void findAndUpdatePreference(ActionConfig action, String tag) {
for (ActionPreference pref : mPrefHolder) {
if (pref.getTag().equals(mHolderTag)) {
if (action == null) {
action = pref.getDefaultActionConfig();
}
pref.setActionConfig(action);
ButtonConfig button = mButtons.get(pref.getConfigMap().button);
ActionConfig newAction = pref.getActionConfig();
button.setActionConfig(newAction, pref.getConfigMap().action);
mButtons = Config.replaceButtonAtPosition(mButtons, button, pref.getConfigMap());
Config.setConfig(getActivity(), mDefaults, mButtons);
onActionPolicyEnforced(mPrefHolder);
break;
}
}
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.CHERISH_SETTINGS;
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright (C) 2015 TeamEos project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Simple preference class implementing ActionHolder interface to assign
* actions to buttons. It is ABSOLUTELY IMPERITIVE that the preference
* key is identical to the target ConfigMap tag in ActionConstants
*/
package com.cherish.settings.preferences;
import java.util.Map;
import com.android.internal.util.hwkeys.ActionConstants.ConfigMap;
import com.android.internal.util.hwkeys.ActionConstants.Defaults;
import com.android.internal.util.hwkeys.ActionHolder;
import com.android.internal.util.hwkeys.Config.ActionConfig;
import com.android.internal.util.hwkeys.Config.ButtonConfig;
import android.content.Context;
import androidx.preference.Preference;
import android.util.AttributeSet;
public class ActionPreference extends Preference implements ActionHolder {
private Defaults mDefaults;
private ConfigMap mMap;
private ActionConfig mAction;
private ActionConfig mDefaultAction;
public ActionPreference(Context context) {
this(context, null);
}
public ActionPreference(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ActionPreference(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public ActionPreference(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs);
}
@Override
public String getTag() {
return this.getKey();
}
@Override
public void setTag(String tag) {
this.setKey(tag);
}
@Override
public Defaults getDefaults() {
return mDefaults;
}
@Override
public void setDefaults(Defaults defaults) {
mDefaults = defaults;
final String tag = this.getKey();
for (Map.Entry<String, ConfigMap> entry : defaults.getActionMap().entrySet()) {
if (((String) entry.getKey()).equals(tag)) {
mMap = entry.getValue();
break;
}
}
}
@Override
public ConfigMap getConfigMap() {
return mMap;
}
@Override
public void setConfigMap(ConfigMap map) {
mMap = map;
}
@Override
public ButtonConfig getButtonConfig() {
return null;
}
@Override
public void setButtonConfig(ButtonConfig button) {
}
@Override
public ActionConfig getActionConfig() {
return mAction;
}
@Override
public void setActionConfig(ActionConfig action) {
mAction = action;
this.setSummary(action.getLabel());
}
@Override
public ButtonConfig getDefaultButtonConfig() {
return null;
}
@Override
public void setDefaultButtonConfig(ButtonConfig button) {
}
@Override
public ActionConfig getDefaultActionConfig() {
return mDefaultAction;
}
@Override
public void setDefaultActionConfig(ActionConfig action) {
mDefaultAction = action;
}
}

View File

@@ -0,0 +1,123 @@
/*
* Copyright (C) 2015 TeamEos project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Adapter for displaying custom actions in a list
*/
package com.cherish.settings.preferences;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.util.hwkeys.ActionHandler;
import com.android.internal.util.hwkeys.Config.ActionConfig;
import com.android.settings.R;
public class CustomActionListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Context mContext;
private List<ActionConfig> mCustomActions = new ArrayList<ActionConfig>();
public CustomActionListAdapter(Context context) {
mContext = context;
mInflater = LayoutInflater.from(context);
reloadActions();
}
private void reloadActions() {
mCustomActions.clear();
mCustomActions.addAll(ActionHandler.getSystemActions(mContext));
notifyDataSetChanged();
}
public void removeAction(String action) {
int index = -1;
for (int i = 0; i < mCustomActions.size(); i++) {
if (TextUtils.equals(mCustomActions.get(i).getAction(), action)) {
index = i;
break;
}
}
if (index > -1) {
mCustomActions.remove(index);
notifyDataSetChanged();
}
}
@Override
public int getCount() {
return mCustomActions.size();
}
@Override
public ActionConfig getItem(int position) {
return mCustomActions.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
final Context ctx = mContext;
if (convertView != null) {
holder = (ViewHolder) convertView.getTag();
} else {
convertView = mInflater.inflate(R.layout.custom_action_item, null, false);
holder = new ViewHolder();
convertView.setTag(holder);
holder.title = (TextView) convertView.findViewById(com.android.internal.R.id.title);
holder.summary = (TextView) convertView
.findViewById(com.android.internal.R.id.summary);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.icon.getLayoutParams();
params.width = holder.icon.getMaxWidth();
params.height = holder.icon.getMaxHeight();
holder.icon.setLayoutParams(params);
holder.icon.setScaleType(ScaleType.CENTER);
holder.icon.setCropToPadding(true);
}
ActionConfig config = getItem(position);
holder.title.setText(config.getLabel());
holder.icon.setBackgroundResource(R.drawable.fab_accent);
holder.icon.setImageDrawable(config.getDefaultIcon(ctx));
holder.summary.setVisibility(View.GONE);
return convertView;
}
private static class ViewHolder {
TextView title;
TextView summary;
ImageView icon;
}
}

View File

@@ -0,0 +1,327 @@
/*
* Copyright (C) 2011 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cherish.settings.preferences;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.TextView;
import com.android.settings.R;
import com.cherish.settings.preferences.ShortcutPickHelper.AppExpandableAdapter.GroupInfo;
public class ShortcutPickHelper {
private FragmentActivity mParent;
private AlertDialog mAlertDialog;
private OnPickListener mListener;
private PackageManager mPackageManager;
private static final int REQUEST_PICK_SHORTCUT = 100;
private static final int REQUEST_PICK_APPLICATION = 101;
private static final int REQUEST_CREATE_SHORTCUT = 102;
private int lastFragmentId;
public interface OnPickListener {
void shortcutPicked(String uri, String friendlyName, boolean isApplication);
}
public ShortcutPickHelper(FragmentActivity parent, OnPickListener listener) {
mParent = parent;
mPackageManager = mParent.getPackageManager();
mListener = listener;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == FragmentActivity.RESULT_OK) {
switch (requestCode) {
case REQUEST_PICK_APPLICATION:
completeSetCustomApp(data);
break;
case REQUEST_CREATE_SHORTCUT:
completeSetCustomShortcut(data);
break;
case REQUEST_PICK_SHORTCUT:
processShortcut(data, REQUEST_PICK_APPLICATION, REQUEST_CREATE_SHORTCUT);
break;
}
}
}
public void pickShortcut(String[] names, ShortcutIconResource[] icons, int fragmentId) {
Bundle bundle = new Bundle();
ArrayList<String> shortcutNames = new ArrayList<String>();
if (names != null) {
for (String s : names) {
shortcutNames.add(s);
}
}
shortcutNames.add(mParent.getString(R.string.profile_applist_title));
shortcutNames.add(mParent.getString(R.string.picker_activities));
bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
ArrayList<ShortcutIconResource> shortcutIcons = new ArrayList<ShortcutIconResource>();
if (icons != null) {
for (ShortcutIconResource s : icons) {
shortcutIcons.add(s);
}
}
shortcutIcons.add(ShortcutIconResource.fromContext(mParent, android.R.drawable.sym_def_app_icon));
shortcutIcons.add(ShortcutIconResource.fromContext(mParent, R.drawable.activities_icon));
bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT, new Intent(Intent.ACTION_CREATE_SHORTCUT));
pickIntent.putExtra(Intent.EXTRA_TITLE, mParent.getText(R.string.select_custom_app_title));
pickIntent.putExtras(bundle);
lastFragmentId = fragmentId;
startFragmentOrActivity(pickIntent, REQUEST_PICK_SHORTCUT);
}
private void startFragmentOrActivity(Intent pickIntent, int requestCode) {
if (lastFragmentId == 0) {
mParent.startActivityForResult(pickIntent, requestCode);
} else {
Fragment cFrag = mParent.getSupportFragmentManager().findFragmentById(lastFragmentId);
if (cFrag != null) {
mParent.startActivityFromFragment(cFrag, pickIntent, requestCode);
}
}
}
private void processShortcut(final Intent intent, int requestCodeApplication, int requestCodeShortcut) {
// Handle case where user selected "Applications"
String applicationName = mParent.getString(R.string.profile_applist_title);
String application2name = mParent.getString(R.string.picker_activities);
String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
if (applicationName != null && applicationName.equals(shortcutName)) {
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
startFragmentOrActivity(pickIntent, requestCodeApplication);
} else if (application2name != null && application2name.equals(shortcutName)){
final List<PackageInfo> pInfos = mPackageManager.getInstalledPackages(PackageManager.GET_ACTIVITIES);
ExpandableListView appListView = new ExpandableListView(mParent);
AppExpandableAdapter appAdapter = new AppExpandableAdapter(pInfos, mParent);
appListView.setAdapter(appAdapter);
appListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Intent shortIntent = new Intent(Intent.ACTION_MAIN);
String pkgName = ((GroupInfo)parent.getExpandableListAdapter().getGroup(groupPosition))
.info.packageName;
String actName = ((GroupInfo)parent.getExpandableListAdapter().getGroup(groupPosition))
.info.activities[childPosition].name;
shortIntent.setClassName(pkgName, actName);
completeSetCustomApp(shortIntent);
mAlertDialog.dismiss();
return true;
}
});
Builder builder = new Builder(mParent);
builder.setView(appListView);
mAlertDialog = builder.create();
mAlertDialog.setTitle(mParent.getString(R.string.select_custom_activity_title));
mAlertDialog.show();
mAlertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
mListener.shortcutPicked(null, null, false);
}
});
} else {
startFragmentOrActivity(intent, requestCodeShortcut);
}
}
public class AppExpandableAdapter extends BaseExpandableListAdapter {
ArrayList<GroupInfo> allList = new ArrayList<GroupInfo>();
final int groupPadding;
public class LabelCompare implements Comparator<GroupInfo>{
@Override
public int compare(GroupInfo item1, GroupInfo item2) {
String rank1 = item1.label.toLowerCase();
String rank2 = item2.label.toLowerCase();
int result = rank1.compareTo(rank2);
if(result == 0) {
return 0;
} else if(result < 0) {
return -1;
} else {
return +1;
}
}
}
class GroupInfo {
String label;
PackageInfo info;
GroupInfo (String l, PackageInfo p) {
label = l;
info = p;
}
}
public AppExpandableAdapter(List<PackageInfo> pInfos, Context context) {
for (PackageInfo i : pInfos) {
allList.add(new GroupInfo(i.applicationInfo.loadLabel(mPackageManager).toString(), i));
}
Collections.sort(allList, new LabelCompare());
groupPadding = context.getResources().getDimensionPixelSize(R.dimen.shortcut_picker_left_padding);
}
public String getChild(int groupPosition, int childPosition) {
return allList.get(groupPosition).info.activities[childPosition].name;
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public int getChildrenCount(int groupPosition) {
if (allList.get(groupPosition).info.activities != null) {
return allList.get(groupPosition).info.activities.length;
} else {
return 0;
}
}
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = View.inflate(mParent, android.R.layout.simple_list_item_1, null);
convertView.setPadding(groupPadding, 0, 0, 0);
}
TextView textView = (TextView)convertView.findViewById(android.R.id.text1);
textView.setText(getChild(groupPosition, childPosition).replaceFirst(allList.get(groupPosition).info.packageName + ".", ""));
return convertView;
}
public GroupInfo getGroup(int groupPosition) {
return allList.get(groupPosition);
}
public int getGroupCount() {
return allList.size();
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
if (convertView == null) {
convertView = View.inflate(mParent, android.R.layout.simple_list_item_1, null);
convertView.setPadding(70, 0, 0, 0);
}
TextView textView = (TextView)convertView.findViewById(android.R.id.text1);
textView.setText(getGroup(groupPosition).label.toString());
return convertView;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public boolean hasStableIds() {
return true;
}
}
private void completeSetCustomApp(Intent data) {
mListener.shortcutPicked(data.toUri(0), getFriendlyActivityName(data, false), true);
}
private void completeSetCustomShortcut(Intent data) {
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
if (intent == null) return;
// preserve shortcut name, we want to restore it later
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME));
// standardize the uri scheme to be sure we can launch it
// TODO: add compatibility for apps that use ACTION_CONFIRM_PIN_SHORTCUT (drag widget on the home screen)
String appUri = intent.toUri(Intent.URI_INTENT_SCHEME);
appUri = appUri.replaceAll("com.android.contacts.action.QUICK_CONTACT", "android.intent.action.VIEW");
mListener.shortcutPicked(appUri, getFriendlyShortcutName(intent), false);
}
private String getFriendlyActivityName(Intent intent, boolean labelOnly) {
ActivityInfo ai = intent.resolveActivityInfo(mPackageManager, PackageManager.GET_ACTIVITIES);
String friendlyName = null;
if (ai != null) {
friendlyName = ai.loadLabel(mPackageManager).toString();
if (friendlyName == null && !labelOnly) {
friendlyName = ai.name;
}
}
return friendlyName != null || labelOnly ? friendlyName : intent.toUri(0);
}
private String getFriendlyShortcutName(Intent intent) {
String activityName = getFriendlyActivityName(intent, true);
String name = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
if (activityName != null && name != null) {
return activityName + ": " + name;
}
return name != null ? name : intent.toUri(0);
}
public String getFriendlyNameForUri(String uri) {
if (uri == null) {
return null;
}
try {
Intent intent = Intent.parseUri(uri, 0);
if (Intent.ACTION_MAIN.equals(intent.getAction())) {
return getFriendlyActivityName(intent, false);
}
return getFriendlyShortcutName(intent);
} catch (URISyntaxException e) {
}
return uri;
}
}