mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-01-25 00:57:33 +01:00
Sony Headphones: Implement Noise Cancelling Optimizer
This commit is contained in:
parent
e50fa36632
commit
d0f80eb5b4
@ -121,6 +121,10 @@ public class DeviceSettingsPreferenceConst {
|
||||
public static final String PREF_SONY_AMBIENT_SOUND_CONTROL = "pref_sony_ambient_sound_control";
|
||||
public static final String PREF_SONY_FOCUS_VOICE = "pref_sony_focus_voice";
|
||||
public static final String PREF_SONY_AMBIENT_SOUND_LEVEL = "pref_sony_ambient_sound_level";
|
||||
public static final String PREF_SONY_NOISE_OPTIMIZER_START = "pref_sony_noise_optimizer_start";
|
||||
public static final String PREF_SONY_NOISE_OPTIMIZER_CANCEL = "pref_sony_noise_optimizer_cancel";
|
||||
public static final String PREF_SONY_NOISE_OPTIMIZER_STATUS = "pref_sony_noise_optimizer_status";
|
||||
public static final String PREF_SONY_NOISE_OPTIMIZER_STATE_PRESSURE = "pref_sony_noise_optimizer_state_pressure";
|
||||
public static final String PREF_SONY_SOUND_POSITION = "pref_sony_sound_position";
|
||||
public static final String PREF_SONY_SURROUND_MODE = "pref_sony_surround_mode";
|
||||
public static final String PREF_SONY_EQUALIZER = "pref_sony_equalizer";
|
||||
|
@ -195,6 +195,19 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
getListView().post(runnable);
|
||||
}
|
||||
|
||||
/*
|
||||
* delayed execution so that the preferences are applied first
|
||||
*/
|
||||
@Override
|
||||
public void notifyPreferenceChanged(final String preferenceKey) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(preferenceKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setChangeListener() {
|
||||
final Prefs prefs = new Prefs(getPreferenceManager().getSharedPreferences());
|
||||
String disconnectNotificationState = prefs.getString(PREF_DISCONNECT_NOTIFICATION, PREF_DO_NOT_DISTURB_OFF);
|
||||
@ -206,12 +219,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
disconnectNotificationStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION_START);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_DISCONNECT_NOTIFICATION_START);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -223,12 +231,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
disconnectNotificationEnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION_END);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_DISCONNECT_NOTIFICATION_END);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -243,12 +246,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
|
||||
Objects.requireNonNull(disconnectNotificationStart).setEnabled(scheduled);
|
||||
Objects.requireNonNull(disconnectNotificationEnd).setEnabled(scheduled);
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_DISCONNECT_NOTIFICATION);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -264,12 +262,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
nightModeStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_NIGHT_MODE_START);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_NIGHT_MODE_START);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -281,12 +274,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
nightModeEnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_NIGHT_MODE_END);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_NIGHT_MODE_END);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -303,12 +291,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
Objects.requireNonNull(nightModeStart).setEnabled(scheduled);
|
||||
Objects.requireNonNull(nightModeEnd).setEnabled(scheduled);
|
||||
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_NIGHT_MODE);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_NIGHT_MODE);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -324,12 +307,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
doNotDisturbStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_DO_NOT_DISTURB_START);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_DO_NOT_DISTURB_START);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -341,12 +319,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
doNotDisturbEnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_DO_NOT_DISTURB_END);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_DO_NOT_DISTURB_END);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -362,12 +335,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
Objects.requireNonNull(doNotDisturbStart).setEnabled(scheduled);
|
||||
Objects.requireNonNull(doNotDisturbEnd).setEnabled(scheduled);
|
||||
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_DO_NOT_DISTURB);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_DO_NOT_DISTURB);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -495,12 +463,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
sleepTimeInfo.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_SLEEP_TIME);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_SLEEP_TIME);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -512,12 +475,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
sleepTimeStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_SLEEP_TIME_START);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_SLEEP_TIME_START);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -529,12 +487,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
sleepTimeEnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_SLEEP_TIME_END);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_SLEEP_TIME_END);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -551,12 +504,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
if (sleepTimeInfo != null) {
|
||||
//sleepTimeInfo.setEnabled(!PREF_DO_NOT_DISTURB_OFF.equals(newVal.toString()));
|
||||
}
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_SLEEP_TIME);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_SLEEP_TIME);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -570,12 +518,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
rotateWristCycleInfo.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -587,12 +530,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
displayOnLiftStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_DISPLAY_ON_LIFT_START);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_DISPLAY_ON_LIFT_START);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -604,12 +542,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
displayOnLiftEnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_DISPLAY_ON_LIFT_END);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_DISPLAY_ON_LIFT_END);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -626,12 +559,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
if (rotateWristCycleInfo != null) {
|
||||
rotateWristCycleInfo.setEnabled(!PREF_DO_NOT_DISTURB_OFF.equals(newVal.toString()));
|
||||
}
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_ACTIVATE_DISPLAY_ON_LIFT);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(PREF_ACTIVATE_DISPLAY_ON_LIFT);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -802,12 +730,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
if (pref != null) {
|
||||
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(preferenceKey);
|
||||
}
|
||||
});
|
||||
notifyPreferenceChanged(preferenceKey);
|
||||
|
||||
if (extraListener != null) {
|
||||
return extraListener.onPreferenceChange(preference, newVal);
|
||||
|
@ -39,6 +39,13 @@ public interface DeviceSpecificSettingsHandler {
|
||||
*/
|
||||
void addPreferenceHandlerFor(final String preferenceKey);
|
||||
|
||||
/**
|
||||
* Notify the device that a preference changed.
|
||||
*
|
||||
* @param preferenceKey the preference key.
|
||||
*/
|
||||
void notifyPreferenceChanged(final String preferenceKey);
|
||||
|
||||
/**
|
||||
* Adds a preference handler for a preference key. On change, this handler calls the provided extra listener, and then sends the preference to the device.
|
||||
*
|
||||
|
@ -28,12 +28,21 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BASS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MODE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_FOCUS_VOICE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_NOISE_OPTIMIZER_CANCEL;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_NOISE_OPTIMIZER_START;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_NOISE_OPTIMIZER_STATUS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_SOUND_POSITION;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_SURROUND_MODE;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.preference.EditTextPreference;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
@ -41,13 +50,17 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.NoiseCancellingOptimizerStatus;
|
||||
|
||||
public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsCustomizer {
|
||||
private ProgressDialog ancOptimizerProgressDialog;
|
||||
|
||||
final GBDevice device;
|
||||
|
||||
public SonyHeadphonesSettingsCustomizer(final GBDevice device) {
|
||||
@ -80,6 +93,24 @@ public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle ANC Optimizer status
|
||||
if (preference.getKey().equals(PREF_SONY_NOISE_OPTIMIZER_STATUS)) {
|
||||
final EditTextPreference optimizerStatusPreference = (EditTextPreference) preference;
|
||||
final NoiseCancellingOptimizerStatus optimizerStatus = NoiseCancellingOptimizerStatus.valueOf(optimizerStatusPreference.getText().toUpperCase(Locale.ROOT));
|
||||
|
||||
if (ancOptimizerProgressDialog != null) {
|
||||
switch (optimizerStatus) {
|
||||
case FINISHED:
|
||||
case NOT_RUNNING:
|
||||
ancOptimizerProgressDialog.dismiss();
|
||||
ancOptimizerProgressDialog = null;
|
||||
break;
|
||||
default:
|
||||
ancOptimizerProgressDialog.setMessage(optimizerStatus.i18n(preference.getContext()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -104,6 +135,54 @@ public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsC
|
||||
ambientSoundControlPrefListener.onPreferenceChange(ambientSoundControl, ambientSoundControl.getValue());
|
||||
handler.addPreferenceHandlerFor(PREF_SONY_AMBIENT_SOUND_CONTROL, ambientSoundControlPrefListener);
|
||||
}
|
||||
|
||||
// ANC Optimizer
|
||||
|
||||
final Preference ancOptimizer = handler.findPreference("pref_sony_anc_optimizer");
|
||||
|
||||
if (ancOptimizer != null) {
|
||||
ancOptimizer.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(final Preference preference) {
|
||||
if (ancOptimizerProgressDialog != null) {
|
||||
// Already optimizing
|
||||
return true;
|
||||
}
|
||||
|
||||
final Context context = preference.getContext();
|
||||
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.sony_anc_optimize_confirmation_title)
|
||||
.setMessage(R.string.sony_anc_optimize_confirmation_description)
|
||||
.setIcon(R.drawable.ic_hearing)
|
||||
.setPositiveButton(R.string.start, new DialogInterface.OnClickListener() {
|
||||
public void onClick(final DialogInterface dialog, final int whichButton) {
|
||||
handler.notifyPreferenceChanged(PREF_SONY_NOISE_OPTIMIZER_START);
|
||||
|
||||
ancOptimizerProgressDialog = new ProgressDialog(context);
|
||||
ancOptimizerProgressDialog.setCancelable(false);
|
||||
ancOptimizerProgressDialog.setMessage(context.getString(R.string.sony_anc_optimizer_status_starting));
|
||||
ancOptimizerProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
||||
ancOptimizerProgressDialog.setProgress(0);
|
||||
ancOptimizerProgressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.Cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
dialog.dismiss();
|
||||
ancOptimizerProgressDialog = null;
|
||||
handler.notifyPreferenceChanged(PREF_SONY_NOISE_OPTIMIZER_CANCEL);
|
||||
}
|
||||
});
|
||||
|
||||
ancOptimizerProgressDialog.show();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static final Creator<SonyHeadphonesSettingsCustomizer> CREATOR = new Creator<SonyHeadphonesSettingsCustomizer>() {
|
||||
|
@ -44,6 +44,7 @@ public class SonyWH1000XM3Coordinator extends SonyHeadphonesCoordinator {
|
||||
public int[] getSupportedDeviceSpecificSettings(final GBDevice device) {
|
||||
return new int[]{
|
||||
R.xml.devicesettings_sony_headphones_ambient_sound_control_wind_noise_reduction,
|
||||
R.xml.devicesettings_sony_headphones_anc_optimizer,
|
||||
R.xml.devicesettings_header_other,
|
||||
R.xml.devicesettings_sony_warning_wh1000xm3,
|
||||
R.xml.devicesettings_sony_headphones_equalizer,
|
||||
|
@ -45,6 +45,7 @@ public class SonyWH1000XM4Coordinator extends SonyHeadphonesCoordinator {
|
||||
return new int[]{
|
||||
// TODO: Function of [CUSTOM] button
|
||||
R.xml.devicesettings_sony_headphones_ambient_sound_control_wind_noise_reduction,
|
||||
R.xml.devicesettings_sony_headphones_anc_optimizer,
|
||||
R.xml.devicesettings_header_other,
|
||||
R.xml.devicesettings_sony_headphones_equalizer,
|
||||
R.xml.devicesettings_sony_headphones_audio_upsampling,
|
||||
|
@ -152,6 +152,12 @@ public class SonyHeadphonesProtocol extends GBDeviceProtocol {
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_LEVEL:
|
||||
configRequest = protocolImpl.setAmbientSoundControl(AmbientSoundControl.fromPreferences(prefs));
|
||||
break;
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_NOISE_OPTIMIZER_START:
|
||||
configRequest = protocolImpl.startNoiseCancellingOptimizer(true);
|
||||
break;
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_NOISE_OPTIMIZER_CANCEL:
|
||||
configRequest = protocolImpl.startNoiseCancellingOptimizer(false);
|
||||
break;
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_SOUND_POSITION:
|
||||
configRequest = protocolImpl.setSoundPosition(SoundPosition.fromPreferences(prefs));
|
||||
break;
|
||||
@ -211,10 +217,6 @@ public class SonyHeadphonesProtocol extends GBDeviceProtocol {
|
||||
public byte[] encodeTestNewFunction() {
|
||||
//return Request.fromHex(MessageType.COMMAND_1, "c40100").encode(sequenceNumber);
|
||||
|
||||
if (protocolImpl != null) {
|
||||
return protocolImpl.startNoiseCancellingOptimizer().encode(sequenceNumber);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,8 @@ public abstract class AbstractSonyProtocolImpl {
|
||||
|
||||
public abstract Request setAmbientSoundControl(final AmbientSoundControl config);
|
||||
|
||||
public abstract Request getNoiseCancellingOptimizerState();
|
||||
|
||||
public abstract Request getAudioCodec();
|
||||
|
||||
public abstract Request getBattery(final BatteryType batteryType);
|
||||
@ -94,7 +96,7 @@ public abstract class AbstractSonyProtocolImpl {
|
||||
|
||||
public abstract Request setVoiceNotifications(final VoiceNotifications config);
|
||||
|
||||
public abstract Request startNoiseCancellingOptimizer();
|
||||
public abstract Request startNoiseCancellingOptimizer(final boolean start);
|
||||
|
||||
public abstract Request powerOff();
|
||||
|
||||
|
@ -53,7 +53,12 @@ public enum PayloadType {
|
||||
AMBIENT_SOUND_CONTROL_SET(MessageType.COMMAND_1, 0x68),
|
||||
AMBIENT_SOUND_CONTROL_NOTIFY(MessageType.COMMAND_1, 0x69),
|
||||
|
||||
NOISE_CANCELLING_OPTIMIZER_START_REQUEST(MessageType.COMMAND_1, 0x84),
|
||||
NOISE_CANCELLING_OPTIMIZER_START(MessageType.COMMAND_1, 0x84),
|
||||
NOISE_CANCELLING_OPTIMIZER_STATUS(MessageType.COMMAND_1, 0x85),
|
||||
|
||||
NOISE_CANCELLING_OPTIMIZER_STATE_GET(MessageType.COMMAND_1, 0x86),
|
||||
NOISE_CANCELLING_OPTIMIZER_STATE_RET(MessageType.COMMAND_1, 0x87),
|
||||
NOISE_CANCELLING_OPTIMIZER_STATE_NOTIFY(MessageType.COMMAND_1, 0x89),
|
||||
|
||||
TOUCH_SENSOR_GET(MessageType.COMMAND_1, 0xd6),
|
||||
TOUCH_SENSOR_RET(MessageType.COMMAND_1, 0xd7),
|
||||
|
@ -16,6 +16,9 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_NOISE_OPTIMIZER_STATE_PRESSURE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_NOISE_OPTIMIZER_STATUS;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -53,6 +56,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.prot
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.AbstractSonyProtocolImpl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.AudioCodec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.BatteryType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.NoiseCancellingOptimizerStatus;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.VirtualSoundParam;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
@ -130,6 +134,17 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return new Request(PayloadType.AMBIENT_SOUND_CONTROL_SET.getMessageType(), buf.array());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request getNoiseCancellingOptimizerState() {
|
||||
return new Request(
|
||||
PayloadType.NOISE_CANCELLING_OPTIMIZER_STATE_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.NOISE_CANCELLING_OPTIMIZER_STATE_GET.getCode(),
|
||||
(byte) 0x01
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request getAudioCodec() {
|
||||
return new Request(
|
||||
@ -399,14 +414,14 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request startNoiseCancellingOptimizer() {
|
||||
public Request startNoiseCancellingOptimizer(final boolean start) {
|
||||
return new Request(
|
||||
PayloadType.NOISE_CANCELLING_OPTIMIZER_START_REQUEST.getMessageType(),
|
||||
PayloadType.NOISE_CANCELLING_OPTIMIZER_START.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.NOISE_CANCELLING_OPTIMIZER_START_REQUEST.getCode(),
|
||||
PayloadType.NOISE_CANCELLING_OPTIMIZER_START.getCode(),
|
||||
(byte) 0x01,
|
||||
(byte) 0x00,
|
||||
(byte) 0x01
|
||||
(byte) (start ? 0x01 : 0x00)
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -447,6 +462,11 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
case AMBIENT_SOUND_CONTROL_RET:
|
||||
case AMBIENT_SOUND_CONTROL_NOTIFY:
|
||||
return handleAmbientSoundControl(payload);
|
||||
case NOISE_CANCELLING_OPTIMIZER_STATUS:
|
||||
return handleNoiseCancellingOptimizerStatus(payload);
|
||||
case NOISE_CANCELLING_OPTIMIZER_STATE_RET:
|
||||
case NOISE_CANCELLING_OPTIMIZER_STATE_NOTIFY:
|
||||
return handleNoiseCancellingOptimizerState(payload);
|
||||
case TOUCH_SENSOR_RET:
|
||||
case TOUCH_SENSOR_NOTIFY:
|
||||
return handleTouchSensor(payload);
|
||||
@ -486,6 +506,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
capabilityRequests.add(getBattery(BatteryType.SINGLE));
|
||||
capabilityRequests.add(getAudioCodec());
|
||||
capabilityRequests.add(getAmbientSoundControl());
|
||||
capabilityRequests.add(getNoiseCancellingOptimizerState());
|
||||
capabilityRequests.add(getAudioUpsampling());
|
||||
capabilityRequests.add(getVoiceNotifications());
|
||||
capabilityRequests.add(getAutomaticPowerOff());
|
||||
@ -499,6 +520,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
capabilityRequests.add(getBattery(BatteryType.SINGLE));
|
||||
capabilityRequests.add(getAudioCodec());
|
||||
capabilityRequests.add(getAmbientSoundControl());
|
||||
capabilityRequests.add(getNoiseCancellingOptimizerState());
|
||||
capabilityRequests.add(getAudioUpsampling());
|
||||
capabilityRequests.add(getVoiceNotifications());
|
||||
capabilityRequests.add(getAutomaticPowerOff());
|
||||
@ -592,6 +614,50 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.singletonList(eventUpdatePreferences);
|
||||
}
|
||||
|
||||
public List<? extends GBDeviceEvent> handleNoiseCancellingOptimizerStatus(final byte[] payload) {
|
||||
if (payload.length != 4) {
|
||||
LOG.warn("Unexpected payload length {}", payload.length);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final NoiseCancellingOptimizerStatus status = NoiseCancellingOptimizerStatus.fromCode(payload[3]);
|
||||
|
||||
if (status == null) {
|
||||
LOG.warn("Unable to determine noise cancelling opptimizer status from {}", GB.hexdump(payload));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
LOG.info("Noise Cancelling Optimizer status: {}", status);
|
||||
|
||||
final GBDeviceEventUpdatePreferences event = new GBDeviceEventUpdatePreferences()
|
||||
.withPreference(PREF_SONY_NOISE_OPTIMIZER_STATUS, status.name().toLowerCase(Locale.ROOT));
|
||||
|
||||
return Collections.singletonList(event);
|
||||
}
|
||||
|
||||
public List<? extends GBDeviceEvent> handleNoiseCancellingOptimizerState(final byte[] payload) {
|
||||
// 89 01 01 01 01 0A
|
||||
if (payload.length != 6) {
|
||||
LOG.warn("Unexpected payload length {}", payload.length);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final float pressure = payload[5] / 10.0f;
|
||||
|
||||
if (pressure <= 0 || pressure > 1.0f) {
|
||||
LOG.warn("Invalid Noise Cancelling Optimizer pressure: {} atm, ignoring", pressure);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
LOG.info("Noise Cancelling Optimizer pressure: {} atm", pressure);
|
||||
|
||||
final GBDeviceEventUpdatePreferences event = new GBDeviceEventUpdatePreferences()
|
||||
.withPreference(PREF_SONY_NOISE_OPTIMIZER_STATE_PRESSURE, String.format(Locale.getDefault(), "%.2f atm", pressure));
|
||||
|
||||
return Collections.singletonList(event);
|
||||
}
|
||||
|
||||
|
||||
public List<? extends GBDeviceEvent> handleAudioUpsampling(final byte[] payload) {
|
||||
if (payload.length != 4) {
|
||||
LOG.warn("Unexpected payload length {}", payload.length);
|
||||
|
@ -0,0 +1,56 @@
|
||||
/* Copyright (C) 2021 José Rebelo
|
||||
|
||||
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 <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public enum NoiseCancellingOptimizerStatus {
|
||||
NOT_RUNNING(0x00),
|
||||
WEARING_CONDITION(0x01),
|
||||
ATMOSPHERIC_PRESSURE(0x02),
|
||||
ANALYZING(0x10),
|
||||
FINISHED(0x11),
|
||||
;
|
||||
|
||||
private final byte code;
|
||||
|
||||
NoiseCancellingOptimizerStatus(final int code) {
|
||||
this.code = (byte) code;
|
||||
}
|
||||
|
||||
public byte getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public static NoiseCancellingOptimizerStatus fromCode(final byte code) {
|
||||
for (final NoiseCancellingOptimizerStatus audioCodec : values()) {
|
||||
if (audioCodec.code == code) {
|
||||
return audioCodec;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String i18n(final Context context) {
|
||||
final String stringName = String.format("sony_anc_optimizer_status_%s", name().toLowerCase(Locale.ROOT));
|
||||
final int stringId = context.getResources().getIdentifier(stringName, "string", context.getPackageName());
|
||||
return context.getString(stringId);
|
||||
}
|
||||
}
|
5
app/src/main/res/drawable/ic_auto_awesome.xml
Normal file
5
app/src/main/res/drawable/ic_auto_awesome.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:tint="#7E7E7E"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M19,9l1.25,-2.75L23,5l-2.75,-1.25L19,1l-1.25,2.75L15,5l2.75,1.25L19,9zM11.5,9.5L9,4 6.5,9.5 1,12l5.5,2.5L9,20l2.5,-5.5L17,12l-5.5,-2.5zM19,15l-1.25,2.75L15,19l2.75,1.25L19,23l1.25,-2.75L23,19l-2.75,-1.25L19,15z"/>
|
||||
</vector>
|
5
app/src/main/res/drawable/ic_pressure.xml
Normal file
5
app/src/main/res/drawable/ic_pressure.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:tint="#7E7E7E"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M20.38,8.57l-1.23,1.85a8,8 0,0 1,-0.22 7.58L5.07,18A8,8 0,0 1,15.58 6.85l1.85,-1.23A10,10 0,0 0,3.35 19a2,2 0,0 0,1.72 1h13.85a2,2 0,0 0,1.74 -1,10 10,0 0,0 -0.27,-10.44zM10.59,15.41a2,2 0,0 0,2.83 0l5.66,-8.49 -8.49,5.66a2,2 0,0 0,0 2.83z"/>
|
||||
</vector>
|
@ -355,6 +355,7 @@
|
||||
<string name="connected">Connected</string>
|
||||
<string name="unknown_state">Unknown state</string>
|
||||
<string name="_unknown_">(unknown)</string>
|
||||
<string name="unknown">Unknown</string>
|
||||
<string name="test">Test</string>
|
||||
<string name="test_notification">Test notification</string>
|
||||
<string name="this_is_a_test_notification_from_gadgetbridge">This is a test notification from Gadgetbridge</string>
|
||||
@ -771,6 +772,7 @@
|
||||
<string name="Cancel">Cancel</string>
|
||||
<string name="Delete">Delete</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="set">Set</string>
|
||||
<string name="activity_data_management_directory_content_title">Export/Import directory content</string>
|
||||
<string name="activity_DB_ShowContentButton">Show Export/Import directory content</string>
|
||||
@ -1393,6 +1395,12 @@
|
||||
<string name="sony_ambient_sound_ambient_sound">Ambient Sound</string>
|
||||
<string name="sony_ambient_sound_focus_voice">Focus on Voice</string>
|
||||
<string name="sony_ambient_sound_level">Ambient Sound Level</string>
|
||||
<string name="pref_header_sony_anc_optimizer">Noise Cancelling Optimizer</string>
|
||||
<string name="sony_anc_optimize_title">Optimize</string>
|
||||
<string name="sony_anc_optimize_description">Click to start the noise cancelling optimizer.</string>
|
||||
<string name="sony_anc_optimize_confirmation_title">Noise Cancelling Optimizer</string>
|
||||
<string name="sony_anc_optimize_confirmation_description">Use the headphones as you normally would. If the wearing condition or atmospheric pressure change, run the optimizer again.</string>
|
||||
<string name="pref_anc_optimizer_state_pressure">Atmospheric pressure</string>
|
||||
<string name="sony_sound_position">Sound Position</string>
|
||||
<string name="sony_sound_position_off">Off</string>
|
||||
<string name="sony_sound_position_front">Front</string>
|
||||
@ -1408,6 +1416,12 @@
|
||||
<string name="sony_surround_mode_concert_hall">Concert Hall</string>
|
||||
<string name="sony_warn_sbc_codec">Warning: The equalizer, audio position and surround settings only work for the SBC audio codec.</string>
|
||||
<string name="sony_equalizer">Equalizer</string>
|
||||
<string name="sony_anc_optimizer_status_starting">Starting…</string>
|
||||
<string name="sony_anc_optimizer_status_not_running">Not Running</string>
|
||||
<string name="sony_anc_optimizer_status_wearing_condition">Measuring wearing condition…</string>
|
||||
<string name="sony_anc_optimizer_status_atmospheric_pressure">Measuring atmostpheric pressure…</string>
|
||||
<string name="sony_anc_optimizer_status_analyzing">Analyzing…</string>
|
||||
<string name="sony_anc_optimizer_status_finished">Finishing…</string>
|
||||
<string name="sony_equalizer_preset_off">Off</string>
|
||||
<string name="sony_equalizer_preset_bright">Bright</string>
|
||||
<string name="sony_equalizer_preset_excited">Excited</string>
|
||||
|
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<PreferenceCategory
|
||||
android:key="pref_key_header_sony_anc_optimizer"
|
||||
android:title="@string/pref_header_sony_anc_optimizer">
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="@string/unknown"
|
||||
android:enabled="false"
|
||||
android:icon="@drawable/ic_pressure"
|
||||
android:key="pref_sony_noise_optimizer_state_pressure"
|
||||
android:shouldDisableView="false"
|
||||
android:title="@string/pref_anc_optimizer_state_pressure"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
<Preference
|
||||
android:icon="@drawable/ic_auto_awesome"
|
||||
android:key="pref_sony_anc_optimizer"
|
||||
android:summary="@string/sony_anc_optimize_description"
|
||||
android:title="@string/sony_anc_optimize_title" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="NOT_RUNNING"
|
||||
android:enabled="false"
|
||||
android:key="pref_sony_noise_optimizer_status"
|
||||
android:shouldDisableView="false"
|
||||
android:title="pref_sony_noise_optimizer_status"
|
||||
app:isPreferenceVisible="false" />
|
||||
</PreferenceCategory>
|
||||
</androidx.preference.PreferenceScreen>
|
Loading…
x
Reference in New Issue
Block a user