sanders: [SQUASHED] Refactor LineageActions and implement keyhandler

This adds support for FP and screen off gestures

Originally implemented in DU-MOD by @jhenrique09
Adapted to Oreo by @gregor160300 and @jhenrique09
This commit is contained in:
jhenrique09
2017-10-23 09:21:31 -03:00
committed by therootlord
parent 2741c07f99
commit c0c11cd323
31 changed files with 2084 additions and 381 deletions

View File

@@ -29,10 +29,8 @@ LOCAL_RESOURCE_DIR := \
LOCAL_AAPT_FLAGS := --auto-add-overlay \
--extra-packages android.support.v14.preference:android.support.v7.appcompat:android.support.v7.preference:android.support.v7.recyclerview
ifneq ($(INCREMENTAL_BUILDS),)
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_JACK_ENABLED := incremental
endif
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_DEX_PREOPT := false
include frameworks/base/packages/SettingsLib/common.mk

View File

@@ -10,12 +10,14 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<protected-broadcast android:name="com.android.systemui.doze.pulse" />
<application
android:allowBackup="true"
android:label="@string/device_settings_app_name"
android:label="@string/moto_actions_title"
android:icon="@drawable/ic_gesture"
android:persistent="true">
<receiver android:name="org.lineageos.settings.device.BootCompletedReceiver">
@@ -32,7 +34,7 @@
</service>
<activity
android:name=".DozePreferenceActivity"
android:name=".DozeSettings"
android:label="@string/ambient_display_title"
android:theme="@style/LineageActions">
<intent-filter>
@@ -43,7 +45,8 @@
<activity
android:name=".ActionsPreferenceActivity"
android:label="@string/screen_gestures_panel_title"
android:label="@string/moto_actions_title"
android:summary="@string/device_gestures_summary"
android:theme="@style/LineageActions">
<intent-filter>
<action android:name="com.android.settings.action.EXTRA_SETTINGS" />
@@ -54,6 +57,27 @@
<meta-data
android:name="com.android.settings.icon"
android:resource="@drawable/ic_settings_gestures" />
<meta-data
android:name="com.android.settings.summary"
android:resource="@string/device_gestures_summary" />
</activity>
<activity
android:name=".GestureSettings"
android:label="@string/device_gestures_title"
android:theme="@style/LineageActions">
</activity>
<activity
android:name=".FPGestureSettings"
android:label="@string/fingerprint_gestures_title"
android:theme="@style/LineageActions">
</activity>
<activity
android:name=".ScreenOffGestureSettings"
android:label="@string/screen_off_gestures_title"
android:theme="@style/LineageActions">
</activity>
</application>

View File

@@ -1,9 +0,0 @@
-keep class org.lineageos.LineageActions.* {
*;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keep class ** extends android.support.v14.preference.PreferenceFragment

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1000.000000"
android:viewportHeight="1000.000000"
android:tint="?android:attr/colorAccent">
<group
android:translateY="1000.000000"
android:scaleX="0.100000"
android:scaleY="-0.100000">
<path
android:fillColor="@android:color/white"
android:strokeWidth="1"
android:pathData="M3022 9600 c-109 -29 -187 -74 -272 -160 -87 -86 -131 -163 -160 -276 -20 -76 -20
-127 -20 -4094 0 -3967 0 -4018 20 -4094 29 -113 73 -190 160 -276 86 -87 163 -131
276 -160 75 -20 117 -20 1849 -20 1732 0 1774 0 1849 20 113 29 190 73 276 160 87
86 131 163 160 276 20 76 20 127 20 4094 0 3967 0 4018 -20 4094 -29 113 -73 190
-160 276 -86 87 -163 131 -276 160 -75 20 -116 20 -1853 19 -1716 0 -1778 -1 -1849
-19z m1943 -2149 c51 -23 93 -65 116 -116 14 -31 19 -65 19 -150 l0 -110 83 -19
c227 -50 446 -169 623 -338 195 -187 315 -391 387 -658 l32 -115 3 -785 2 -785 363
-357 362 -357 -2075 0 -2075 0 352 347 352 347 3 795 3 795 32 115 c72 267 192 471
387 658 177 169 396 288 624 338 l82 19 0 110 c0 85 5 119 19 150 38 84 117 135
211 135 32 0 72 -8 95 -19z m415 -4018 c-1 -27 -32 -118 -60 -172 -60 -119 -188
-221 -325 -257 -27 -8 -86 -14 -130 -14 -95 0 -157 15 -244 60 -119 60 -221 188
-257 325 -8 28 -14 53 -14 58 0 4 232 7 515 7 283 0 515 -3 515 -7z" />
</group>
</vector>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorAccent">
<path android:fillColor="@android:color/white" android:pathData="M11.83,1.73C8.43,1.79 6.23,3.32 6.23,3.32C5.95,3.5 5.88,3.91 6.07,4.19C6.27,4.5 6.66,4.55 6.96,4.34C6.96,4.34 11.27,1.15 17.46,4.38C17.75,4.55 18.14,4.45 18.31,4.15C18.5,3.85 18.37,3.47 18.03,3.28C16.36,2.4 14.78,1.96 13.36,1.8C12.83,1.74 12.32,1.72 11.83,1.73M12.22,4.34C6.26,4.26 3.41,9.05 3.41,9.05C3.22,9.34 3.3,9.72 3.58,9.91C3.87,10.1 4.26,10 4.5,9.68C4.5,9.68 6.92,5.5 12.2,5.59C17.5,5.66 19.82,9.65 19.82,9.65C20,9.94 20.38,10.04 20.68,9.87C21,9.69 21.07,9.31 20.9,9C20.9,9 18.15,4.42 12.22,4.34M11.5,6.82C9.82,6.94 8.21,7.55 7,8.56C4.62,10.53 3.1,14.14 4.77,19C4.88,19.33 5.24,19.5 5.57,19.39C5.89,19.28 6.07,18.92 5.95,18.6V18.6C4.41,14.13 5.78,11.2 7.8,9.5C9.77,7.89 13.25,7.5 15.84,9.1C17.11,9.9 18.1,11.28 18.6,12.64C19.11,14 19.08,15.32 18.67,15.94C18.25,16.59 17.4,16.83 16.65,16.64C15.9,16.45 15.29,15.91 15.26,14.77C15.23,13.06 13.89,12 12.5,11.84C11.16,11.68 9.61,12.4 9.21,14C8.45,16.92 10.36,21.07 14.78,22.45C15.11,22.55 15.46,22.37 15.57,22.04C15.67,21.71 15.5,21.35 15.15,21.25C11.32,20.06 9.87,16.43 10.42,14.29C10.66,13.33 11.5,13 12.38,13.08C13.25,13.18 14,13.7 14,14.79C14.05,16.43 15.12,17.54 16.34,17.85C17.56,18.16 18.97,17.77 19.72,16.62C20.5,15.45 20.37,13.8 19.78,12.21C19.18,10.61 18.07,9.03 16.5,8.04C14.96,7.08 13.19,6.7 11.5,6.82M11.86,9.25V9.26C10.08,9.32 8.3,10.24 7.28,12.18C5.96,14.67 6.56,17.21 7.44,19.04C8.33,20.88 9.54,22.1 9.54,22.1C9.78,22.35 10.17,22.35 10.42,22.11C10.67,21.87 10.67,21.5 10.43,21.23C10.43,21.23 9.36,20.13 8.57,18.5C7.78,16.87 7.3,14.81 8.38,12.77C9.5,10.67 11.5,10.16 13.26,10.67C15.04,11.19 16.53,12.74 16.5,15.03C16.46,15.38 16.71,15.68 17.06,15.7C17.4,15.73 17.7,15.47 17.73,15.06C17.79,12.2 15.87,10.13 13.61,9.47C13.04,9.31 12.45,9.23 11.86,9.25M12.08,14.25C11.73,14.26 11.46,14.55 11.47,14.89C11.47,14.89 11.5,16.37 12.31,17.8C13.15,19.23 14.93,20.59 18.03,20.3C18.37,20.28 18.64,20 18.62,19.64C18.6,19.29 18.3,19.03 17.91,19.06C15.19,19.31 14.04,18.28 13.39,17.17C12.74,16.07 12.72,14.88 12.72,14.88C12.72,14.53 12.44,14.25 12.08,14.25Z" />
</vector>

View File

@@ -18,7 +18,8 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
android:viewportHeight="24"
android:tint="?android:attr/colorAccent">
<path
android:fillColor="@android:color/white"

View File

@@ -0,0 +1,22 @@
<!--
Copyright (C) 2016 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorAccent">
<path
android:fillColor="@android:color/white"
android:pathData="M9,11.24L9,7.5C9,6.12 10.12,5 11.5,5S14,6.12 14,7.5v3.74c1.21,-0.81 2,-2.18 2,-3.74C16,5.01 13.99,3 11.5,3S7,5.01 7,7.5c0,1.56 0.79,2.93 2,3.74zM18.84,15.87l-4.54,-2.26c-0.17,-0.07 -0.35,-0.11 -0.54,-0.11L13,13.5v-6c0,-0.83 -0.67,-1.5 -1.5,-1.5S10,6.67 10,7.5v10.74l-3.43,-0.72c-0.08,-0.01 -0.15,-0.03 -0.24,-0.03 -0.31,0 -0.59,0.13 -0.79,0.33l-0.79,0.8 4.94,4.94c0.27,0.27 0.65,0.44 1.06,0.44h6.79c0.75,0 1.33,-0.55 1.44,-1.28l0.75,-5.27c0.01,-0.07 0.02,-0.14 0.02,-0.2 0,-0.62 -0.38,-1.16 -0.91,-1.38z"/>
</vector>

View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013-2016 The CyanogenMod Project
(C) 2017 The LineageOS 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.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Title and summary -->
<string name="moto_actions_title">Moto Ações</string>
<!-- Device gestures -->
<string name="device_gestures_title">Gestos do dispositivo</string>
<string name="device_gestures_summary">Gerenciar os gestos do dispositivo</string>
<!-- Ambient display gestures -->
<string name="ambient_display_manage_summary">Gerenciar os gestos da tela ambiente</string>
<!-- Fingerprint gestures -->
<string name="fingerprint_gestures_title">Gestos no sensor biométrico</string>
<string name="fingerprint_gestures_summary">Habilitar o uso de gestos no sensor biométrico</string>
<string name="fingerprint_gestures_manage_summary">Gerenciar os gestos do sensor biométrico</string>
<string name="fingerprint_actions_screenon">Ações com a tela ligada</string>
<string name="fingerprint_tap_title">Toque único</string>
<string name="fingerprint_tap_dlg_title">Selecione a ação para toque único</string>
<string name="fingerprint_double_tap_title">Toque duplo</string>
<string name="fingerprint_double_tap_dlg_title">Selecione a ação para toque duplo</string>
<string name="fingerprint_long_tap_title">Toque longo</string>
<string name="fingerprint_long_tap_dlg_title">Selecione a ação para toque longo</string>
<string name="fingerprint_swipe_left_title">Deslizar para a esquerda</string>
<string name="fingerprint_swipe_left_dlg_title">Selecione a ação para deslizar para a esquerda</string>
<string name="fingerprint_swipe_right_title">Deslizar para a direita</string>
<string name="fingerprint_swipe_right_dlg_title">Selecione a ação para deslizar para a direita</string>
<!-- Fingerprint gestures screen off -->
<string name="fingerprint_gestures_screenoff_title">Habilitar com a tela desligada</string>
<string name="fingerprint_gestures_screenoff_summary">Habilitar os gestos no sensor biométrico quando a tela estiver desligada.\n\nO desbloqueio por impressão digital deve estar desativado para usar esse recurso.</string>
<string name="fingerprint_actions_screenoff">Ações com a tela desligada</string>
<!-- Actions -->
<string name="action_none">Não fazer nada</string>
<string name="action_home">Início</string>
<string name="action_power">Ligar/desligar tela</string>
<string name="action_wake">Acordar o dispositivo</string>
<string name="action_back">Voltar</string>
<string name="action_recents">Recentes</string>
<string name="action_volume_up">Aumentar volume</string>
<string name="action_volume_down">Diminuir volume</string>
<string name="action_voice_assistant">Assistente de voz</string>
<string name="action_play_pause">Tocar/pausar</string>
<string name="action_previous_track">Faixa anterior</string>
<string name="action_next_track">Próxima faixa</string>
<string name="action_flashlight">Ligar/desligar lanterna</string>
<string name="action_camera">Abrir câmera</string>
<string name="action_screenshot">Tirar uma captura de tela</string>
<string name="action_browser">Abrir navegador</string>
<string name="action_dialer">Abrir discador</string>
<string name="action_email">Abrir app de mail</string>
<string name="action_messages">Abrir app de mensagens</string>
<string name="action_pip">Modo picture-in-picture</string>
<!-- Screen off gestures -->
<string name="screen_off_gestures_title">Gestos com a tela desligada</string>
<string name="screen_off_gestures_manage_summary">Gerenciar os gestos com a tela desligada</string>
<string name="screen_off_gestures_swipe_left_title">Deslizar para a esquerda</string>
<string name="screen_off_gestures_swipe_left_dlg_title">Selecione a ação para deslizar para a esquerda</string>
<string name="screen_off_gestures_swipe_right_title">Deslizar para a direita</string>
<string name="screen_off_gestures_swipe_right_dlg_title">Selecione a ação para deslizar para a direita</string>
<string name="screen_off_gestures_swipe_up_title">Deslizar para cima</string>
<string name="screen_off_gestures_swipe_up_dlg_title">Selecione a ação para deslizar para cima</string>
<string name="screen_off_gestures_swipe_down_title">Deslizar para baixo</string>
<string name="screen_off_gestures_swipe_down_dlg_title">Selecione a ação para deslizar para baixo</string>
<!-- Double tap to wake -->
<string name="tap_to_wake">Tocar para ativar</string>
<string name="tap_to_wake_summary">Toque duas vezes em qualquer parte da tela para ativar o dispositivo</string>
<!-- Screen off gestures haptic feedback -->
<string name="haptic_feedback">Retorno tátil</string>
<string name="haptic_feedback_summary">Vibrar quando um gesto for detectado</string>
<!-- Pip -->
<string name="app_does_not_support_pip">O aplicativo não tem suporte ao modo picture-in-picture.</string>
</resources>

View File

@@ -16,29 +16,87 @@
-->
<resources>
<string-array name="fp_keys_listArray">
<item>None</item>
<item>Home</item>
<item>Power</item>
<item>Back</item>
<item>Recents</item>
<item>Volume Up</item>
<item>Volume Down</item>
<item>Voice Assistant</item>
<item>Play/Pause</item>
<item>Previous Track</item>
<item>Next Track</item>
<item>@string/action_none</item>
<item>@string/action_home</item>
<item>@string/action_power</item>
<item>@string/action_back</item>
<item>@string/action_recents</item>
<item>@string/action_volume_up</item>
<item>@string/action_volume_down</item>
<item>@string/action_voice_assistant</item>
<item>@string/action_play_pause</item>
<item>@string/action_previous_track</item>
<item>@string/action_next_track</item>
<item>@string/action_flashlight</item>
<item>@string/action_camera</item>
<item>@string/action_screenshot</item>
<item>@string/action_pip</item>
</string-array>
<string-array name="fp_keys_listValues">
<item>0</item>
<item>102</item>
<item>116</item>
<item>158</item>
<item>580</item>
<item>115</item>
<item>114</item>
<item>582</item>
<item>164</item>
<item>165</item>
<item>163</item>
<item>100</item> <!-- home -->
<item>101</item> <!-- power -->
<item>102</item> <!-- back -->
<item>103</item> <!-- recents -->
<item>104</item> <!-- volume up -->
<item>105</item> <!-- volume down -->
<item>106</item> <!-- voice assistant -->
<item>107</item> <!-- play/pause -->
<item>108</item> <!-- previous track -->
<item>109</item> <!-- next track -->
<item>110</item> <!-- flashlight -->
<item>111</item> <!-- camera -->
<item>112</item> <!-- screenshot -->
<item>120</item> <!-- pip -->
</string-array>
<string-array name="fp_keys_screen_off_listArray">
<item>@string/action_none</item>
<item>@string/action_power</item>
<item>@string/action_volume_up</item>
<item>@string/action_volume_down</item>
<item>@string/action_play_pause</item>
<item>@string/action_previous_track</item>
<item>@string/action_next_track</item>
<item>@string/action_flashlight</item>
<item>@string/action_camera</item>
</string-array>
<string-array name="fp_keys_screen_off_listValues">
<item>0</item>
<item>101</item> <!-- power -->
<item>104</item> <!-- volume up -->
<item>105</item> <!-- volume down -->
<item>107</item> <!-- play/pause -->
<item>108</item> <!-- previous track -->
<item>109</item> <!-- next track -->
<item>110</item> <!-- flashlight -->
<item>111</item> <!-- camera -->
</string-array>
<string-array name="screen_off_listArray">
<item>@string/action_none</item>
<item>@string/action_wake</item>
<item>@string/action_play_pause</item>
<item>@string/action_previous_track</item>
<item>@string/action_next_track</item>
<item>@string/action_flashlight</item>
<item>@string/action_camera</item>
<item>@string/action_browser</item>
<item>@string/action_dialer</item>
<item>@string/action_email</item>
<item>@string/action_messages</item>
</string-array>
<string-array name="screen_off_listValues">
<item>0</item>
<item>101</item> <!-- wake/power -->
<item>107</item> <!-- play/pause -->
<item>108</item> <!-- previous track -->
<item>109</item> <!-- next track -->
<item>110</item> <!-- flashlight -->
<item>111</item> <!-- camera -->
<item>116</item> <!-- browser -->
<item>117</item> <!-- dialer -->
<item>118</item> <!-- email -->
<item>119</item> <!-- messages -->
</string-array>
</resources>

View File

@@ -16,6 +16,79 @@
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Title and summary -->
<string name="moto_actions_title">Moto Actions</string>
<string name="moto_actions_summary">Manage custom actions and fingerprint gestures</string>
<!-- Device gestures -->
<string name="device_gestures_title">Device gestures</string>
<string name="device_gestures_summary">Manage device gestures</string>
<!-- Ambient display gestures -->
<string name="ambient_display_manage_summary">Manage ambient display gestures</string>
<!-- Fingerprint gestures -->
<string name="fingerprint_gestures_title">Fingerprint gestures</string>
<string name="fingerprint_gestures_summary">Use fingerprint gestures</string>
<string name="fingerprint_gestures_manage_summary">Manage fingerprint gestures</string>
<string name="fingerprint_actions_screenon">Actions with screen on</string>
<string name="fingerprint_tap_title">Single tap</string>
<string name="fingerprint_tap_dlg_title">Select action for single tap</string>
<string name="fingerprint_double_tap_title">Double tap</string>
<string name="fingerprint_double_tap_dlg_title">Select action for double tap</string>
<string name="fingerprint_long_tap_title">Long tap</string>
<string name="fingerprint_long_tap_dlg_title">Select action for long tap</string>
<string name="fingerprint_swipe_left_title">Swipe left</string>
<string name="fingerprint_swipe_left_dlg_title">Select action for swipe left</string>
<string name="fingerprint_swipe_right_title">Swipe right</string>
<string name="fingerprint_swipe_right_dlg_title">Select action for swipe right</string>
<!-- Fingerprint gestures screen off -->
<string name="fingerprint_gestures_screenoff_title">Fingerprint gestures when screen off</string>
<string name="fingerprint_gestures_screenoff_summary">Use fingerprint gestures when screen off.\n\nFingerprint unlocking must be disabled to use this feature.</string>
<string name="fingerprint_actions_screenoff">Actions with screen off</string>
<!-- Actions -->
<string name="action_none">None</string>
<string name="action_home">Home</string>
<string name="action_power">Screen on/off</string>
<string name="action_wake">Wake</string>
<string name="action_back">Back</string>
<string name="action_recents">Recents</string>
<string name="action_volume_up">Volume up</string>
<string name="action_volume_down">Volume down</string>
<string name="action_voice_assistant">Voice assistant</string>
<string name="action_play_pause">Play/pause</string>
<string name="action_previous_track">Previous track</string>
<string name="action_next_track">Next track</string>
<string name="action_flashlight">Flashlight on/off</string>
<string name="action_camera">Open camera</string>
<string name="action_screenshot">Take screenshot</string>
<string name="action_browser">Open browser</string>
<string name="action_dialer">Open dialer</string>
<string name="action_email">Open email app</string>
<string name="action_messages">Open messages app</string>
<string name="action_pip">Picture-in-Picture mode</string>
<!-- Screen off gestures -->
<string name="screen_off_gestures_title">Screen off gestures</string>
<string name="screen_off_gestures_manage_summary">Manage gestures when screen is off</string>
<string name="screen_off_gestures_swipe_left_title">Swipe left</string>
<string name="screen_off_gestures_swipe_left_dlg_title">Select action for swipe left</string>
<string name="screen_off_gestures_swipe_right_title">Swipe right</string>
<string name="screen_off_gestures_swipe_right_dlg_title">Select action for swipe right</string>
<string name="screen_off_gestures_swipe_up_title">Swipe up</string>
<string name="screen_off_gestures_swipe_up_dlg_title">Select action for swipe up</string>
<string name="screen_off_gestures_swipe_down_title">Swipe down</string>
<string name="screen_off_gestures_swipe_down_dlg_title">Select action for swipe down</string>
<!-- Double tap to wake -->
<string name="tap_to_wake">Tap to wake</string>
<string name="tap_to_wake_summary">Double-tap anywhere on the screen to wake device</string>
<!-- Screen off gestures haptic feedback -->
<string name="haptic_feedback">Haptic feedback</string>
<string name="haptic_feedback_summary">Vibrate when a touchscreen gesture is detected</string>
<!-- Pip -->
<string name="app_does_not_support_pip">App does not support picture-in-picture mode.</string>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<java-symbol type="string" name="app_does_not_support_pip" />
</resources>

View File

@@ -7,7 +7,7 @@
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
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,
@@ -16,157 +16,36 @@
limitations under the License.
-->
<PreferenceScreen 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">
<PreferenceCategory
android:key="actions_key"
android:title="@string/actions_title">
<SwitchPreference
android:key="gesture_camera_action"
android:defaultValue="true"
android:title="@string/camera_gesture_title"
android:summary="@string/camera_gesture_summary" />
<SwitchPreference
android:key="gesture_camera_action"
android:defaultValue="true"
android:title="@string/camera_gesture_title"
android:summary="@string/camera_gesture_summary" />
<SwitchPreference
android:key="gesture_chop_chop"
android:defaultValue="true"
android:title="@string/chop_chop_gesture_title"
android:summary="@string/chop_chop_gesture_summary" />
<SwitchPreference
android:key="gesture_chop_chop"
android:defaultValue="true"
android:title="@string/chop_chop_gesture_title"
android:summary="@string/chop_chop_gesture_summary" />
<SwitchPreference
android:key="gesture_ir_silencer"
android:defaultValue="false"
android:title="@string/hand_wave_silencer_title"
android:summary="@string/hand_wave_silencer_summary" />
<SwitchPreference
android:key="gesture_ir_silencer"
android:defaultValue="false"
android:title="@string/hand_wave_silencer_title"
android:summary="@string/hand_wave_silencer_summary" />
<SwitchPreference
android:key="gesture_flip_to_mute"
android:defaultValue="false"
android:title="@string/flip_to_mute_title"
android:summary="@string/flip_to_mute_summary" />
<SwitchPreference
android:key="gesture_flip_to_mute"
android:defaultValue="false"
android:title="@string/flip_to_mute_title"
android:summary="@string/flip_to_mute_summary" />
<SwitchPreference
android:key="gesture_lift_to_silence"
android:defaultValue="false"
android:title="@string/lift_to_silence_title"
android:summary="@string/lift_to_silence_summary" />
</PreferenceCategory>
<PreferenceCategory
android:key="fp_key"
android:title="@string/fingerprint_title" >
<SwitchPreference
android:key="fp_home"
android:title="Fingerprint Gestures"
android:summary="Use fingerprint gestures" />
<SwitchPreference
android:key="fp_home_scr_off"
android:dependency="fp_home"
android:title="Fingerprint Gestures when screen off"
android:summary="Use fingerprint gestures when screen off" />
<SwitchPreference
android:key="fp_haptic"
android:dependency="fp_home"
android:defaultValue="0"
android:title="Fingerprint Gestures Haptic Feedback"
android:summary="Vibrate on actions" />
</PreferenceCategory>
<PreferenceCategory
android:key="fp_keys_scr_on"
android:title="Screen On Gestures" >
<ListPreference
android:dependency="fp_home"
android:title="Fingerprint Tap"
android:summary="%s"
android:dialogTitle="Select action for single tap"
android:key="fp_keys"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
<ListPreference
android:dependency="fp_home"
android:title="Fingerprint Long Press"
android:summary="%s"
android:dialogTitle="Select action for long press"
android:key="fp_key_hold"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
<ListPreference
android:dependency="fp_home"
android:title="Fingerprint Swipe Left"
android:summary="%s"
android:dialogTitle="Select action for swipe left"
android:key="fp_key_left"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
<ListPreference
android:dependency="fp_home"
android:title="Fingerprint Swipe Right"
android:summary="%s"
android:dialogTitle="Select action for swipe right"
android:key="fp_key_right"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
</PreferenceCategory>
<PreferenceCategory
android:key="fp_keys_scr_off"
android:title="Screen Off Gestures" >
<ListPreference
android:dependency="fp_home_scr_off"
android:title="Fingerprint Tap"
android:summary="%s"
android:dialogTitle="Select action for single tap"
android:key="fp_keys_off"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
<ListPreference
android:dependency="fp_home_scr_off"
android:title="Fingerprint Long Press"
android:summary="%s"
android:dialogTitle="Select action for long press"
android:key="fp_key_hold_off"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
<ListPreference
android:dependency="fp_home_scr_off"
android:title="Fingerprint Swipe Left"
android:summary="%s"
android:dialogTitle="Select action for swipe left"
android:key="fp_key_left_off"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
<ListPreference
android:dependency="fp_home_scr_off"
android:title="Fingerprint Swipe Right"
android:summary="%s"
android:dialogTitle="Select action for swipe right"
android:key="fp_key_right_off"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
</PreferenceCategory>
<SwitchPreference
android:key="gesture_lift_to_silence"
android:defaultValue="false"
android:title="@string/lift_to_silence_title"
android:summary="@string/lift_to_silence_summary" />
</PreferenceScreen>

View File

@@ -17,29 +17,24 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<PreferenceCategory
android:key="ambient_display_key"
android:title="@string/ambient_display_title">
<SwitchPreference
android:key="doze_enabled"
android:defaultValue="true"
android:title="@string/ambient_display_enable_title"
android:summary="@string/ambient_display_enable_summary" />
<lineageos.preference.SecureSettingSwitchPreference
android:key="doze_enabled"
android:defaultValue="true"
android:title="@string/ambient_display_enable_title"
android:summary="@string/ambient_display_enable_summary" />
<SwitchPreference
android:key="gesture_pick_up"
android:defaultValue="true"
android:title="@string/pick_up_gesture_title"
android:summary="@string/pick_up_gesture_summary"
android:dependency="doze_enabled" />
<SwitchPreference
android:key="gesture_pick_up"
android:defaultValue="true"
android:title="@string/pick_up_gesture_title"
android:summary="@string/pick_up_gesture_summary"
android:dependency="doze_enabled" />
<SwitchPreference
android:key="gesture_hand_wave"
android:defaultValue="true"
android:title="@string/hand_wave_gesture_title"
android:summary="@string/hand_wave_gesture_summary"
android:dependency="doze_enabled" />
</PreferenceCategory>
<SwitchPreference
android:key="gesture_hand_wave"
android:defaultValue="true"
android:title="@string/hand_wave_gesture_title"
android:summary="@string/hand_wave_gesture_summary"
android:dependency="doze_enabled" />
</PreferenceScreen>

View File

@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-2016 The CyanogenMod Project
Copyright (C) 2017 The LineageOS 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<SwitchPreference
android:key="fp_home"
android:title="@string/fingerprint_gestures_title"
android:summary="@string/fingerprint_gestures_summary" />
<SwitchPreference
android:key="fp_home_scr_off"
android:dependency="fp_home"
android:enabled="false"
android:title="@string/fingerprint_gestures_screenoff_title"
android:summary="@string/fingerprint_gestures_screenoff_summary" />
<PreferenceCategory
android:key="fp_keys_scr_on"
android:title="@string/fingerprint_actions_screenon" >
<SwitchPreference
android:key="fp_haptic"
android:dependency="fp_home"
android:defaultValue="0"
android:title="@string/haptic_feedback"
android:summary="@string/haptic_feedback_summary" />
<ListPreference
android:dependency="fp_home"
android:title="@string/fingerprint_tap_title"
android:summary="%s"
android:dialogTitle="@string/fingerprint_tap_dlg_title"
android:key="fp_keys"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
<ListPreference
android:dependency="fp_home"
android:title="@string/fingerprint_double_tap_title"
android:summary="%s"
android:dialogTitle="@string/fingerprint_double_tap_dlg_title"
android:key="fp_key_dbltap"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
<ListPreference
android:dependency="fp_home"
android:title="@string/fingerprint_long_tap_title"
android:summary="%s"
android:dialogTitle="@string/fingerprint_long_tap_dlg_title"
android:key="fp_key_hold"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
<ListPreference
android:dependency="fp_home"
android:title="@string/fingerprint_swipe_left_title"
android:summary="%s"
android:dialogTitle="@string/fingerprint_swipe_left_dlg_title"
android:key="fp_key_left"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
<ListPreference
android:dependency="fp_home"
android:title="@string/fingerprint_swipe_right_title"
android:summary="%s"
android:dialogTitle="@string/fingerprint_swipe_right_dlg_title"
android:key="fp_key_right"
android:defaultValue="0"
android:entries="@array/fp_keys_listArray"
android:entryValues="@array/fp_keys_listValues" />
</PreferenceCategory>
<PreferenceCategory
android:key="fp_keys_scr_off"
android:title="@string/fingerprint_actions_screenoff"
android:enabled="false" >
<SwitchPreference
android:key="fp_haptic_scr_off"
android:dependency="fp_home_scr_off"
android:defaultValue="0"
android:title="@string/haptic_feedback"
android:summary="@string/haptic_feedback_summary" />
<ListPreference
android:dependency="fp_home_scr_off"
android:title="@string/fingerprint_tap_title"
android:summary="%s"
android:dialogTitle="@string/fingerprint_tap_dlg_title"
android:key="fp_keys_off"
android:defaultValue="0"
android:entries="@array/fp_keys_screen_off_listArray"
android:entryValues="@array/fp_keys_screen_off_listValues" />
<ListPreference
android:dependency="fp_home_scr_off"
android:title="@string/fingerprint_double_tap_title"
android:summary="%s"
android:dialogTitle="@string/fingerprint_double_tap_dlg_title"
android:key="fp_key_dbltap_off"
android:defaultValue="0"
android:entries="@array/fp_keys_screen_off_listArray"
android:entryValues="@array/fp_keys_screen_off_listValues" />
<ListPreference
android:dependency="fp_home_scr_off"
android:title="@string/fingerprint_long_tap_title"
android:summary="%s"
android:dialogTitle="@string/fingerprint_long_tap_dlg_title"
android:key="fp_key_hold_off"
android:defaultValue="0"
android:entries="@array/fp_keys_screen_off_listArray"
android:entryValues="@array/fp_keys_screen_off_listValues" />
<ListPreference
android:dependency="fp_home_scr_off"
android:title="@string/fingerprint_swipe_left_title"
android:summary="%s"
android:dialogTitle="@string/fingerprint_swipe_left_dlg_title"
android:key="fp_key_left_off"
android:defaultValue="0"
android:entries="@array/fp_keys_screen_off_listArray"
android:entryValues="@array/fp_keys_screen_off_listValues" />
<ListPreference
android:dependency="fp_home_scr_off"
android:title="@string/fingerprint_swipe_right_title"
android:summary="%s"
android:dialogTitle="@string/fingerprint_swipe_right_dlg_title"
android:key="fp_key_right_off"
android:defaultValue="0"
android:entries="@array/fp_keys_screen_off_listArray"
android:entryValues="@array/fp_keys_screen_off_listValues" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-2016 The CyanogenMod Project
Copyright (C) 2017 The LineageOS 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<PreferenceScreen
android:key="gestures"
android:title="@string/device_gestures_title"
android:summary="@string/device_gestures_summary"
android:icon="@drawable/ic_settings_gestures">
<intent
android:targetPackage="org.lineageos.settings.device"
android:targetClass="org.lineageos.settings.device.GestureSettings" />
</PreferenceScreen>
<PreferenceScreen
android:key="doze"
android:title="@string/ambient_display_title"
android:summary="@string/ambient_display_manage_summary"
android:icon="@drawable/ic_settings_doze">
<intent
android:targetPackage="org.lineageos.settings.device"
android:targetClass="org.lineageos.settings.device.DozeSettings" />
</PreferenceScreen>
<PreferenceScreen
android:key="fp_gestures"
android:title="@string/fingerprint_gestures_title"
android:summary="@string/fingerprint_gestures_manage_summary"
android:icon="@drawable/ic_settings_fingerprint">
<intent
android:targetPackage="org.lineageos.settings.device"
android:targetClass="org.lineageos.settings.device.FPGestureSettings" />
</PreferenceScreen>
<PreferenceScreen
android:key="screen_off_gestures"
android:title="@string/screen_off_gestures_title"
android:summary="@string/screen_off_gestures_manage_summary"
android:icon="@drawable/ic_settings_screen_off_gestures">
<intent
android:targetPackage="org.lineageos.settings.device"
android:targetClass="org.lineageos.settings.device.ScreenOffGestureSettings" />
</PreferenceScreen>
</PreferenceScreen>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-2016 The CyanogenMod Project
Copyright (C) 2017 The LineageOS 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<SwitchPreference
android:key="tap_to_wake"
android:title="@string/tap_to_wake"
android:summary="@string/tap_to_wake_summary" />
<SwitchPreference
android:key="haptic_feedback"
android:title="@string/haptic_feedback"
android:summary="@string/haptic_feedback_summary" />
<ListPreference
android:title="@string/screen_off_gestures_swipe_left_title"
android:summary="%s"
android:dialogTitle="@string/screen_off_gestures_swipe_left_dlg_title"
android:key="screen_off_gestures_swipe_left"
android:defaultValue="0"
android:entries="@array/screen_off_listArray"
android:entryValues="@array/screen_off_listValues" />
<ListPreference
android:title="@string/screen_off_gestures_swipe_right_title"
android:summary="%s"
android:dialogTitle="@string/screen_off_gestures_swipe_right_dlg_title"
android:key="screen_off_gestures_swipe_right"
android:defaultValue="0"
android:entries="@array/screen_off_listArray"
android:entryValues="@array/screen_off_listValues" />
<ListPreference
android:title="@string/screen_off_gestures_swipe_up_title"
android:summary="%s"
android:dialogTitle="@string/screen_off_gestures_swipe_up_dlg_title"
android:key="screen_off_gestures_swipe_up"
android:defaultValue="0"
android:entries="@array/screen_off_listArray"
android:entryValues="@array/screen_off_listValues" />
<ListPreference
android:title="@string/screen_off_gestures_swipe_down_title"
android:summary="%s"
android:dialogTitle="@string/screen_off_gestures_swipe_down_dlg_title"
android:key="screen_off_gestures_swipe_down"
android:defaultValue="0"
android:entries="@array/screen_off_listArray"
android:entryValues="@array/screen_off_listValues" />
</PreferenceScreen>

View File

@@ -25,7 +25,9 @@ public class ActionsPreferenceActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new ActionsPreferenceFragment()).commit();
if (savedInstanceState == null){
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new ActionsPreferenceFragment()).commit();
}
}
}

View File

@@ -17,80 +17,12 @@
package org.lineageos.settings.device;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.NotificationManager;
import android.os.Bundle;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.preference.PreferenceCategory;
import android.support.v14.preference.PreferenceFragment;
import android.support.v7.preference.Preference;
import android.support.v14.preference.SwitchPreference;
import android.view.Menu;
import android.view.MenuItem;
import android.text.TextUtils;
import java.io.File;
import org.lineageos.internal.util.FileUtils;
import org.lineageos.settings.device.actions.Constants;
public class ActionsPreferenceFragment extends PreferenceFragment {
private SwitchPreference mFlipPref;
private NotificationManager mNotificationManager;
private boolean mFlipClick = false;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.actions_panel);
final ActionBar actionBar = getActivity().getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
mNotificationManager = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
mFlipPref = (SwitchPreference) findPreference("gesture_flip_to_mute");
mFlipPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
if (!mNotificationManager.isNotificationPolicyAccessGranted()) {
mFlipPref.setChecked(false);
new AlertDialog.Builder(getContext())
.setTitle(getString(R.string.flip_to_mute_title))
.setMessage(getString(R.string.dnd_access))
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mFlipClick = true;
startActivity(new Intent(
android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS));
}
}).show();
}
return true;
}
});
//Users may deny DND access after giving it
if (!mNotificationManager.isNotificationPolicyAccessGranted()) {
mFlipPref.setChecked(false);
}
}
@Override
public void onResume() {
super.onResume();
if (mNotificationManager.isNotificationPolicyAccessGranted() && mFlipClick) {
mFlipPref.setChecked(true);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
getActivity().onBackPressed();
return true;
}
return false;
addPreferencesFromResource(R.xml.main_panel);
}
}

View File

@@ -42,7 +42,7 @@ public class BootCompletedReceiver extends BroadcastReceiver {
Log.i(TAG, "Booting");
// Restore nodes to saved preference values
for (String pref : Constants.sButtonPrefKeys) {
for (String pref : Constants.sPrefKeys) {
Constants.writePreference(context, pref);
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright (c) 2017 The LineageOS 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 org.lineageos.settings.device;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v14.preference.PreferenceFragment;
import android.support.v14.preference.SwitchPreference;
import android.view.MenuItem;
public class DozePreferenceActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(true);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new DozePreferenceFragment()).commit();
}
public class DozePreferenceFragment extends PreferenceFragment {
private static final String KEY_AMBIENT_DISPLAY_ENABLE = "doze_enabled";
private SwitchPreference mAmbientDisplayPreference;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.doze_panel);
boolean dozeEnabled = LineageActionsSettings.isDozeEnabled(getActivity().getContentResolver());
mAmbientDisplayPreference = (SwitchPreference) findPreference(KEY_AMBIENT_DISPLAY_ENABLE);
// Read from DOZE_ENABLED secure setting
mAmbientDisplayPreference.setChecked(dozeEnabled);
mAmbientDisplayPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean enable = (boolean) newValue;
return enableDoze(enable);
}
});
}
private boolean enableDoze(boolean enable) {
return Settings.Secure.putInt(getContext().getContentResolver(),
Settings.Secure.DOZE_ENABLED, enable ? 1 : 0);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2017 The LineageOS 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 org.lineageos.settings.device;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.provider.Settings;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.SwitchPreference;
import android.view.MenuItem;
public class DozeSettings extends PreferenceActivity {
private static final String KEY_AMBIENT_DISPLAY_ENABLE = "doze_enabled";
private SwitchPreference mAmbientDisplayPreference;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.doze_panel);
getActionBar().setDisplayHomeAsUpEnabled(true);
boolean dozeEnabled = LineageActionsSettings.isDozeEnabled(getContentResolver());
mAmbientDisplayPreference = (SwitchPreference) findPreference(KEY_AMBIENT_DISPLAY_ENABLE);
// Read from DOZE_ENABLED secure setting
mAmbientDisplayPreference.setChecked(dozeEnabled);
mAmbientDisplayPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean enable = (boolean) newValue;
return enableDoze(enable);
}
});
}
private boolean enableDoze(boolean enable) {
return Settings.Secure.putInt(getContentResolver(),
Settings.Secure.DOZE_ENABLED, enable ? 1 : 0);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2016 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 org.lineageos.settings.device;
import android.os.Bundle;
import android.content.Context;
import android.preference.PreferenceCategory;
import android.preference.SwitchPreference;
import android.hardware.fingerprint.FingerprintManager;
import android.preference.PreferenceActivity;
import android.view.MenuItem;
public class FPGestureSettings extends PreferenceActivity {
private SwitchPreference mFPScreenOffGesture;
private PreferenceCategory mFPScreenOffCategory;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.fp_gesture_panel);
getActionBar().setDisplayHomeAsUpEnabled(true);
mFPScreenOffGesture = (SwitchPreference) findPreference("fp_home_scr_off");
mFPScreenOffCategory = (PreferenceCategory) findPreference("fp_keys_scr_off");
boolean hasEnrolledFingerprints = hasEnrolledFingerprints();
mFPScreenOffGesture.setEnabled(!hasEnrolledFingerprints);
mFPScreenOffCategory.setEnabled(!hasEnrolledFingerprints);
}
private boolean hasEnrolledFingerprints(){
FingerprintManager fingerprintManager = (FingerprintManager) getSystemService(Context.FINGERPRINT_SERVICE);
return fingerprintManager.hasEnrolledFingerprints();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) 2016 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 org.lineageos.settings.device;
import android.app.AlertDialog;
import android.app.NotificationManager;
import android.os.Bundle;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.SwitchPreference;
import android.view.MenuItem;
public class GestureSettings extends PreferenceActivity {
private SwitchPreference mFlipPref;
private NotificationManager mNotificationManager;
private boolean mFlipClick = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.actions_panel);
getActionBar().setDisplayHomeAsUpEnabled(true);
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mFlipPref = (SwitchPreference) findPreference("gesture_flip_to_mute");
mFlipPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
if (!mNotificationManager.isNotificationPolicyAccessGranted()) {
mFlipPref.setChecked(false);
new AlertDialog.Builder(GestureSettings.this)
.setTitle(getString(R.string.flip_to_mute_title))
.setMessage(getString(R.string.dnd_access))
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mFlipClick = true;
startActivity(new Intent(
android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS));
}
}).show();
}
return true;
}
});
//Users may deny DND access after giving it
if (!mNotificationManager.isNotificationPolicyAccessGranted()) {
mFlipPref.setChecked(false);
}
}
@Override
public void onResume() {
super.onResume();
if (mNotificationManager.isNotificationPolicyAccessGranted() && mFlipClick) {
mFlipPref.setChecked(true);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -0,0 +1,951 @@
/*
* Copyright (C) 2016 The CyanogenMod Project
* Copyright (C) 2017 The LineageOS 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 org.lineageos.settings.device;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.KeyguardManager;
import android.app.NotificationManager;
import android.app.ISearchManager;
import android.widget.Toast;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.content.res.Resources;
import android.content.pm.ActivityInfo;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.provider.MediaStore;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.input.InputManager;
import android.media.AudioAttributes;
import android.media.session.MediaSessionLegacyHelper;
import android.os.Bundle;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.Vibrator;
import android.os.VibrationEffect;
import android.util.Log;
import android.provider.Settings;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.ViewConfiguration;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
import android.text.TextUtils;
import android.Manifest;
import java.util.List;
import com.android.internal.os.DeviceKeyHandler;
import com.android.internal.util.ArrayUtils;
import lineageos.providers.LineageSettings;
import org.lineageos.internal.util.FileUtils;
import static org.lineageos.settings.device.actions.Constants.*;
public class KeyHandler implements DeviceKeyHandler {
private static final String TAG = KeyHandler.class.getSimpleName();
private static final int GESTURE_REQUEST = 1;
private static final int FP_ACTION_REQUEST = 2;
private static final String ACTION_DISMISS_KEYGUARD =
"com.android.keyguard.action.DISMISS_KEYGUARD_SECURELY";
private static final String GESTURE_WAKEUP_REASON = "keyhandler-gesture-wakeup";
private static final int GESTURE_WAKELOCK_DURATION = 3000;
private final Context mContext;
private final PowerManager mPowerManager;
private final NotificationManager mNotificationManager;
WakeLock mProximityWakeLock;
WakeLock mGestureWakeLock;
private KeyguardManager mKeyguardManager;
private ScreenOffGesturesHandler mScreenOffGesturesHandler;
private FPScreenOffGesturesHandler mFPScreenOffGesturesHandler;
private SensorManager mSensorManager;
private CameraManager mCameraManager;
private String mRearCameraId;
private boolean mTorchEnabled;
private Sensor mProximitySensor;
private Vibrator mVibrator;
private int mProximityTimeOut;
private boolean mProximityWakeSupported;
private ISearchManager mSearchManagerService;
private Handler mHandler;
private int fpTapCounts = 0;
private boolean fpTapPending = false;
private boolean screenOffGesturePending = false;
public boolean mIsHapticFeedbackEnabledOnSystem;
private SettingsObserver mSettingsObserver;
private class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler) {
super(handler);
}
void observe() {
mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor(
Settings.System.HAPTIC_FEEDBACK_ENABLED), false, this, UserHandle.USER_ALL);
update();
}
@Override
public void onChange(boolean selfChange) {
update();
}
public void update() {
mIsHapticFeedbackEnabledOnSystem = Settings.System.getIntForUser(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 1;
}
}
private void setHapticFeedbackEnabledOnSystem(boolean enabled){
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_ENABLED, enabled ? 1 : 0, UserHandle.USER_CURRENT);
}
private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
.build();
public KeyHandler(Context context) {
mContext = context;
mSettingsObserver = new SettingsObserver(new Handler());
mSettingsObserver.observe();
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mNotificationManager
= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mScreenOffGesturesHandler = new ScreenOffGesturesHandler();
mFPScreenOffGesturesHandler = new FPScreenOffGesturesHandler();
mGestureWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"GestureWakeLock");
final Resources resources = mContext.getResources();
mProximityTimeOut = resources.getInteger(
org.lineageos.platform.internal.R.integer.config_proximityCheckTimeout);
mProximityWakeSupported = resources.getBoolean(
org.lineageos.platform.internal.R.bool.config_proximityCheckOnWake);
if (mProximityWakeSupported) {
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
mProximityWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"ProximityWakeLock");
}
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (mVibrator == null || !mVibrator.hasVibrator()) {
mVibrator = null;
}
mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
mCameraManager.registerTorchCallback(new MyTorchCallback(), mScreenOffGesturesHandler);
mCameraManager.registerTorchCallback(new MyTorchCallback(), mFPScreenOffGesturesHandler);
mHandler = new Handler(Looper.getMainLooper());
}
static long[] getLongIntArray(Resources r, int resid) {
int[] ar = r.getIntArray(resid);
if (ar == null) {
return null;
}
long[] out = new long[ar.length];
for (int i=0; i<ar.length; i++) {
out[i] = ar[i];
}
return out;
}
private String getRearCameraId() {
if (mRearCameraId == null) {
try {
for (final String cameraId : mCameraManager.getCameraIdList()) {
CameraCharacteristics characteristics =
mCameraManager.getCameraCharacteristics(cameraId);
int cOrientation = characteristics.get(CameraCharacteristics.LENS_FACING);
if (cOrientation == CameraCharacteristics.LENS_FACING_BACK) {
mRearCameraId = cameraId;
break;
}
}
} catch (CameraAccessException e) {
// Ignore
}
}
return mRearCameraId;
}
private Intent getLaunchableIntent(Intent intent) {
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> resInfo = pm.queryIntentActivities(intent, 0);
if (resInfo.isEmpty()) {
return null;
}
return pm.getLaunchIntentForPackage(resInfo.get(0).activityInfo.packageName);
}
private void triggerCameraAction(){
ensureKeyguardManager();
WakeLock wl = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "GestureWakeLock");
wl.acquire(500);
if (mKeyguardManager.inKeyguardRestrictedInputMode()) {
launchSecureCamera();
} else {
launchCamera();
}
}
private void launchCamera() {
Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
if (getBestActivityInfo(intent) != null) {
// Only launch if we can succeed, but let the user pick the action
mContext.startActivity(intent);
}
}
private void launchSecureCamera() {
// Keyguard won't allow a picker, try to pick the secure intent in the package
// that would be the one used for a default action of launching the camera
Intent normalIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
normalIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
normalIntent.addFlags(Intent.FLAG_FROM_BACKGROUND);
Intent secureIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
secureIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
secureIntent.addFlags(Intent.FLAG_FROM_BACKGROUND);
ActivityInfo normalActivity = getBestActivityInfo(normalIntent);
ActivityInfo secureActivity = getBestActivityInfo(secureIntent, normalActivity);
if (secureActivity != null) {
secureIntent.setComponent(new ComponentName(secureActivity.applicationInfo.packageName, secureActivity.name));
mContext.startActivity(secureIntent);
}
}
private ActivityInfo getBestActivityInfo(Intent intent) {
PackageManager pm = mContext.getPackageManager();
ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
if (resolveInfo != null) {
return resolveInfo.activityInfo;
} else {
// If the resolving failed, just find our own best match
return getBestActivityInfo(intent, null);
}
}
private ActivityInfo getBestActivityInfo(Intent intent, ActivityInfo match) {
PackageManager pm = mContext.getPackageManager();
List <ResolveInfo> activities = pm.queryIntentActivities(intent, 0);
ActivityInfo best = null;
if (activities.size() > 0) {
best = activities.get(0).activityInfo;
if (match != null) {
String packageName = match.applicationInfo.packageName;
for (int i = activities.size()-1; i >= 0; i--) {
ActivityInfo activityInfo = activities.get(i).activityInfo;
if (packageName.equals(activityInfo.applicationInfo.packageName)) {
best = activityInfo;
}
}
}
}
return best;
}
private void openBrowser() {
mGestureWakeLock.acquire(GESTURE_WAKELOCK_DURATION);
mPowerManager.wakeUp(SystemClock.uptimeMillis(), GESTURE_WAKEUP_REASON);
final Intent intent = getLaunchableIntent(
new Intent(Intent.ACTION_VIEW, Uri.parse("http:")));
startActivitySafely(intent);
}
private void openDialer() {
mGestureWakeLock.acquire(GESTURE_WAKELOCK_DURATION);
mPowerManager.wakeUp(SystemClock.uptimeMillis(), GESTURE_WAKEUP_REASON);
final Intent intent = new Intent(Intent.ACTION_DIAL, null);
startActivitySafely(intent);
}
private void openEmail() {
mGestureWakeLock.acquire(GESTURE_WAKELOCK_DURATION);
mPowerManager.wakeUp(SystemClock.uptimeMillis(), GESTURE_WAKEUP_REASON);
final Intent intent = getLaunchableIntent(
new Intent(Intent.ACTION_VIEW, Uri.parse("mailto:")));
startActivitySafely(intent);
}
private void openMessages() {
mGestureWakeLock.acquire(GESTURE_WAKELOCK_DURATION);
mPowerManager.wakeUp(SystemClock.uptimeMillis(), GESTURE_WAKEUP_REASON);
final String defaultApplication = Settings.Secure.getString(
mContext.getContentResolver(), "sms_default_application");
final PackageManager pm = mContext.getPackageManager();
final Intent intent = pm.getLaunchIntentForPackage(defaultApplication);
if (intent != null) {
startActivitySafely(intent);
}
}
private void toggleFlashlight(){
String rearCameraId = getRearCameraId();
if (rearCameraId != null) {
mGestureWakeLock.acquire(GESTURE_WAKELOCK_DURATION);
try {
mCameraManager.setTorchMode(rearCameraId, !mTorchEnabled);
mTorchEnabled = !mTorchEnabled;
} catch (CameraAccessException e) {
// Ignore
}
}
}
private void ensureKeyguardManager() {
if (mKeyguardManager == null) {
mKeyguardManager =
(KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
}
}
private void resetDoubleTapOnFP() {
fpTapCounts = 0;
fpTapPending = false;
mHandler.removeCallbacks(doubleTapRunnable);
}
private Runnable doubleTapRunnable = new Runnable() {
public void run() {
int action = 0;
if (fpTapCounts > 1){
action = str2int(FileUtils.readOneLine(getFPNodeBasedOnScreenState(FP_KEY_DBLTAP_NODE)));
}else{
if (isSingleTapEnabledOnFP()){
action = str2int(FileUtils.readOneLine(getFPNodeBasedOnScreenState(FP_KEYS_NODE)));
}
}
if (action != 0){
boolean isActionSupported = ArrayUtils.contains(mPowerManager.isScreenOn() ? sFPSupportedActions : sFPSupportedActionsScreenOff, action);
if (isActionSupported){
fireFPAction(action, false);
}
}
resetDoubleTapOnFP();
}
};
private void detectDoubleTapOnFP() {
fpTapCounts++;
if (fpTapCounts == 1 || fpTapCounts == 2){
doHapticFeedbackFP(false);
}
if (!fpTapPending){
fpTapPending = true;
mHandler.postDelayed(doubleTapRunnable, ViewConfiguration.getDoubleTapTimeout());
}
}
private boolean isSingleTapEnabledOnFP() {
return !FileUtils.readOneLine(getFPNodeBasedOnScreenState(FP_KEYS_NODE)).equals("0");
}
private boolean isDoubleTapEnabledOnFP() {
return !FileUtils.readOneLine(getFPNodeBasedOnScreenState(FP_KEY_DBLTAP_NODE)).equals("0");
}
private boolean isHapticFeedbackEnabledOnFP() {
return !FileUtils.readOneLine(getFPNodeBasedOnScreenState(FP_HAPTIC_NODE)).equals("0");
}
private String getFPNodeBasedOnScreenState(String node){
if (mPowerManager.isScreenOn()){
return node;
}
switch (node) {
case FP_KEYS_NODE:
return FP_KEYS_SCREENOFF_NODE;
case FP_HAPTIC_NODE:
return FP_HAPTIC_SCREENOFF_NODE;
case FP_KEY_DBLTAP_NODE:
return FP_KEY_SCREENOFF_DBLTAP_NODE;
case FP_KEY_HOLD_NODE:
return FP_KEY_SCREENOFF_HOLD_NODE;
case FP_KEY_RIGHT_NODE:
return FP_KEY_SCREENOFF_RIGHT_NODE;
case FP_KEY_LEFT_NODE:
return FP_KEY_SCREENOFF_LEFT_NODE;
}
return node;
}
public boolean handleKeyEvent(KeyEvent event) {
int scanCode = event.getScanCode();
if (DEBUG){
Log.d(TAG, "DEBUG: action=" + event.getAction()
+ ", flags=" + event.getFlags()
+ ", keyCode=" + event.getKeyCode()
+ ", scanCode=" + event.getScanCode()
+ ", metaState=" + event.getMetaState()
+ ", repeatCount=" + event.getRepeatCount());
}
boolean isFPScanCode = ArrayUtils.contains(sSupportedFPGestures, scanCode);
boolean isScreenOffGesturesScanCode = ArrayUtils.contains(sSupportedScreenOffGestures, scanCode);
if (!isFPScanCode && !isScreenOffGesturesScanCode) {
return false;
}
boolean isFPGestureEnabled = FileUtils.readOneLine(FP_HOME_NODE).equals("1");
boolean isFPGestureEnabledOnScreenOff = FileUtils.readOneLine(FP_HOME_OFF_NODE).equals("1");
boolean isScreenOn = mPowerManager.isScreenOn();
// We only want ACTION_UP event
if (event.getAction() != KeyEvent.ACTION_UP) {
return true;
}
if (scanCode != FP_TAP_SCANCODE){
resetDoubleTapOnFP();
}
if (isFPScanCode) {
if((!isFPGestureEnabled) || (!isScreenOn && !isFPGestureEnabledOnScreenOff)){
resetDoubleTapOnFP();
return false;
}
if (!isScreenOn && isFPGestureEnabledOnScreenOff){
processFPScreenOffScancode(scanCode);
}else{
processFPScancode(scanCode);
}
}else if (isScreenOffGesturesScanCode) {
processScreenOffScancode(scanCode);
}
return true;
}
private void processFPScancode(int scanCode){
int action = 0;
boolean isScreenOn = mPowerManager.isScreenOn();
switch (scanCode) {
case FP_TAP_SCANCODE:
if (isDoubleTapEnabledOnFP()) {
detectDoubleTapOnFP();
return;
}else{
resetDoubleTapOnFP();
action = str2int(FileUtils.readOneLine(getFPNodeBasedOnScreenState(FP_KEYS_NODE)));
}
break;
case FP_HOLD_SCANCODE:
action = str2int(FileUtils.readOneLine(getFPNodeBasedOnScreenState(FP_KEY_HOLD_NODE)));
break;
case FP_RIGHT_SCANCODE:
action = str2int(FileUtils.readOneLine(getFPNodeBasedOnScreenState(FP_KEY_RIGHT_NODE)));
break;
case FP_LEFT_SCANCODE:
action = str2int(FileUtils.readOneLine(getFPNodeBasedOnScreenState(FP_KEY_LEFT_NODE)));
break;
}
boolean isActionSupported = ArrayUtils.contains(isScreenOn ? sFPSupportedActions : sFPSupportedActionsScreenOff, action);
if (isActionSupported){
fireFPAction(action, true);
}
}
private void fireFPAction(int action, boolean haptic){
ensureKeyguardManager();
boolean isHapticFeedbackEnabledOnFP = isHapticFeedbackEnabledOnFP();
if (!haptic){
isHapticFeedbackEnabledOnFP = false;
}
if (isHapticFeedbackEnabledOnFP && (action == ACTION_CAMERA || action == ACTION_FLASHLIGHT)){
vibrate(action == ACTION_CAMERA ? 500 : 250);
}
switch (action) {
case ACTION_HOME:
if (!mKeyguardManager.inKeyguardRestrictedInputMode()){
triggerVirtualKeypress(mHandler, KeyEvent.KEYCODE_HOME);
}
break;
case ACTION_POWER:
toggleScreenState();
break;
case ACTION_BACK:
triggerVirtualKeypress(mHandler, KeyEvent.KEYCODE_BACK);
break;
case ACTION_RECENTS:
if (!mKeyguardManager.inKeyguardRestrictedInputMode()){
triggerVirtualKeypress(mHandler, KeyEvent.KEYCODE_APP_SWITCH);
}
break;
case ACTION_VOLUME_UP:
triggerVirtualKeypress(mHandler, KeyEvent.KEYCODE_VOLUME_UP);
break;
case ACTION_VOLUME_DOWN:
triggerVirtualKeypress(mHandler, KeyEvent.KEYCODE_VOLUME_DOWN);
break;
case ACTION_VOICE_ASSISTANT:
if (!mKeyguardManager.inKeyguardRestrictedInputMode()){
fireGoogleNowOnTap();
}
return;
case ACTION_PLAY_PAUSE:
dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, mContext);
break;
case ACTION_PREVIOUS_TRACK:
dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_PREVIOUS, mContext);
break;
case ACTION_NEXT_TRACK:
dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_NEXT, mContext);
break;
case ACTION_FLASHLIGHT:
toggleFlashlight();
break;
case ACTION_CAMERA:
triggerCameraAction();
break;
case ACTION_SCREENSHOT:
triggerVirtualKeypress(mHandler, KeyEvent.KEYCODE_SYSRQ);
break;
case ACTION_PIP:
if (!mKeyguardManager.inKeyguardRestrictedInputMode()){
goToPipMode();
}
break;
}
if (isHapticFeedbackEnabledOnFP && action != ACTION_VOICE_ASSISTANT && action != ACTION_CAMERA && action != ACTION_FLASHLIGHT){ // prevent double vibration
doHapticFeedbackFP(false);
}
}
private void vibrate(int intensity){
if (mVibrator == null) {
return;
}
mVibrator.vibrate(intensity);
}
private void goToPipMode(){
ActivityInfo ai = getRunningActivityInfo(mContext);
if (ai != null && !ai.supportsPictureInPicture()) {
try {
PackageManager pm = mContext.getPackageManager();
Resources resources = pm.getResourcesForApplication("org.lineageos.settings.device");
int resId = resources.getIdentifier("app_does_not_support_pip", "string", "org.lineageos.settings.device");
final String text = resources.getString(resId);
mHandler.post(new Runnable() {
public void run() {
Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
}
return;
}
triggerVirtualKeypress(mHandler, 171);
}
private static ActivityInfo getRunningActivityInfo(Context context) {
final ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
final PackageManager pm = context.getPackageManager();
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
if (tasks != null && !tasks.isEmpty()) {
ActivityManager.RunningTaskInfo top = tasks.get(0);
try {
return pm.getActivityInfo(top.topActivity, 0);
} catch (PackageManager.NameNotFoundException e) {
}
}
return null;
}
private void toggleScreenState(){
if(mPowerManager.isScreenOn()){
mPowerManager.goToSleep(SystemClock.uptimeMillis());
}else{
mPowerManager.wakeUp(SystemClock.uptimeMillis());
}
}
private static void dispatchMediaKeyWithWakeLock(int keycode, Context context) {
if (ActivityManagerNative.isSystemReady()) {
KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(), KeyEvent.ACTION_DOWN, keycode, 0);
MediaSessionLegacyHelper.getHelper(context).sendMediaButtonEvent(event, true);
event = KeyEvent.changeAction(event, KeyEvent.ACTION_UP);
MediaSessionLegacyHelper.getHelper(context).sendMediaButtonEvent(event, true);
}
}
private void triggerVirtualKeypress(final Handler handler, final int keyCode) {
final boolean mIsHapticFeedbackEnabledOnSystem_ = mIsHapticFeedbackEnabledOnSystem;
if (mIsHapticFeedbackEnabledOnSystem_){
setHapticFeedbackEnabledOnSystem(false);
}
final InputManager im = InputManager.getInstance();
long now = SystemClock.uptimeMillis();
final KeyEvent downEvent = new KeyEvent(now, now, KeyEvent.ACTION_DOWN,
keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, InputDevice.SOURCE_CLASS_BUTTON);
final KeyEvent upEvent = KeyEvent.changeAction(downEvent,
KeyEvent.ACTION_UP);
// add a small delay to make sure everything behind got focus
handler.post(new Runnable(){
@Override
public void run() {
im.injectInputEvent(downEvent,InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}});
handler.postDelayed(new Runnable(){
@Override
public void run() {
im.injectInputEvent(upEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
if (mIsHapticFeedbackEnabledOnSystem_){
setHapticFeedbackEnabledOnSystem(true);
}
}}, 10);
}
private static void sendCloseSystemWindows(String reason) {
if (ActivityManagerNative.isSystemReady()) {
try {
ActivityManagerNative.getDefault().closeSystemDialogs(reason);
} catch (RemoteException e) {
}
}
}
private void fireGoogleNowOnTap() {
doHapticFeedbackFP(false);
mSearchManagerService = ISearchManager.Stub.asInterface(ServiceManager.getService(Context.SEARCH_SERVICE));
if (mSearchManagerService != null) {
try {
mSearchManagerService.launchAssist(new Bundle());
} catch (RemoteException e) {
}
}
doHapticFeedbackFP(true);
}
private int str2int(String str){
if (str == null || str.isEmpty()){
return 0;
}
try {
return Integer.valueOf(str);
} catch (Exception e) {
return 0;
}
}
private void processFPScreenOffScancode(int scanCode){
if (!mFPScreenOffGesturesHandler.hasMessages(FP_ACTION_REQUEST)) {
Message msg = mFPScreenOffGesturesHandler.obtainMessage(FP_ACTION_REQUEST);
msg.arg1 = scanCode;
boolean defaultProximity = mContext.getResources().getBoolean(
org.lineageos.platform.internal.R.bool.config_proximityCheckOnWakeEnabledByDefault);
boolean proximityWakeCheckEnabled = LineageSettings.System.getInt(mContext.getContentResolver(),
LineageSettings.System.PROXIMITY_ON_WAKE, defaultProximity ? 1 : 0) == 1;
if (mProximityWakeSupported && proximityWakeCheckEnabled && mProximitySensor != null) {
mFPScreenOffGesturesHandler.sendMessageDelayed(msg, mProximityTimeOut);
registerFPScreenOffListener(scanCode);
}else{
mFPScreenOffGesturesHandler.sendMessage(msg);
}
}
}
private void registerFPScreenOffListener(final int scanCode) {
mProximityWakeLock.acquire();
mSensorManager.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
mProximityWakeLock.release();
mSensorManager.unregisterListener(this);
if (!mFPScreenOffGesturesHandler.hasMessages(FP_ACTION_REQUEST)) {
// The sensor took to long, ignoring.
return;
}
mFPScreenOffGesturesHandler.removeMessages(FP_ACTION_REQUEST);
if (event.values[0] == mProximitySensor.getMaximumRange()) {
Message msg = mFPScreenOffGesturesHandler.obtainMessage(FP_ACTION_REQUEST);
msg.arg1 = scanCode;
mFPScreenOffGesturesHandler.sendMessage(msg);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, mProximitySensor, SensorManager.SENSOR_DELAY_FASTEST);
}
private void resetScreenOffGestureDelay() {
screenOffGesturePending = false;
mHandler.removeCallbacks(screenOffGestureRunnable);
}
private Runnable screenOffGestureRunnable = new Runnable() {
public void run() {
resetScreenOffGestureDelay();
}
};
private void processScreenOffScancode(int scanCode){
if (screenOffGesturePending){
return;
}else{
resetScreenOffGestureDelay();
screenOffGesturePending = true;
mHandler.postDelayed(screenOffGestureRunnable, 500);
}
if (!mScreenOffGesturesHandler.hasMessages(GESTURE_REQUEST)) {
Message msg = mScreenOffGesturesHandler.obtainMessage(GESTURE_REQUEST);
msg.arg1 = scanCode;
boolean defaultProximity = mContext.getResources().getBoolean(
org.lineageos.platform.internal.R.bool.config_proximityCheckOnWakeEnabledByDefault);
boolean proximityWakeCheckEnabled = LineageSettings.System.getInt(mContext.getContentResolver(),
LineageSettings.System.PROXIMITY_ON_WAKE, defaultProximity ? 1 : 0) == 1;
if (mProximityWakeSupported && proximityWakeCheckEnabled && mProximitySensor != null) {
mScreenOffGesturesHandler.sendMessageDelayed(msg, mProximityTimeOut);
registerScreenOffGesturesListener(scanCode);
} else {
mScreenOffGesturesHandler.sendMessage(msg);
}
}
}
private void registerScreenOffGesturesListener(final int scanCode) {
mProximityWakeLock.acquire();
mSensorManager.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
mProximityWakeLock.release();
mSensorManager.unregisterListener(this);
if (!mScreenOffGesturesHandler.hasMessages(GESTURE_REQUEST)) {
// The sensor took to long, ignoring.
return;
}
mScreenOffGesturesHandler.removeMessages(GESTURE_REQUEST);
if (event.values[0] == mProximitySensor.getMaximumRange()) {
Message msg = mScreenOffGesturesHandler.obtainMessage(GESTURE_REQUEST);
msg.arg1 = scanCode;
mScreenOffGesturesHandler.sendMessage(msg);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, mProximitySensor, SensorManager.SENSOR_DELAY_FASTEST);
}
private class ScreenOffGesturesHandler extends Handler {
@Override
public void handleMessage(Message msg) {
int scanCode = msg.arg1;
int action = 0;
switch (scanCode) {
case GESTURE_SWIPE_RIGHT_SCANCODE:
action = str2int(FileUtils.readOneLine(GESTURE_SWIPE_RIGHT_NODE));
break;
case GESTURE_SWIPE_LEFT_SCANCODE:
action = str2int(FileUtils.readOneLine(GESTURE_SWIPE_LEFT_NODE));
break;
case GESTURE_SWIPE_DOWN_SCANCODE:
action = str2int(FileUtils.readOneLine(GESTURE_SWIPE_DOWN_NODE));
break;
case GESTURE_SWIPE_UP_SCANCODE:
action = str2int(FileUtils.readOneLine(GESTURE_SWIPE_UP_NODE));
break;
case GESTURE_DOUBLE_TAP_SCANCODE:
action = str2int(FileUtils.readOneLine(GESTURE_DOUBLE_TAP_NODE));
if (action != 0){
action = ACTION_POWER;
}
break;
}
boolean isActionSupported = ArrayUtils.contains(sScreenOffSupportedActions, action);
if(isActionSupported){
fireScreenOffAction(action);
}
}
}
private void fireScreenOffAction(int action){
boolean haptic = Settings.System.getInt(mContext.getContentResolver(), KEY_GESTURE_ENABLE_HAPTIC_FEEDBACK, 1) != 0;
if (haptic && (action == ACTION_CAMERA || action == ACTION_FLASHLIGHT)){
vibrate(action == ACTION_CAMERA ? 500 : 250);
}
switch (action) {
case ACTION_POWER:
toggleScreenState();
break;
case ACTION_PLAY_PAUSE:
dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, mContext);
break;
case ACTION_PREVIOUS_TRACK:
dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_PREVIOUS, mContext);
break;
case ACTION_NEXT_TRACK:
dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_NEXT, mContext);
break;
case ACTION_FLASHLIGHT:
toggleFlashlight();
break;
case ACTION_CAMERA:
triggerCameraAction();
break;
case ACTION_BROWSER:
openBrowser();
break;
case ACTION_DIALER:
openDialer();
break;
case ACTION_EMAIL:
openEmail();
break;
case ACTION_MESSAGES:
openMessages();
break;
}
if (action != ACTION_FLASHLIGHT && action != ACTION_CAMERA){
doHapticFeedbackScreenOff();
}
}
private class FPScreenOffGesturesHandler extends Handler {
@Override
public void handleMessage(Message msg) {
processFPScancode(msg.arg1);
}
}
private void startActivitySafely(Intent intent) {
intent.addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
UserHandle user = new UserHandle(UserHandle.USER_CURRENT);
mContext.startActivityAsUser(intent, null, user);
} catch (ActivityNotFoundException e) {
// Ignore
}
}
private void doHapticFeedbackScreenOff() {
if (mVibrator == null) {
return;
}
boolean enabled = Settings.System.getInt(mContext.getContentResolver(), KEY_GESTURE_ENABLE_HAPTIC_FEEDBACK, 1) != 0;
if (enabled) {
mVibrator.vibrate(50);
}
}
private void doHapticFeedbackFP(boolean longpress) {
if (mVibrator == null) {
return;
}
if (isHapticFeedbackEnabledOnFP()) {
long[] pattern = null;
int owningUid;
String owningPackage;
owningUid = android.os.Process.myUid();
owningPackage = mContext.getOpPackageName();
VibrationEffect effect;
if (longpress){
pattern = getLongIntArray(mContext.getResources(),com.android.internal.R.array.config_longPressVibePattern);
}else{
pattern = getLongIntArray(mContext.getResources(),com.android.internal.R.array.config_virtualKeyVibePattern);
}
if (pattern.length == 0) {
// No vibration
return;
} else if (pattern.length == 1) {
// One-shot vibration
effect = VibrationEffect.createOneShot(pattern[0], VibrationEffect.DEFAULT_AMPLITUDE);
} else {
// Pattern vibration
effect = VibrationEffect.createWaveform(pattern, -1);
}
mVibrator.vibrate(owningUid, owningPackage, effect, VIBRATION_ATTRIBUTES);
}
}
private class MyTorchCallback extends CameraManager.TorchCallback {
@Override
public void onTorchModeChanged(String cameraId, boolean enabled) {
if (!cameraId.equals(mRearCameraId))
return;
mTorchEnabled = enabled;
}
@Override
public void onTorchModeUnavailable(String cameraId) {
if (!cameraId.equals(mRearCameraId))
return;
mTorchEnabled = false;
}
}
}

View File

@@ -134,7 +134,9 @@ public class LineageActionsSettings {
mFlipToMuteEnabled = sharedPreferences.getBoolean(GESTURE_FLIP_TO_MUTE_KEY, false);
} else if (GESTURE_LIFT_TO_SILENCE_KEY.equals(key)) {
mLiftToSilenceEnabled = sharedPreferences.getBoolean(GESTURE_LIFT_TO_SILENCE_KEY, false);
} else if (Constants.FP_HOME_KEY.equals(key) || Constants.FP_HAPTIC_KEY.equals(key) || Constants.FP_KEYS.equals(key) || Constants.FP_KEY_HOLD.equals(key) || Constants.FP_KEY_LEFT.equals(key) || Constants.FP_KEY_RIGHT.equals(key)) {
} else if (Constants.FP_HOME_KEY.equals(key) || Constants.FP_HAPTIC_KEY.equals(key) || Constants.FP_HOME_KEY_OFF.equals(key) || Constants.FP_HAPTIC_SCREENOFF_KEY.equals(key) || Constants.FP_KEYS.equals(key) || Constants.FP_KEY_DBLTAP.equals(key) || Constants.FP_KEY_HOLD.equals(key) || Constants.FP_KEY_LEFT.equals(key) || Constants.FP_KEY_RIGHT.equals(key)
|| Constants.FP_KEYS_OFF.equals(key) || Constants.FP_KEY_DBLTAP_OFF.equals(key) || Constants.FP_KEY_HOLD_OFF.equals(key) || Constants.FP_KEY_LEFT_OFF.equals(key) || Constants.FP_KEY_RIGHT_OFF.equals(key)
|| Constants.GESTURE_SWIPE_RIGHT.equals(key) || Constants.GESTURE_SWIPE_LEFT.equals(key) || Constants.GESTURE_SWIPE_DOWN.equals(key) || Constants.GESTURE_SWIPE_UP.equals(key)) {
Constants.writePreference(mContext, key);
updated = false;
} else {

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2016 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 org.lineageos.settings.device;
import android.os.Bundle;
import android.provider.Settings;
import android.preference.Preference;
import android.preference.SwitchPreference;
import android.preference.PreferenceActivity;
import android.view.MenuItem;
import static android.provider.Settings.Secure.DOUBLE_TAP_TO_WAKE;
import static org.lineageos.settings.device.actions.Constants.KEY_GESTURE_ENABLE_HAPTIC_FEEDBACK;
public class ScreenOffGestureSettings extends PreferenceActivity {
private SwitchPreference mTapToWake;
private SwitchPreference mHapticFeedback;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.screen_off_gesture_panel);
getActionBar().setDisplayHomeAsUpEnabled(true);
mTapToWake = (SwitchPreference) findPreference("tap_to_wake");
mTapToWake.setChecked(Settings.Secure.getInt(getContentResolver(), DOUBLE_TAP_TO_WAKE, 0) == 1);
mTapToWake.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object objValue) {
boolean value = (Boolean) objValue;
Settings.Secure.putInt(getContentResolver(), DOUBLE_TAP_TO_WAKE, value ? 1 : 0);
return true;
}
});
mHapticFeedback = (SwitchPreference) findPreference("haptic_feedback");
mHapticFeedback.setChecked(Settings.System.getInt(getContentResolver(), KEY_GESTURE_ENABLE_HAPTIC_FEEDBACK, 1) == 1);
mHapticFeedback.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object objValue) {
boolean value = (Boolean) objValue;
Settings.System.putInt(getContentResolver(), KEY_GESTURE_ENABLE_HAPTIC_FEEDBACK, value ? 1 : 0);
return true;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -29,8 +29,68 @@ import org.lineageos.internal.util.FileUtils;
public class Constants {
public static final boolean DEBUG = false;
private static final String TAG = "LineageActions";
// FP gestures
public static final int FP_TAP_SCANCODE = 616;
public static final int FP_HOLD_SCANCODE = 617;
public static final int FP_RIGHT_SCANCODE = 620;
public static final int FP_LEFT_SCANCODE = 621;
public static final int[] sSupportedFPGestures = new int[]{
FP_TAP_SCANCODE,
FP_HOLD_SCANCODE,
FP_RIGHT_SCANCODE,
FP_LEFT_SCANCODE
};
// FP actions
public static final int ACTION_HOME = 100;
public static final int ACTION_POWER = 101;
public static final int ACTION_BACK = 102;
public static final int ACTION_RECENTS = 103;
public static final int ACTION_VOLUME_UP = 104;
public static final int ACTION_VOLUME_DOWN = 105;
public static final int ACTION_VOICE_ASSISTANT = 106;
public static final int ACTION_PLAY_PAUSE = 107;
public static final int ACTION_PREVIOUS_TRACK = 108;
public static final int ACTION_NEXT_TRACK = 109;
public static final int ACTION_FLASHLIGHT = 110;
public static final int ACTION_CAMERA = 111;
public static final int ACTION_SCREENSHOT = 112;
public static final int ACTION_BROWSER = 116;
public static final int ACTION_DIALER = 117;
public static final int ACTION_EMAIL = 118;
public static final int ACTION_MESSAGES = 119;
public static final int ACTION_PIP = 120;
public static final int[] sFPSupportedActions = new int[]{
ACTION_HOME,
ACTION_POWER,
ACTION_BACK,
ACTION_RECENTS,
ACTION_VOLUME_UP,
ACTION_VOLUME_DOWN,
ACTION_VOICE_ASSISTANT,
ACTION_PLAY_PAUSE,
ACTION_PREVIOUS_TRACK,
ACTION_NEXT_TRACK,
ACTION_FLASHLIGHT,
ACTION_CAMERA,
ACTION_SCREENSHOT,
ACTION_PIP
};
public static final int[] sFPSupportedActionsScreenOff = new int[]{
ACTION_POWER,
ACTION_VOLUME_UP,
ACTION_VOLUME_DOWN,
ACTION_PLAY_PAUSE,
ACTION_PREVIOUS_TRACK,
ACTION_NEXT_TRACK,
ACTION_FLASHLIGHT,
ACTION_CAMERA
};
// Swap keys
public static final String FP_HOME_KEY = "fp_home";
public static final String FP_HOME_KEY_OFF = "fp_home_scr_off";
@@ -42,71 +102,142 @@ public class Constants {
// Haptic node
public static final String FP_HAPTIC_NODE = "/sys/homebutton/haptic";
public static final String FP_HAPTIC_KEY = "fp_haptic";
public static final String FP_HAPTIC_SCREENOFF_NODE = "/sys/homebutton/haptic_off";
public static final String FP_HAPTIC_SCREENOFF_KEY = "fp_haptic_scr_off";
// List of keys
public static final String FP_KEYS = "fp_keys";
public static final String FP_KEY_DBLTAP = "fp_key_dbltap";
public static final String FP_KEY_HOLD = "fp_key_hold";
public static final String FP_KEY_LEFT = "fp_key_left";
public static final String FP_KEY_RIGHT = "fp_key_right";
public static final String FP_KEYS_OFF = "fp_keys_off";
public static final String FP_KEY_DBLTAP_OFF = "fp_key_dbltap_off";
public static final String FP_KEY_HOLD_OFF = "fp_key_hold_off";
public static final String FP_KEY_LEFT_OFF = "fp_key_left_off";
public static final String FP_KEY_RIGHT_OFF = "fp_key_right_off";
// Keys nodes
public static final String FP_KEYS_NODE = "/sys/homebutton/key";
public static final String FP_KEY_DBLTAP_NODE = "/sys/homebutton/key_dbltap";
public static final String FP_KEY_HOLD_NODE = "/sys/homebutton/key_hold";
public static final String FP_KEY_LEFT_NODE = "/sys/homebutton/key_left";
public static final String FP_KEY_RIGHT_NODE = "/sys/homebutton/key_right";
public static final String FP_KEYS_SCREENOFF_NODE = "/sys/homebutton/key_screenoff";
public static final String FP_KEY_SCREENOFF_DBLTAP_NODE = "/sys/homebutton/key_screenoff_dbltap";
public static final String FP_KEY_SCREENOFF_HOLD_NODE = "/sys/homebutton/key_screenoff_hold";
public static final String FP_KEY_SCREENOFF_LEFT_NODE = "/sys/homebutton/key_screenoff_left";
public static final String FP_KEY_SCREENOFF_RIGHT_NODE = "/sys/homebutton/key_screenoff_right";
// Screen off gestures
public static final int GESTURE_SWIPE_RIGHT_SCANCODE = 622;
public static final int GESTURE_SWIPE_LEFT_SCANCODE = 623;
public static final int GESTURE_SWIPE_DOWN_SCANCODE = 624;
public static final int GESTURE_SWIPE_UP_SCANCODE = 625;
public static final int GESTURE_DOUBLE_TAP_SCANCODE = 626;
public static final int[] sSupportedScreenOffGestures = new int[]{
GESTURE_SWIPE_RIGHT_SCANCODE,
GESTURE_SWIPE_LEFT_SCANCODE,
GESTURE_SWIPE_DOWN_SCANCODE,
GESTURE_SWIPE_UP_SCANCODE,
GESTURE_DOUBLE_TAP_SCANCODE
};
public static final int[] sScreenOffSupportedActions = new int[]{
ACTION_POWER,
ACTION_PLAY_PAUSE,
ACTION_PREVIOUS_TRACK,
ACTION_NEXT_TRACK,
ACTION_FLASHLIGHT,
ACTION_CAMERA,
ACTION_BROWSER,
ACTION_DIALER,
ACTION_EMAIL,
ACTION_MESSAGES
};
// List of screen off gestures keys
public static final String GESTURE_SWIPE_RIGHT = "screen_off_gestures_swipe_right";
public static final String GESTURE_SWIPE_LEFT = "screen_off_gestures_swipe_left";
public static final String GESTURE_SWIPE_DOWN = "screen_off_gestures_swipe_down";
public static final String GESTURE_SWIPE_UP = "screen_off_gestures_swipe_up";
// Screen off gestures nodes
public static final String GESTURE_SWIPE_RIGHT_NODE = "/sys/android_touch/gesture_swipe_right";
public static final String GESTURE_SWIPE_LEFT_NODE = "/sys/android_touch/gesture_swipe_left";
public static final String GESTURE_SWIPE_DOWN_NODE = "/sys/android_touch/gesture_swipe_down";
public static final String GESTURE_SWIPE_UP_NODE = "/sys/android_touch/gesture_swipe_up";
public static final String GESTURE_DOUBLE_TAP_NODE = "/sys/android_touch/doubletap2wake";
// Screen off gestures haptic
public static final String KEY_GESTURE_ENABLE_HAPTIC_FEEDBACK = "screen_off_gesture_haptic_feedback";
// Holds <preference_key> -> <proc_node> mapping
public static final Map<String, String> sBooleanNodePreferenceMap = new HashMap<>();
// Holds <preference_key> -> <default_values> mapping
public static final Map<String, Object> sNodeDefaultMap = new HashMap<>();
public static final String[] sButtonPrefKeys = {
public static final String[] sPrefKeys = {
FP_HOME_KEY,
FP_HOME_KEY_OFF,
FP_HAPTIC_KEY,
FP_HAPTIC_SCREENOFF_KEY,
FP_KEYS,
FP_KEY_DBLTAP,
FP_KEY_HOLD,
FP_KEY_RIGHT,
FP_KEY_LEFT,
FP_HAPTIC_KEY,
};
public static final String[] sButtonScreenOffPrefKeys = {
FP_KEYS_OFF,
FP_KEY_DBLTAP_OFF,
FP_KEY_HOLD_OFF,
FP_KEY_RIGHT_OFF,
FP_KEY_LEFT_OFF,
FP_HOME_KEY_OFF,
GESTURE_SWIPE_RIGHT,
GESTURE_SWIPE_LEFT,
GESTURE_SWIPE_DOWN,
GESTURE_SWIPE_UP
};
static {
sBooleanNodePreferenceMap.put(FP_HOME_KEY, FP_HOME_NODE);
sBooleanNodePreferenceMap.put(FP_HOME_KEY_OFF, FP_HOME_OFF_NODE);
sBooleanNodePreferenceMap.put(FP_HAPTIC_KEY, FP_HAPTIC_NODE);
sBooleanNodePreferenceMap.put(FP_HAPTIC_SCREENOFF_KEY, FP_HAPTIC_SCREENOFF_NODE);
sBooleanNodePreferenceMap.put(FP_KEYS, FP_KEYS_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_DBLTAP, FP_KEY_DBLTAP_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_HOLD, FP_KEY_HOLD_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_LEFT, FP_KEY_LEFT_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_RIGHT, FP_KEY_RIGHT_NODE);
sBooleanNodePreferenceMap.put(FP_HAPTIC_KEY, FP_HAPTIC_NODE);
sBooleanNodePreferenceMap.put(FP_KEYS_OFF, FP_KEYS_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_HOLD_OFF, FP_KEY_HOLD_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_LEFT_OFF, FP_KEY_LEFT_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_RIGHT_OFF, FP_KEY_RIGHT_NODE);
sBooleanNodePreferenceMap.put(FP_KEYS_OFF, FP_KEYS_SCREENOFF_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_DBLTAP_OFF, FP_KEY_SCREENOFF_DBLTAP_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_HOLD_OFF, FP_KEY_SCREENOFF_HOLD_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_LEFT_OFF, FP_KEY_SCREENOFF_LEFT_NODE);
sBooleanNodePreferenceMap.put(FP_KEY_RIGHT_OFF, FP_KEY_SCREENOFF_RIGHT_NODE);
sBooleanNodePreferenceMap.put(GESTURE_SWIPE_RIGHT, GESTURE_SWIPE_RIGHT_NODE);
sBooleanNodePreferenceMap.put(GESTURE_SWIPE_LEFT, GESTURE_SWIPE_LEFT_NODE);
sBooleanNodePreferenceMap.put(GESTURE_SWIPE_DOWN, GESTURE_SWIPE_DOWN_NODE);
sBooleanNodePreferenceMap.put(GESTURE_SWIPE_UP, GESTURE_SWIPE_UP_NODE);
sNodeDefaultMap.put(FP_HOME_KEY, false);
sNodeDefaultMap.put(FP_HOME_KEY_OFF, false);
sNodeDefaultMap.put(FP_HAPTIC_KEY, false);
sNodeDefaultMap.put(FP_HAPTIC_SCREENOFF_KEY, false);
sNodeDefaultMap.put(FP_KEYS, "0");
sNodeDefaultMap.put(FP_KEY_DBLTAP, "0");
sNodeDefaultMap.put(FP_KEY_HOLD, "0");
sNodeDefaultMap.put(FP_KEY_LEFT, "0");
sNodeDefaultMap.put(FP_KEY_RIGHT, "0");
sNodeDefaultMap.put(FP_KEYS_OFF, "0");
sNodeDefaultMap.put(FP_KEY_DBLTAP_OFF, "0");
sNodeDefaultMap.put(FP_KEY_HOLD_OFF, "0");
sNodeDefaultMap.put(FP_KEY_LEFT_OFF, "0");
sNodeDefaultMap.put(FP_KEY_RIGHT_OFF, "0");
sNodeDefaultMap.put(FP_HAPTIC_KEY, false);
sNodeDefaultMap.put(GESTURE_SWIPE_RIGHT, "0");
sNodeDefaultMap.put(GESTURE_SWIPE_LEFT, "0");
sNodeDefaultMap.put(GESTURE_SWIPE_DOWN, "0");
sNodeDefaultMap.put(GESTURE_SWIPE_UP, "0");
}
public static boolean isPreferenceEnabled(Context context, String key) {
@@ -123,8 +254,8 @@ public class Constants {
String value = "1";
Log.e(TAG, "Write Pref: " + pref);
if (!pref.equals(FP_KEYS) && !pref.equals(FP_KEY_HOLD) && !pref.equals(FP_KEY_LEFT) && !pref.equals(FP_KEY_RIGHT) &&
!pref.equals(FP_KEYS_OFF) && !pref.equals(FP_KEY_HOLD_OFF) && !pref.equals(FP_KEY_LEFT_OFF) && !pref.equals(FP_KEY_RIGHT_OFF))
if (!pref.equals(FP_KEYS) && !pref.equals(FP_KEY_DBLTAP) && !pref.equals(FP_KEY_HOLD) && !pref.equals(FP_KEY_LEFT) && !pref.equals(FP_KEY_RIGHT) &&
!pref.equals(FP_KEYS_OFF) && !pref.equals(FP_KEY_DBLTAP_OFF) && !pref.equals(FP_KEY_HOLD_OFF) && !pref.equals(FP_KEY_LEFT_OFF) && !pref.equals(FP_KEY_RIGHT_OFF) && !pref.equals(GESTURE_SWIPE_RIGHT) && !pref.equals(GESTURE_SWIPE_LEFT) && !pref.equals(GESTURE_SWIPE_DOWN) && !pref.equals(GESTURE_SWIPE_UP))
value = isPreferenceEnabled(context, pref) ? "1" : "0";
else
value = GetPreference(context, pref);

View File

@@ -41,16 +41,8 @@ public class ScreenReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
mNotifier.screenTurnedOff();
for (String pref : Constants.sButtonScreenOffPrefKeys) {
Constants.writePreference(context, pref);
}
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
mNotifier.screenTurnedOn();
for (String pref : Constants.sButtonPrefKeys) {
Constants.writePreference(context, pref);
}
}
}
}