diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index b150f4c9c..a3880a6ad 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -19,6 +19,23 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.*; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_CONTROL_CENTER_SORTABLE; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ITEMS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_EXPOSE_HR_THIRDPARTY; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS_SORTABLE; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_END; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_OFF; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_SCHEDULED; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_START; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_SWIPE_UNLOCK; + import android.content.Context; import android.content.Intent; import android.media.AudioManager; @@ -43,10 +60,10 @@ import java.util.Set; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.AbstractPreferenceFragment; import nodomain.freeyourgadget.gadgetbridge.activities.CalBlacklistActivity; import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureContacts; import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureWorldClocks; -import nodomain.freeyourgadget.gadgetbridge.activities.AbstractPreferenceFragment; import nodomain.freeyourgadget.gadgetbridge.activities.app_specific_notifications.AppSpecificNotificationSettingsActivity; import nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsActivity; import nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst; @@ -61,30 +78,6 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.*; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_CONTROL_CENTER_SORTABLE; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_FELL_SLEEP_BROADCAST; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_FELL_SLEEP_SELECTIONS; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_SELECTION_BROADCAST; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_START_NON_WEAR_BROADCAST; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_START_NON_WEAR_SELECTIONS; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_WOKE_UP_BROADCAST; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_ACTION_WOKE_UP_SELECTIONS; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ITEMS; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_EXPOSE_HR_THIRDPARTY; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS_SORTABLE; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_END; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_OFF; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_SCHEDULED; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE_START; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_SWIPE_UNLOCK; - public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment implements DeviceSpecificSettingsHandler { private static final Logger LOG = LoggerFactory.getLogger(DeviceSpecificSettingsFragment.class); @@ -928,6 +921,7 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i setInputTypeFor(DeviceSettingsPreferenceConst.PREF_INACTIVITY_THRESHOLD, InputType.TYPE_CLASS_NUMBER); setInputTypeFor(DeviceSettingsPreferenceConst.PREF_DEVICE_GPS_UPDATE_INTERVAL, InputType.TYPE_CLASS_NUMBER); setInputTypeFor(DeviceSettingsPreferenceConst.PREF_BANGLEJS_TEXT_BITMAP_SIZE, InputType.TYPE_CLASS_NUMBER); + setInputTypeFor(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, InputType.TYPE_CLASS_NUMBER); new PasswordCapabilityImpl().registerPreferences(getContext(), coordinator.getPasswordCapability(), this); new HeartRateCapability().registerPreferences(getContext(), coordinator.getHeartRateMeasurementIntervals(), this); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsScreen.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsScreen.java index 542aad723..39df4ce33 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsScreen.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsScreen.java @@ -25,6 +25,7 @@ public enum DeviceSpecificSettingsScreen { AUDIO("pref_screen_audio", R.xml.devicesettings_root_audio), AUTHENTICATION("pref_screen_authentication", R.xml.devicesettings_root_authentication), CALENDAR("pref_screen_calendar", R.xml.devicesettings_root_calendar), + CALLS_AND_NOTIFICATIONS("pref_screen_calls_and_notifications", R.xml.devicesettings_root_calls_and_notifications), CONNECTION("pref_screen_connection", R.xml.devicesettings_root_connection), DEVELOPER("pref_screen_developer", R.xml.devicesettings_root_developer), DISPLAY("pref_screen_display", R.xml.devicesettings_root_display), diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java index 0c8ae52a6..e6a1ec6e0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java @@ -49,6 +49,8 @@ public class GalaxyBudsLiveDeviceCoordinator extends GalaxyBudsGenericCoordinato final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings(); final List audio = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.AUDIO); audio.add(R.xml.devicesettings_galaxy_buds_live); + final List callsAndNotif = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.CALLS_AND_NOTIFICATIONS); + callsAndNotif.add(R.xml.devicesettings_headphones); return deviceSpecificSettings; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java index 704c5f196..12f213e05 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java @@ -16,11 +16,11 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_2_NOISE_CONTROL; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOLUME; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_ANC_LEVEL; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_BALANCE; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_NOISE_CONTROL; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_2_NOISE_CONTROL; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_RIGHT; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java index 129f0403a..5d4ebcee2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java @@ -23,6 +23,7 @@ import androidx.annotation.NonNull; import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLClassicDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; @@ -74,10 +75,11 @@ public abstract class AbstractEarCoordinator extends AbstractBLClassicDeviceCoor } @Override - public int[] getSupportedDeviceSpecificSettings(GBDevice device) { - return new int[]{ - R.xml.devicesettings_nothing_ear1 - }; + public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) { + final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings(); + deviceSpecificSettings.addRootScreen(R.xml.devicesettings_nothing_ear1); + deviceSpecificSettings.addRootScreen(R.xml.devicesettings_headphones); + return deviceSpecificSettings; } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java index 0e5d19409..9deb19e96 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java @@ -17,9 +17,7 @@ package nodomain.freeyourgadget.gadgetbridge.devices.nothing; import android.os.Parcel; -import android.text.InputType; -import androidx.preference.EditTextPreference; import androidx.preference.ListPreference; import androidx.preference.Preference; @@ -76,22 +74,6 @@ public class EarSettingsCustomizer implements DeviceSpecificSettingsCustomizer { ((ListPreference) audioModePref).setEntryValues(entryValues.toArray(new CharSequence[0])); } } - final Preference autoReplyPref = handler.findPreference(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL); - final Preference autoReplyDelay = handler.findPreference(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY); - - if (autoReplyPref != null && autoReplyDelay != null) { - - autoReplyDelay.setEnabled(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL, false)); - - autoReplyPref.setOnPreferenceChangeListener((preference, newValue) -> { - autoReplyDelay.setEnabled((Boolean) newValue); - return true; - }); - - ((EditTextPreference) autoReplyDelay).setOnBindEditTextListener(editText -> editText.setInputType(InputType.TYPE_CLASS_NUMBER)); - - } - } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractHeadphoneDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractHeadphoneDeviceSupport.java new file mode 100644 index 000000000..75062aa36 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractHeadphoneDeviceSupport.java @@ -0,0 +1,135 @@ +/* Copyright (C) 2024 Arjan Schrijver, Daniele Gobbetti + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service; + +import android.content.SharedPreferences; +import android.os.Handler; +import android.os.Looper; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; +import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; +import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.util.GBTextToSpeech; + +public abstract class AbstractHeadphoneDeviceSupport extends AbstractSerialDeviceSupport { + private static final Logger LOG = LoggerFactory.getLogger(AbstractHeadphoneDeviceSupport.class); + private GBTextToSpeech gbTextToSpeech; + + @Override + public void onSetCallState(CallSpec callSpec) { + SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); + + if (!prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL, false)) + return; + + final int delayMillis = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, "15")) * 1000; + + if (CallSpec.CALL_INCOMING != callSpec.command) + return; + + if (!gbTextToSpeech.isConnected()) { // schedule the automatic reply here, if the speech to text is not connected. Else it's done by the callback, and the timeout starts after the name or number have been spoken + Looper mainLooper = Looper.getMainLooper(); + LOG.debug("Incoming call, scheduling auto answer in {} seconds.", delayMillis / 1000); + + new Handler(mainLooper).postDelayed(() -> { + GBDeviceEventCallControl callCmd = new GBDeviceEventCallControl(); + callCmd.event = GBDeviceEventCallControl.Event.ACCEPT; + evaluateGBDeviceEvent(callCmd); + }, delayMillis); //15s + + return; + } + String speechText = callSpec.name; + if (callSpec.name.equals(callSpec.number)) { + StringBuilder numberSpeller = new StringBuilder(); + for (char c : callSpec.number.toCharArray()) { + numberSpeller.append(c).append(" "); + } + speechText = numberSpeller.toString(); + } + gbTextToSpeech.speak(speechText); + + } + + @Override + public void onNotification(NotificationSpec notificationSpec) { + SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); + + if (!prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SPEAK_NOTIFICATIONS_ALOUD, false)) + return; + + if (gbTextToSpeech.isConnected()) { + + String notificationSpeller = new StringBuilder() + .append(notificationSpec.sourceName == null ? "" : notificationSpec.sourceName).append(". ") + .append(notificationSpec.title == null ? "" : notificationSpec.title).append(": ") + .append(notificationSpec.body == null ? "" : notificationSpec.body).toString(); + + + gbTextToSpeech.speakNotification(notificationSpeller); + + } + } + + @Override + public boolean connect() { + getDeviceIOThread().start(); + gbTextToSpeech = new GBTextToSpeech(getContext(), new UtteranceProgressListener()); + return true; + } + + @Override + public void dispose() { + gbTextToSpeech.shutdown(); + super.dispose(); + } + + private class UtteranceProgressListener extends android.speech.tts.UtteranceProgressListener { + @Override + public void onStart(String utteranceId) { +// LOG.debug("UtteranceProgressListener onStart."); + } + + @Override + public void onDone(String utteranceId) { +// LOG.debug("UtteranceProgressListener onDone."); + if (utteranceId.equals("call")) { + SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); + final int delayMillis = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, "15")) * 1000; + + + Looper mainLooper = Looper.getMainLooper(); + new Handler(mainLooper).postDelayed(() -> { + GBDeviceEventCallControl callCmd = new GBDeviceEventCallControl(); + callCmd.event = GBDeviceEventCallControl.Event.ACCEPT; + evaluateGBDeviceEvent(callCmd); + }, delayMillis); //15s + } + } + + @Override + public void onError(String utteranceId) { + LOG.error("UtteranceProgressListener returned error."); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsDeviceSupport.java index 43aa14318..135f21039 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsDeviceSupport.java @@ -16,23 +16,16 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.galaxy_buds; -import android.net.Uri; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.UUID; - -import nodomain.freeyourgadget.gadgetbridge.model.Alarm; -import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.service.AbstractHeadphoneDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread; import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol; -public class GalaxyBudsDeviceSupport extends AbstractSerialDeviceSupport { +public class GalaxyBudsDeviceSupport extends AbstractHeadphoneDeviceSupport { private static final Logger LOG = LoggerFactory.getLogger(GalaxyBudsDeviceSupport.class); - @Override public void onSendConfiguration(String config) { super.onSendConfiguration(config); @@ -43,12 +36,6 @@ public class GalaxyBudsDeviceSupport extends AbstractSerialDeviceSupport { super.onTestNewFunction(); } - @Override - public boolean connect() { - getDeviceIOThread().start(); - return true; - } - @Override public synchronized GalaxyBudsIOThread getDeviceIOThread() { return (GalaxyBudsIOThread) super.getDeviceIOThread(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/nothing/Ear1Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/nothing/Ear1Support.java index b972cc6c8..f0c8eb0f0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/nothing/Ear1Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/nothing/Ear1Support.java @@ -16,82 +16,15 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.nothing; -import android.content.SharedPreferences; -import android.os.Handler; -import android.os.Looper; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; -import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; -import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; -import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; -import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.service.AbstractHeadphoneDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread; import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol; -import nodomain.freeyourgadget.gadgetbridge.util.GBTextToSpeech; -public class Ear1Support extends AbstractSerialDeviceSupport { +public class Ear1Support extends AbstractHeadphoneDeviceSupport { private static final Logger LOG = LoggerFactory.getLogger(Ear1Support.class); - private GBTextToSpeech gbTextToSpeech; - - @Override - public void onSetCallState(CallSpec callSpec) { - SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); - - if (!prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL, false)) - return; - - final int delayMillis = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, "15")) * 1000; - - if (CallSpec.CALL_INCOMING != callSpec.command) - return; - - if (!gbTextToSpeech.isConnected()) { // schedule the automatic reply here, if the speech to text is not connected. Else it's done by the callback, and the timeout starts after the name or number have been spoken - Looper mainLooper = Looper.getMainLooper(); - LOG.debug("Incoming call, scheduling auto answer in {} seconds.", delayMillis / 1000); - - new Handler(mainLooper).postDelayed(() -> { - GBDeviceEventCallControl callCmd = new GBDeviceEventCallControl(); - callCmd.event = GBDeviceEventCallControl.Event.ACCEPT; - evaluateGBDeviceEvent(callCmd); - }, delayMillis); //15s - - return; - } - String speechText = callSpec.name; - if (callSpec.name.equals(callSpec.number)) { - StringBuilder numberSpeller = new StringBuilder(); - for (char c : callSpec.number.toCharArray()) { - numberSpeller.append(c).append(" "); - } - speechText = numberSpeller.toString(); - } - gbTextToSpeech.speak(speechText); - - } - - @Override - public void onNotification(NotificationSpec notificationSpec) { - SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); - - if (!prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SPEAK_NOTIFICATIONS_ALOUD, false)) - return; - - if (gbTextToSpeech.isConnected()) { - - String notificationSpeller = new StringBuilder() - .append(notificationSpec.sourceName == null ? "" : notificationSpec.sourceName).append(". ") - .append(notificationSpec.title == null ? "" : notificationSpec.title).append(": ") - .append(notificationSpec.body == null ? "" : notificationSpec.body).toString(); - - - gbTextToSpeech.speakNotification(notificationSpeller); - - } - } @Override public void onSendConfiguration(String config) { @@ -103,13 +36,6 @@ public class Ear1Support extends AbstractSerialDeviceSupport { //getDeviceIOThread().write(((NothingProtocol) getDeviceProtocol()).encodeBatteryStatusReq()); } - @Override - public boolean connect() { - getDeviceIOThread().start(); - gbTextToSpeech = new GBTextToSpeech(getContext(), new UtteranceProgressListener()); - return true; - } - @Override public synchronized NothingIOThread getDeviceIOThread() { return (NothingIOThread) super.getDeviceIOThread(); @@ -129,39 +55,4 @@ public class Ear1Support extends AbstractSerialDeviceSupport { return new NothingIOThread(getDevice(), getContext(), (NothingProtocol) getDeviceProtocol(), Ear1Support.this, getBluetoothAdapter()); } - - @Override - public void dispose() { - gbTextToSpeech.shutdown(); - super.dispose(); - } - - private class UtteranceProgressListener extends android.speech.tts.UtteranceProgressListener { - @Override - public void onStart(String utteranceId) { -// LOG.debug("UtteranceProgressListener onStart."); - } - - @Override - public void onDone(String utteranceId) { -// LOG.debug("UtteranceProgressListener onDone."); - if (utteranceId.equals("call")) { - SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); - final int delayMillis = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, "15")) * 1000; - - - Looper mainLooper = Looper.getMainLooper(); - new Handler(mainLooper).postDelayed(() -> { - GBDeviceEventCallControl callCmd = new GBDeviceEventCallControl(); - callCmd.event = GBDeviceEventCallControl.Event.ACCEPT; - evaluateGBDeviceEvent(callCmd); - }, delayMillis); //15s - } - } - - @Override - public void onError(String utteranceId) { - LOG.error("UtteranceProgressListener returned error."); - } - } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3222cb398..9f1947626 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2789,4 +2789,5 @@ Automatic Answer Delay Notifications will be read aloud through the headphones Speak Notifications Aloud + Calls and notifications diff --git a/app/src/main/res/xml/devicesettings_headphones.xml b/app/src/main/res/xml/devicesettings_headphones.xml new file mode 100644 index 000000000..2cc577471 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_headphones.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/devicesettings_nothing_ear1.xml b/app/src/main/res/xml/devicesettings_nothing_ear1.xml index ed237a404..3616079d2 100644 --- a/app/src/main/res/xml/devicesettings_nothing_ear1.xml +++ b/app/src/main/res/xml/devicesettings_nothing_ear1.xml @@ -15,24 +15,4 @@ android:key="pref_nothing_audiomode" android:summary="%s" android:title="@string/nothing_prefs_audiomode_title" /> - - - diff --git a/app/src/main/res/xml/devicesettings_root_calls_and_notifications.xml b/app/src/main/res/xml/devicesettings_root_calls_and_notifications.xml new file mode 100644 index 000000000..ed0aed4dc --- /dev/null +++ b/app/src/main/res/xml/devicesettings_root_calls_and_notifications.xml @@ -0,0 +1,9 @@ + + + + +