Rageshake: settings for sensitivity

This commit is contained in:
Benoit Marty 2020-01-02 17:42:44 +01:00
parent 5a24f78c05
commit 5c26f66523
7 changed files with 158 additions and 98 deletions

View File

@ -54,6 +54,7 @@ import im.vector.riotx.features.rageshake.BugReportActivity
import im.vector.riotx.features.rageshake.BugReporter
import im.vector.riotx.features.rageshake.RageShake
import im.vector.riotx.features.session.SessionListener
import im.vector.riotx.features.settings.VectorPreferences
import im.vector.riotx.features.themes.ActivityOtherThemes
import im.vector.riotx.features.themes.ThemeUtils
import im.vector.riotx.receivers.DebugReceiver
@ -88,9 +89,11 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
private lateinit var configurationViewModel: ConfigurationViewModel
private lateinit var sessionListener: SessionListener
protected lateinit var bugReporter: BugReporter
private lateinit var rageShake: RageShake
lateinit var rageShake: RageShake
private set
protected lateinit var navigator: Navigator
private lateinit var activeSessionHolder: ActiveSessionHolder
private lateinit var vectorPreferences: VectorPreferences
// Filter for multiple invalid token error
private var mainActivityStarted = false
@ -135,7 +138,8 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
}
override fun onCreate(savedInstanceState: Bundle?) {
screenComponent = DaggerScreenComponent.factory().create(getVectorComponent(), this)
val vectorComponent = getVectorComponent()
screenComponent = DaggerScreenComponent.factory().create(vectorComponent, this)
val timeForInjection = measureTimeMillis {
injectWith(screenComponent)
}
@ -150,6 +154,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
rageShake = screenComponent.rageShake()
navigator = screenComponent.navigator()
activeSessionHolder = screenComponent.activeSessionHolder()
vectorPreferences = vectorComponent.vectorPreferences()
configurationViewModel.activityRestarter.observe(this, Observer {
if (!it.hasBeenHandled) {
// Recreate the Activity because configuration has changed
@ -226,7 +231,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
configurationViewModel.onActivityResumed()
if (this !is BugReportActivity) {
if (this !is BugReportActivity && vectorPreferences.useRageshake()) {
rageShake.start()
}

View File

@ -19,33 +19,28 @@ package im.vector.riotx.features.rageshake
import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorManager
import android.preference.PreferenceManager
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.edit
import com.squareup.seismic.ShakeDetector
import im.vector.riotx.R
import im.vector.riotx.features.settings.VectorPreferences
import javax.inject.Inject
class RageShake @Inject constructor(private val activity: AppCompatActivity,
private val bugReporter: BugReporter) : ShakeDetector.Listener {
private val bugReporter: BugReporter,
private val vectorPreferences: VectorPreferences) : ShakeDetector.Listener {
private var shakeDetector: ShakeDetector? = null
private var dialogDisplayed = false
var interceptor: (() -> Unit)? = null
fun start() {
if (!isEnable(activity)) {
return
}
val sensorManager = activity.getSystemService(AppCompatActivity.SENSOR_SERVICE) as? SensorManager
if (sensorManager == null) {
return
}
val sensorManager = activity.getSystemService(AppCompatActivity.SENSOR_SERVICE) as? SensorManager ?: return
shakeDetector = ShakeDetector(this).apply {
setSensitivity(vectorPreferences.getRageshakeSensitivity())
start(sensorManager)
}
}
@ -54,52 +49,41 @@ class RageShake @Inject constructor(private val activity: AppCompatActivity,
shakeDetector?.stop()
}
/**
* Enable the feature, and start it
*/
fun enable() {
PreferenceManager.getDefaultSharedPreferences(activity).edit {
putBoolean(SETTINGS_USE_RAGE_SHAKE_KEY, true)
}
start()
}
/**
* Disable the feature, and stop it
*/
fun disable() {
PreferenceManager.getDefaultSharedPreferences(activity).edit {
putBoolean(SETTINGS_USE_RAGE_SHAKE_KEY, false)
}
stop()
fun setSensitivity(sensitivity: Int) {
shakeDetector?.setSensitivity(sensitivity)
}
override fun hearShake() {
if (dialogDisplayed) {
// Filtered!
return
val i = interceptor
if (i != null) {
i.invoke()
} else {
if (dialogDisplayed) {
// Filtered!
return
}
dialogDisplayed = true
AlertDialog.Builder(activity)
.setMessage(R.string.send_bug_report_alert_message)
.setPositiveButton(R.string.yes) { _, _ -> openBugReportScreen() }
.setNeutralButton(R.string.settings) { _, _ -> openSettings() }
.setOnDismissListener { dialogDisplayed = false }
.setNegativeButton(R.string.no, null)
.show()
}
dialogDisplayed = true
AlertDialog.Builder(activity)
.setMessage(R.string.send_bug_report_alert_message)
.setPositiveButton(R.string.yes) { _, _ -> openBugReportScreen() }
.setNeutralButton(R.string.disable) { _, _ -> disable() }
.setOnDismissListener { dialogDisplayed = false }
.setNegativeButton(R.string.no, null)
.show()
}
private fun openBugReportScreen() {
bugReporter.openBugReportScreen(activity)
}
companion object {
private const val SETTINGS_USE_RAGE_SHAKE_KEY = "SETTINGS_USE_RAGE_SHAKE_KEY"
private fun openSettings() {
// TODO
}
companion object {
/**
* Check if the feature is available
*/
@ -107,12 +91,5 @@ class RageShake @Inject constructor(private val activity: AppCompatActivity,
return (context.getSystemService(AppCompatActivity.SENSOR_SERVICE) as? SensorManager)
?.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null
}
/**
* Check if the feature is enable (enabled by default)
*/
private fun isEnable(context: Context): Boolean {
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(SETTINGS_USE_RAGE_SHAKE_KEY, true)
}
}
}

View File

@ -23,6 +23,7 @@ import android.net.Uri
import android.provider.MediaStore
import androidx.core.content.edit
import androidx.preference.PreferenceManager
import com.squareup.seismic.ShakeDetector
import im.vector.riotx.R
import im.vector.riotx.features.homeserver.ServerUrlsRepository
import im.vector.riotx.features.themes.ThemeUtils
@ -153,7 +154,10 @@ class VectorPreferences @Inject constructor(private val context: Context) {
// analytics
const val SETTINGS_USE_ANALYTICS_KEY = "SETTINGS_USE_ANALYTICS_KEY"
// Rageshake
const val SETTINGS_USE_RAGE_SHAKE_KEY = "SETTINGS_USE_RAGE_SHAKE_KEY"
const val SETTINGS_RAGE_SHAKE_DETECTION_THRESHOLD_KEY = "SETTINGS_RAGE_SHAKE_DETECTION_THRESHOLD_KEY"
// other
const val SETTINGS_MEDIA_SAVING_PERIOD_KEY = "SETTINGS_MEDIA_SAVING_PERIOD_KEY"
@ -732,6 +736,13 @@ class VectorPreferences @Inject constructor(private val context: Context) {
return defaultPrefs.getBoolean(SETTINGS_USE_RAGE_SHAKE_KEY, true)
}
/**
* Get the rage shake sensitivity.
*/
fun getRageshakeSensitivity(): Int {
return defaultPrefs.getInt(SETTINGS_RAGE_SHAKE_DETECTION_THRESHOLD_KEY, ShakeDetector.SENSITIVITY_MEDIUM)
}
/**
* Update the rage shake status.
*

View File

@ -16,14 +16,63 @@
package im.vector.riotx.features.settings
import androidx.preference.Preference
import androidx.preference.SeekBarPreference
import im.vector.riotx.R
import im.vector.riotx.core.platform.VectorBaseActivity
import im.vector.riotx.core.preference.VectorSwitchPreference
import im.vector.riotx.features.rageshake.RageShake
class VectorSettingsDeveloperModeFragment : VectorSettingsBaseFragment() {
override var titleRes = R.string.settings_developer_mode
override val preferenceXmlRes = R.xml.vector_settings_developer_mode
private var rageshake: RageShake? = null
override fun onResume() {
super.onResume()
rageshake = (activity as? VectorBaseActivity)?.rageShake
rageshake?.interceptor = {
(activity as? VectorBaseActivity)?.showSnackbar(getString(R.string.rageshake_detected))
}
}
override fun onPause() {
super.onPause()
rageshake?.interceptor = null
rageshake = null
}
override fun bindPref() {
// Nothing to do
val isRageShakeAvailable = RageShake.isAvailable(requireContext())
if (isRageShakeAvailable) {
findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_USE_RAGE_SHAKE_KEY)!!
.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
if (newValue as? Boolean == true) {
rageshake?.start()
} else {
rageshake?.stop()
}
true
}
findPreference<SeekBarPreference>(VectorPreferences.SETTINGS_RAGE_SHAKE_DETECTION_THRESHOLD_KEY)!!
.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
(activity as? VectorBaseActivity)?.let {
val newValueAsInt = newValue as? Int ?: return@OnPreferenceChangeListener true
rageshake?.setSensitivity(newValueAsInt)
}
true
}
} else {
findPreference<VectorSwitchPreference>("SETTINGS_RAGE_SHAKE_CATEGORY_KEY")!!.isVisible = false
}
}
}

View File

@ -10,5 +10,9 @@
<string name="settings_developer_mode">Developer mode</string>
<string name="settings_developer_mode_summary">The developer mode activates hidden features and may also make the application less stable. For developers only!</string>
<string name="settings_rageshake">Rageshake</string>
<string name="settings_rageshake_detection_threshold">Detection threshold</string>
<string name="settings_rageshake_detection_threshold_summary">Shake your phone to test the detection threshold</string>
<string name="rageshake_detected">Shake detected!</string>
<string name="settings">Settings</string>
</resources>

View File

@ -2,40 +2,63 @@
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<im.vector.riotx.core.preference.VectorSwitchPreference
android:defaultValue="false"
android:key="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
android:summary="@string/settings_developer_mode_summary"
android:title="@string/settings_developer_mode" />
<im.vector.riotx.core.preference.VectorSwitchPreference
android:defaultValue="false"
android:dependency="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
android:key="SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY"
android:title="@string/settings_labs_show_hidden_events_in_timeline" />
<im.vector.riotx.core.preference.VectorSwitchPreference
android:defaultValue="false"
android:dependency="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
android:key="SETTINGS_LABS_ALLOW_EXTENDED_LOGS"
android:summary="@string/labs_allow_extended_logging_summary"
android:title="@string/labs_allow_extended_logging" />
<!-- TODO Display unsupported events -->
<im.vector.riotx.core.preference.VectorPreferenceCategory
android:dependency="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
android:title="@string/settings_notifications">
android:key="SETTINGS_RAGE_SHAKE_CATEGORY_KEY"
android:title="@string/settings_rageshake">
<im.vector.riotx.core.preference.VectorPreference
android:persistent="false"
android:title="@string/settings_notifications_targets"
app:fragment="im.vector.riotx.features.settings.push.PushGatewaysFragment" />
<im.vector.riotx.core.preference.VectorSwitchPreference
android:key="SETTINGS_USE_RAGE_SHAKE_KEY"
android:title="@string/send_bug_report_rage_shake" />
<im.vector.riotx.core.preference.VectorPreference
android:persistent="false"
android:title="@string/settings_push_rules"
app:fragment="im.vector.riotx.features.settings.push.PushRulesFragment" />
<SeekBarPreference
android:defaultValue="13"
android:dependency="SETTINGS_USE_RAGE_SHAKE_KEY"
android:key="SETTINGS_RAGE_SHAKE_DETECTION_THRESHOLD_KEY"
android:max="17"
android:summary="@string/settings_rageshake_detection_threshold_summary"
android:title="@string/settings_rageshake_detection_threshold"
app:min="9" />
</im.vector.riotx.core.preference.VectorPreferenceCategory>
<im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_developer_mode">
<im.vector.riotx.core.preference.VectorSwitchPreference
android:defaultValue="false"
android:key="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
android:summary="@string/settings_developer_mode_summary"
android:title="@string/settings_developer_mode" />
<im.vector.riotx.core.preference.VectorSwitchPreference
android:defaultValue="false"
android:dependency="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
android:key="SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY"
android:title="@string/settings_labs_show_hidden_events_in_timeline" />
<im.vector.riotx.core.preference.VectorSwitchPreference
android:defaultValue="false"
android:dependency="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
android:key="SETTINGS_LABS_ALLOW_EXTENDED_LOGS"
android:summary="@string/labs_allow_extended_logging_summary"
android:title="@string/labs_allow_extended_logging" />
<!-- TODO Display unsupported events -->
<im.vector.riotx.core.preference.VectorPreferenceCategory
android:dependency="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
android:title="@string/settings_notifications">
<im.vector.riotx.core.preference.VectorPreference
android:persistent="false"
android:title="@string/settings_notifications_targets"
app:fragment="im.vector.riotx.features.settings.push.PushGatewaysFragment" />
<im.vector.riotx.core.preference.VectorPreference
android:persistent="false"
android:title="@string/settings_push_rules"
app:fragment="im.vector.riotx.features.settings.push.PushRulesFragment" />
</im.vector.riotx.core.preference.VectorPreferenceCategory>
</im.vector.riotx.core.preference.VectorPreferenceCategory>

View File

@ -81,13 +81,4 @@
</im.vector.riotx.core.preference.VectorPreferenceCategory>
<im.vector.riotx.core.preference.VectorPreferenceDivider />
<im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_rageshake">
<im.vector.riotx.core.preference.VectorSwitchPreference
android:key="SETTINGS_USE_RAGE_SHAKE_KEY"
android:title="@string/send_bug_report_rage_shake" />
</im.vector.riotx.core.preference.VectorPreferenceCategory>
</androidx.preference.PreferenceScreen>