From 9b889d232fa78a621a2a07f58ebf7fcf1c9fd23d Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 31 Jan 2022 16:01:15 +0100 Subject: [PATCH 01/17] add UI to switch audio output in call Signed-off-by: Marcel Hibbe --- .../talk/activities/CallActivity.java | 37 +++-- .../talk/ui/dialog/AudioOutputDialog.kt | 77 ++++++++++ .../ic_baseline_bluetooth_audio_24.xml | 10 ++ .../drawable/ic_baseline_phone_in_talk_24.xml | 10 ++ app/src/main/res/layout/call_activity.xml | 2 +- .../main/res/layout/dialog_audio_output.xml | 141 ++++++++++++++++++ app/src/main/res/values/strings.xml | 4 + 7 files changed, 268 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt create mode 100644 app/src/main/res/drawable/ic_baseline_bluetooth_audio_24.xml create mode 100644 app/src/main/res/drawable/ic_baseline_phone_in_talk_24.xml create mode 100644 app/src/main/res/layout/dialog_audio_output.xml diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index 7bee5a77b..f79298f5b 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -32,6 +32,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; import android.graphics.Color; +import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.media.AudioAttributes; import android.media.MediaPlayer; @@ -82,6 +83,8 @@ import com.nextcloud.talk.models.json.signaling.Signaling; import com.nextcloud.talk.models.json.signaling.SignalingOverall; import com.nextcloud.talk.models.json.signaling.settings.IceServer; import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall; +import com.nextcloud.talk.ui.dialog.AudioOutputDialog; +import com.nextcloud.talk.ui.dialog.ScopeDialog; import com.nextcloud.talk.utils.ApiUtils; import com.nextcloud.talk.utils.DisplayUtils; import com.nextcloud.talk.utils.NotificationUtils; @@ -142,6 +145,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.drawable.DrawableCompat; import autodagger.AutoInjector; import io.reactivex.Observable; import io.reactivex.Observer; @@ -327,16 +331,20 @@ public class CallActivity extends CallBaseActivity { private void initClickListeners() { binding.pictureInPictureButton.setOnClickListener(l -> enterPipMode()); - binding.speakerButton.setOnClickListener(l -> { - if (audioManager != null) { - audioManager.toggleUseSpeakerphone(); - if (audioManager.isSpeakerphoneAutoOn()) { - binding.speakerButton.getHierarchy().setPlaceholderImage(R.drawable.ic_volume_up_white_24dp); - } else { - binding.speakerButton.getHierarchy().setPlaceholderImage(R.drawable.ic_volume_mute_white_24dp); - } - } - }); + binding.audioOutputButton.setOnClickListener(v -> new AudioOutputDialog( + this + ).show()); + +// binding.audioOutputButton.setOnClickListener(l -> { +// if (audioManager != null) { +// audioManager.toggleUseSpeakerphone(); +// if (audioManager.isSpeakerphoneAutoOn()) { +// binding.audioOutputButton.getHierarchy().setPlaceholderImage(R.drawable.ic_volume_up_white_24dp); +// } else { +// binding.audioOutputButton.getHierarchy().setPlaceholderImage(R.drawable.ic_volume_mute_white_24dp); +// } +// } +// }); binding.microphoneButton.setOnClickListener(l -> onMicrophoneClick()); binding.microphoneButton.setOnLongClickListener(l -> { @@ -373,6 +381,11 @@ public class CallActivity extends CallBaseActivity { }); } + public void setAudioOutputIcon(Drawable drawable){ + binding.audioOutputButton.getHierarchy().setPlaceholderImage(drawable); + DrawableCompat.setTint(drawable, Color.WHITE); + } + private void createCameraEnumerator() { boolean camera2EnumeratorIsSupported = false; try { @@ -496,7 +509,7 @@ public class CallActivity extends CallBaseActivity { } if (isVoiceOnlyCall) { - binding.speakerButton.setVisibility(View.VISIBLE); + binding.audioOutputButton.setVisibility(View.VISIBLE); binding.switchSelfVideoButton.setVisibility(View.GONE); binding.cameraButton.setVisibility(View.GONE); binding.selfVideoRenderer.setVisibility(View.GONE); @@ -513,7 +526,7 @@ public class CallActivity extends CallBaseActivity { params.setMargins(0, 0, 0, 0); binding.gridview.setLayoutParams(params); - binding.speakerButton.setVisibility(View.GONE); + binding.audioOutputButton.setVisibility(View.GONE); if (cameraEnumerator.getDeviceNames().length < 2) { binding.switchSelfVideoButton.setVisibility(View.GONE); } diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt new file mode 100644 index 000000000..c8d4cfb2a --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt @@ -0,0 +1,77 @@ +/* + * Nextcloud Talk application + * + * @author Marcel Hibbe + * @author Andy Scherzinger + * Copyright (C) 2021 Marcel Hibbe + * Copyright (C) 2021 Andy Scherzinger + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.nextcloud.talk.ui.dialog + +import android.os.Bundle +import android.util.Log +import android.view.View +import android.view.ViewGroup +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog +import com.nextcloud.talk.R +import com.nextcloud.talk.activities.CallActivity +import com.nextcloud.talk.databinding.DialogAudioOutputBinding + +class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(callActivity) { + + private lateinit var dialogAudioOutputBinding: DialogAudioOutputBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + dialogAudioOutputBinding = DialogAudioOutputBinding.inflate(layoutInflater) + setContentView(dialogAudioOutputBinding.root) + window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + + + dialogAudioOutputBinding.audioOutputBluetooth.setOnClickListener { + Log.d(TAG, "bluetooth button clicked") + callActivity.setAudioOutputIcon(dialogAudioOutputBinding.audioOutputBluetoothIcon.drawable) + dismiss() + } + + dialogAudioOutputBinding.audioOutputSpeaker.setOnClickListener { + Log.d(TAG, "speaker button clicked") + callActivity.setAudioOutputIcon(dialogAudioOutputBinding.audioOutputSpeakerIcon.drawable) + + dismiss() + } + + dialogAudioOutputBinding.audioOutputEarspeaker.setOnClickListener { + Log.d(TAG, "earspeaker button clicked") + callActivity.setAudioOutputIcon(dialogAudioOutputBinding.audioOutputEarspeakerIcon.drawable) + + dismiss() + } + } + + override fun onStart() { + super.onStart() + val bottomSheet = findViewById(R.id.design_bottom_sheet) + val behavior = BottomSheetBehavior.from(bottomSheet as View) + behavior.state = BottomSheetBehavior.STATE_EXPANDED + } + + companion object { + private const val TAG = "AudioOutputDialog" + } +} diff --git a/app/src/main/res/drawable/ic_baseline_bluetooth_audio_24.xml b/app/src/main/res/drawable/ic_baseline_bluetooth_audio_24.xml new file mode 100644 index 000000000..3ac2dc4d6 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_bluetooth_audio_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_phone_in_talk_24.xml b/app/src/main/res/drawable/ic_baseline_phone_in_talk_24.xml new file mode 100644 index 000000000..42e266da8 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_phone_in_talk_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/call_activity.xml b/app/src/main/res/layout/call_activity.xml index ca1c5ddbe..310e1cba1 100644 --- a/app/src/main/res/layout/call_activity.xml +++ b/app/src/main/res/layout/call_activity.xml @@ -153,7 +153,7 @@ app:roundAsCircle="true" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 94ca857b3..00e94ad71 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -494,5 +494,9 @@ Send Error taking picture Taking a photo is not possible without permissions + Bluetooth + Speaker + Phone + Audio output From 9c0fa9acc2489d6d5f3cbe22c704463cd408c219 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 1 Feb 2022 00:42:44 +0100 Subject: [PATCH 02/17] select audio device (WIP) Signed-off-by: Marcel Hibbe --- .../talk/activities/CallActivity.java | 47 +++-- .../talk/ui/dialog/AudioOutputDialog.kt | 13 +- .../talk/webrtc/MagicAudioManager.java | 160 +++++------------- 3 files changed, 77 insertions(+), 143 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index f79298f5b..02027eba7 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -32,7 +32,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; import android.graphics.Color; -import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.media.AudioAttributes; import android.media.MediaPlayer; @@ -84,7 +83,6 @@ import com.nextcloud.talk.models.json.signaling.SignalingOverall; import com.nextcloud.talk.models.json.signaling.settings.IceServer; import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall; import com.nextcloud.talk.ui.dialog.AudioOutputDialog; -import com.nextcloud.talk.ui.dialog.ScopeDialog; import com.nextcloud.talk.utils.ApiUtils; import com.nextcloud.talk.utils.DisplayUtils; import com.nextcloud.talk.utils.NotificationUtils; @@ -145,6 +143,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.content.res.AppCompatResources; import androidx.core.graphics.drawable.DrawableCompat; import autodagger.AutoInjector; import io.reactivex.Observable; @@ -335,17 +334,6 @@ public class CallActivity extends CallBaseActivity { this ).show()); -// binding.audioOutputButton.setOnClickListener(l -> { -// if (audioManager != null) { -// audioManager.toggleUseSpeakerphone(); -// if (audioManager.isSpeakerphoneAutoOn()) { -// binding.audioOutputButton.getHierarchy().setPlaceholderImage(R.drawable.ic_volume_up_white_24dp); -// } else { -// binding.audioOutputButton.getHierarchy().setPlaceholderImage(R.drawable.ic_volume_mute_white_24dp); -// } -// } -// }); - binding.microphoneButton.setOnClickListener(l -> onMicrophoneClick()); binding.microphoneButton.setOnLongClickListener(l -> { if (!microphoneOn) { @@ -381,9 +369,31 @@ public class CallActivity extends CallBaseActivity { }); } - public void setAudioOutputIcon(Drawable drawable){ - binding.audioOutputButton.getHierarchy().setPlaceholderImage(drawable); - DrawableCompat.setTint(drawable, Color.WHITE); + public void setAudioOutputChannel(MagicAudioManager.AudioDevice audioDevice) { + if (audioManager == null) { + return; + } + + audioManager.selectAudioDevice(audioDevice); + + switch (audioManager.getResultingAudioDevice()) { + case BLUETOOTH: + binding.audioOutputButton.getHierarchy().setPlaceholderImage( + AppCompatResources.getDrawable(context, R.drawable.ic_baseline_bluetooth_audio_24)); + break; + case SPEAKER_PHONE: + binding.audioOutputButton.getHierarchy().setPlaceholderImage( + AppCompatResources.getDrawable(context, R.drawable.ic_volume_up_white_24dp)); + break; + case EARPIECE: + binding.audioOutputButton.getHierarchy().setPlaceholderImage( + AppCompatResources.getDrawable(context, R.drawable.ic_baseline_phone_in_talk_24)); + break; + default: + Log.e(TAG, "Invalid audio device selection"); + break; + } + DrawableCompat.setTint(binding.audioOutputButton.getDrawable(), Color.WHITE); } private void createCameraEnumerator() { @@ -391,7 +401,7 @@ public class CallActivity extends CallBaseActivity { try { camera2EnumeratorIsSupported = Camera2Enumerator.isSupported(this); } catch (final Throwable throwable) { - Log.w(TAG, "Camera2Enumator threw an error"); + Log.w(TAG, "Camera2Enumerator threw an error"); } if (camera2EnumeratorIsSupported) { @@ -726,7 +736,8 @@ public class CallActivity extends CallBaseActivity { } private void onAudioManagerDevicesChanged( - final MagicAudioManager.AudioDevice device, final Set availableDevices) { + final MagicAudioManager.AudioDevice device, + final Set availableDevices) { Log.d(TAG, "onAudioManagerDevicesChanged: " + availableDevices + ", " + "selected: " + device); diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt index c8d4cfb2a..eaf999a53 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt @@ -23,7 +23,6 @@ package com.nextcloud.talk.ui.dialog import android.os.Bundle -import android.util.Log import android.view.View import android.view.ViewGroup import com.google.android.material.bottomsheet.BottomSheetBehavior @@ -31,6 +30,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog import com.nextcloud.talk.R import com.nextcloud.talk.activities.CallActivity import com.nextcloud.talk.databinding.DialogAudioOutputBinding +import com.nextcloud.talk.webrtc.MagicAudioManager class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(callActivity) { @@ -44,22 +44,17 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call dialogAudioOutputBinding.audioOutputBluetooth.setOnClickListener { - Log.d(TAG, "bluetooth button clicked") - callActivity.setAudioOutputIcon(dialogAudioOutputBinding.audioOutputBluetoothIcon.drawable) + callActivity.setAudioOutputChannel(MagicAudioManager.AudioDevice.BLUETOOTH) dismiss() } dialogAudioOutputBinding.audioOutputSpeaker.setOnClickListener { - Log.d(TAG, "speaker button clicked") - callActivity.setAudioOutputIcon(dialogAudioOutputBinding.audioOutputSpeakerIcon.drawable) - + callActivity.setAudioOutputChannel(MagicAudioManager.AudioDevice.SPEAKER_PHONE) dismiss() } dialogAudioOutputBinding.audioOutputEarspeaker.setOnClickListener { - Log.d(TAG, "earspeaker button clicked") - callActivity.setAudioOutputIcon(dialogAudioOutputBinding.audioOutputEarspeakerIcon.drawable) - + callActivity.setAudioOutputChannel(MagicAudioManager.AudioDevice.EARPIECE) dismiss() } } diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java b/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java index 7eba93239..7d640591f 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java @@ -55,13 +55,9 @@ import java.util.Set; */ public class MagicAudioManager { private static final String TAG = "MagicAudioManager"; - private static final String SPEAKERPHONE_AUTO = "auto"; - private static final String SPEAKERPHONE_FALSE = "false"; private final Context magicContext; - // Handles all tasks related to Bluetooth headset devices. private final MagicBluetoothManager bluetoothManager; - // Contains speakerphone setting: auto, true or false - private String useSpeakerphone; + private boolean controlSpeakerByProximitySensor; private AudioManager audioManager; private AudioManagerEvents audioManagerEvents; private AudioManagerState amState; @@ -69,31 +65,15 @@ public class MagicAudioManager { private boolean savedIsSpeakerPhoneOn = false; private boolean savedIsMicrophoneMute = false; private boolean hasWiredHeadset = false; - // Default audio device; speaker phone for video calls or earpiece for audio - // only calls. - private AudioDevice defaultAudioDevice; - // Contains the currently selected audio device. - // This device is changed automatically using a certain scheme where e.g. - // a wired headset "wins" over speaker phone. It is also possible for a - // user to explicitly select a device (and overrid any predefined scheme). - // See |userSelectedAudioDevice| for details. - private AudioDevice selectedAudioDevice; - // Contains the user-selected audio device which overrides the predefined - // selection scheme. - // TODO(henrika): always set to AudioDevice.NONE today. Add support for - // explicit selection based on choice by userSelectedAudioDevice. + private AudioDevice userSelectedAudioDevice; - // Proximity sensor object. It measures the proximity of an object in cm - // relative to the view screen of a device and can therefore be used to - // assist device switching (close to ear <=> use headset earpiece if - // available, far from ear <=> use speaker phone). + private AudioDevice resultingAudioDevice; + private MagicProximitySensor proximitySensor = null; - // Contains a list of available audio devices. A Set collection is used to - // avoid duplicate elements. + private Set audioDevices = new HashSet<>(); - // Broadcast receiver for wired headset intent broadcasts. + private BroadcastReceiver wiredHeadsetReceiver; - // Callback method for changes in audio focus. private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener; private PowerManagerUtils powerManagerUtils; @@ -110,18 +90,8 @@ public class MagicAudioManager { powerManagerUtils = new PowerManagerUtils(); powerManagerUtils.updatePhoneState(PowerManagerUtils.PhoneState.WITH_PROXIMITY_SENSOR_LOCK); - if (useProximitySensor) { - useSpeakerphone = SPEAKERPHONE_AUTO; - } else { - useSpeakerphone = SPEAKERPHONE_FALSE; - } - - - if (useSpeakerphone.equals(SPEAKERPHONE_FALSE)) { - defaultAudioDevice = AudioDevice.EARPIECE; - } else { - defaultAudioDevice = AudioDevice.SPEAKER_PHONE; - } + controlSpeakerByProximitySensor = useProximitySensor; + updateAudioDeviceState(); // Create and initialize the proximity sensor. // Tablet devices (e.g. Nexus 7) does not support proximity sensors. @@ -134,8 +104,6 @@ public class MagicAudioManager { onProximitySensorChangedState(); } }); - - Log.d(TAG, "defaultAudioDevice: " + defaultAudioDevice); } /** @@ -145,29 +113,13 @@ public class MagicAudioManager { return new MagicAudioManager(context, useProximitySensor); } - public void toggleUseSpeakerphone() { - if (useSpeakerphone.equals(SPEAKERPHONE_FALSE)) { - useSpeakerphone = SPEAKERPHONE_AUTO; - setDefaultAudioDevice(AudioDevice.SPEAKER_PHONE); - } else { - useSpeakerphone = SPEAKERPHONE_FALSE; - setDefaultAudioDevice(AudioDevice.EARPIECE); - } - - updateAudioDeviceState(); - } - - public boolean isSpeakerphoneAutoOn() { - return (useSpeakerphone.equals(SPEAKERPHONE_AUTO)); - } - /** * This method is called when the proximity sensor reports a state change, * e.g. from "NEAR to FAR" or from "FAR to NEAR". */ private void onProximitySensorChangedState() { - if (!useSpeakerphone.equals(SPEAKERPHONE_AUTO)) { + if (!controlSpeakerByProximitySensor) { return; } @@ -274,7 +226,7 @@ public class MagicAudioManager { // Set initial device states. userSelectedAudioDevice = AudioDevice.NONE; - selectedAudioDevice = AudioDevice.NONE; + resultingAudioDevice = AudioDevice.NONE; audioDevices.clear(); // Initialize and start Bluetooth if a BT device is available or initiate @@ -355,35 +307,10 @@ public class MagicAudioManager { Log.e(TAG, "Invalid audio device selection"); break; } - selectedAudioDevice = device; + resultingAudioDevice = device; } } - /** - * Changes default audio device. - * TODO(henrika): add usage of this method in the AppRTCMobile client. - */ - public void setDefaultAudioDevice(AudioDevice defaultDevice) { - ThreadUtils.checkIsOnMainThread(); - switch (defaultDevice) { - case SPEAKER_PHONE: - defaultAudioDevice = defaultDevice; - break; - case EARPIECE: - if (hasEarpiece()) { - defaultAudioDevice = defaultDevice; - } else { - defaultAudioDevice = AudioDevice.SPEAKER_PHONE; - } - break; - default: - Log.e(TAG, "Invalid default audio device selection"); - break; - } - Log.d(TAG, "setDefaultAudioDevice(device=" + defaultAudioDevice + ")"); - updateAudioDeviceState(); - } - /** * Changes selection of the currently active audio device. */ @@ -392,7 +319,15 @@ public class MagicAudioManager { if (!audioDevices.contains(device)) { Log.e(TAG, "Can not select " + device + " from available " + audioDevices); } + userSelectedAudioDevice = device; + + if (device == AudioDevice.SPEAKER_PHONE) { + controlSpeakerByProximitySensor = true; + } else { + controlSpeakerByProximitySensor = false; + } + updateAudioDeviceState(); } @@ -407,9 +342,9 @@ public class MagicAudioManager { /** * Returns the currently selected audio device. */ - public AudioDevice getSelectedAudioDevice() { + public AudioDevice getResultingAudioDevice() { ThreadUtils.checkIsOnMainThread(); - return selectedAudioDevice; + return resultingAudioDevice; } /** @@ -482,10 +417,6 @@ public class MagicAudioManager { } } - /** - * Updates list of possible audio devices and make new device selection. - * TODO(henrika): add unit test to verify all state transitions. - */ public void updateAudioDeviceState() { ThreadUtils.checkIsOnMainThread(); Log.d(TAG, "--- updateAudioDeviceState: " @@ -493,19 +424,18 @@ public class MagicAudioManager { + "BT state=" + bluetoothManager.getState()); Log.d(TAG, "Device status: " + "available=" + audioDevices + ", " - + "selected=" + selectedAudioDevice + ", " + + "resulting(current)=" + resultingAudioDevice + ", " + "user selected=" + userSelectedAudioDevice); - // Check if any Bluetooth headset is connected. The internal BT state will - // change accordingly. - // TODO(henrika): perhaps wrap required state into BT manager. + + + if (bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_AVAILABLE || bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_UNAVAILABLE || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_DISCONNECTING) { bluetoothManager.updateDevice(); } - // Update the set of available audio devices. Set newAudioDevices = new HashSet<>(); if (bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTED @@ -518,34 +448,32 @@ public class MagicAudioManager { // If a wired headset is connected, then it is the only possible option. newAudioDevices.add(AudioDevice.WIRED_HEADSET); } else { - // No wired headset, hence the audio-device list can contain speaker - // phone (on a tablet), or speaker phone and earpiece (on mobile phone). newAudioDevices.add(AudioDevice.SPEAKER_PHONE); if (hasEarpiece()) { newAudioDevices.add(AudioDevice.EARPIECE); } } - // Store state which is set to true if the device list has changed. + boolean audioDeviceSetUpdated = !audioDevices.equals(newAudioDevices); - // Update the existing audio device set. audioDevices = newAudioDevices; + + + // Correct user selected audio devices if needed. - if (bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_UNAVAILABLE - && userSelectedAudioDevice == AudioDevice.BLUETOOTH) { - // If BT is not available, it can't be the user selection. + if (userSelectedAudioDevice == AudioDevice.BLUETOOTH + && bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_UNAVAILABLE) { userSelectedAudioDevice = AudioDevice.NONE; } - if (hasWiredHeadset && userSelectedAudioDevice == AudioDevice.SPEAKER_PHONE) { - // If user selected speaker phone, but then plugged wired headset then make - // wired headset as user selected device. + if (userSelectedAudioDevice == AudioDevice.SPEAKER_PHONE && hasWiredHeadset) { userSelectedAudioDevice = AudioDevice.WIRED_HEADSET; } - if (!hasWiredHeadset && userSelectedAudioDevice == AudioDevice.WIRED_HEADSET) { - // If user selected wired headset, but then unplugged wired headset then make - // speaker phone as user selected device. + if (userSelectedAudioDevice == AudioDevice.WIRED_HEADSET && !hasWiredHeadset) { userSelectedAudioDevice = AudioDevice.SPEAKER_PHONE; } + + + // Need to start Bluetooth if it is available and user either selected it explicitly or // user did not select any output device. boolean needBluetoothAudioStart = @@ -586,34 +514,34 @@ public class MagicAudioManager { // Update selected audio device. - AudioDevice newAudioDevice = selectedAudioDevice; + AudioDevice newResultingAudioDevice; if (bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTED) { // If a Bluetooth is connected, then it should be used as output audio // device. Note that it is not sufficient that a headset is available; // an active SCO channel must also be up and running. - newAudioDevice = AudioDevice.BLUETOOTH; + newResultingAudioDevice = AudioDevice.BLUETOOTH; } else if (hasWiredHeadset) { // If a wired headset is connected, but Bluetooth is not, then wired headset is used as // audio device. - newAudioDevice = AudioDevice.WIRED_HEADSET; + newResultingAudioDevice = AudioDevice.WIRED_HEADSET; } else { // No wired headset and no Bluetooth, hence the audio-device list can contain speaker // phone (on a tablet), or speaker phone and earpiece (on mobile phone). // |defaultAudioDevice| contains either AudioDevice.SPEAKER_PHONE or AudioDevice.EARPIECE // depending on the user's selection. - newAudioDevice = defaultAudioDevice; + newResultingAudioDevice = userSelectedAudioDevice; } // Switch to new device but only if there has been any changes. - if (newAudioDevice != selectedAudioDevice || audioDeviceSetUpdated) { + if (newResultingAudioDevice != resultingAudioDevice || audioDeviceSetUpdated) { // Do the required device switch. - setAudioDeviceInternal(newAudioDevice); + setAudioDeviceInternal(newResultingAudioDevice); Log.d(TAG, "New device status: " + "available=" + audioDevices + ", " - + "selected=" + newAudioDevice); + + "resulting(new)=" + newResultingAudioDevice); if (audioManagerEvents != null) { // Notify a listening client that audio device has been changed. - audioManagerEvents.onAudioDeviceChanged(selectedAudioDevice, audioDevices); + audioManagerEvents.onAudioDeviceChanged(resultingAudioDevice, audioDevices); } } Log.d(TAG, "--- updateAudioDeviceState done"); From 78b29082bf024d7e9fe370027327ba43c1b354f4 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 1 Feb 2022 11:53:05 +0100 Subject: [PATCH 03/17] show audio button also for videocalls use layout weight Signed-off-by: Marcel Hibbe --- .../talk/activities/CallActivity.java | 2 -- app/src/main/res/layout/call_activity.xml | 31 ++++++++++++------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index 02027eba7..4cfd368fb 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -519,7 +519,6 @@ public class CallActivity extends CallBaseActivity { } if (isVoiceOnlyCall) { - binding.audioOutputButton.setVisibility(View.VISIBLE); binding.switchSelfVideoButton.setVisibility(View.GONE); binding.cameraButton.setVisibility(View.GONE); binding.selfVideoRenderer.setVisibility(View.GONE); @@ -536,7 +535,6 @@ public class CallActivity extends CallBaseActivity { params.setMargins(0, 0, 0, 0); binding.gridview.setLayoutParams(params); - binding.audioOutputButton.setVisibility(View.GONE); if (cameraEnumerator.getDeviceNames().length < 2) { binding.switchSelfVideoButton.setVisibility(View.GONE); } diff --git a/app/src/main/res/layout/call_activity.xml b/app/src/main/res/layout/call_activity.xml index 310e1cba1..897c6ed06 100644 --- a/app/src/main/res/layout/call_activity.xml +++ b/app/src/main/res/layout/call_activity.xml @@ -140,59 +140,66 @@ android:animateLayoutChanges="true" android:background="@android:color/transparent" android:gravity="center" - android:orientation="horizontal"> + android:orientation="horizontal" + android:weightSum="5"> + app:roundAsCircle="true" + android:layout_weight="1"/> + app:roundAsCircle="true" + android:layout_weight="1"/> + app:roundAsCircle="true" + android:layout_weight="1"/> + app:roundAsCircle="true" + android:layout_weight="1"/> + app:roundAsCircle="true" + android:layout_weight="1"/> Date: Tue, 1 Feb 2022 13:26:29 +0100 Subject: [PATCH 04/17] highlight active audio output use layout weight Signed-off-by: Marcel Hibbe --- .../talk/activities/CallActivity.java | 63 ++++++++++--------- .../talk/ui/dialog/AudioOutputDialog.kt | 51 ++++++++++++++- .../main/res/layout/dialog_audio_output.xml | 6 +- 3 files changed, 86 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index 4cfd368fb..aeeda0c53 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -173,6 +173,8 @@ public class CallActivity extends CallBaseActivity { public static final String TAG = "CallActivity"; + public MagicAudioManager audioManager; + private static final String[] PERMISSIONS_CALL = { android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO, @@ -198,7 +200,6 @@ public class CallActivity extends CallBaseActivity { private MediaConstraints videoConstraints; private MediaConstraints sdpConstraints; private MediaConstraints sdpConstraintsForMCU; - private MagicAudioManager audioManager; private VideoSource videoSource; private VideoTrack localVideoTrack; private AudioSource audioSource; @@ -369,33 +370,6 @@ public class CallActivity extends CallBaseActivity { }); } - public void setAudioOutputChannel(MagicAudioManager.AudioDevice audioDevice) { - if (audioManager == null) { - return; - } - - audioManager.selectAudioDevice(audioDevice); - - switch (audioManager.getResultingAudioDevice()) { - case BLUETOOTH: - binding.audioOutputButton.getHierarchy().setPlaceholderImage( - AppCompatResources.getDrawable(context, R.drawable.ic_baseline_bluetooth_audio_24)); - break; - case SPEAKER_PHONE: - binding.audioOutputButton.getHierarchy().setPlaceholderImage( - AppCompatResources.getDrawable(context, R.drawable.ic_volume_up_white_24dp)); - break; - case EARPIECE: - binding.audioOutputButton.getHierarchy().setPlaceholderImage( - AppCompatResources.getDrawable(context, R.drawable.ic_baseline_phone_in_talk_24)); - break; - default: - Log.e(TAG, "Invalid audio device selection"); - break; - } - DrawableCompat.setTint(binding.audioOutputButton.getDrawable(), Color.WHITE); - } - private void createCameraEnumerator() { boolean camera2EnumeratorIsSupported = false; try { @@ -441,6 +415,12 @@ public class CallActivity extends CallBaseActivity { Log.d(TAG, "Starting the audio manager..."); audioManager.start(this::onAudioManagerDevicesChanged); + if (isVoiceOnlyCall) { + setAudioOutputChannel(MagicAudioManager.AudioDevice.EARPIECE); + } else { + setAudioOutputChannel(MagicAudioManager.AudioDevice.SPEAKER_PHONE); + } + iceServers = new ArrayList<>(); //create sdpConstraints @@ -471,6 +451,33 @@ public class CallActivity extends CallBaseActivity { microphoneInitialization(); } + public void setAudioOutputChannel(MagicAudioManager.AudioDevice selectedAudioDevice) { + if (audioManager == null) { + return; + } + + audioManager.selectAudioDevice(selectedAudioDevice); + + switch (audioManager.getResultingAudioDevice()) { + case BLUETOOTH: + binding.audioOutputButton.getHierarchy().setPlaceholderImage( + AppCompatResources.getDrawable(context, R.drawable.ic_baseline_bluetooth_audio_24)); + break; + case SPEAKER_PHONE: + binding.audioOutputButton.getHierarchy().setPlaceholderImage( + AppCompatResources.getDrawable(context, R.drawable.ic_volume_up_white_24dp)); + break; + case EARPIECE: + binding.audioOutputButton.getHierarchy().setPlaceholderImage( + AppCompatResources.getDrawable(context, R.drawable.ic_baseline_phone_in_talk_24)); + break; + default: + Log.e(TAG, "Icon for audio output not available"); + break; + } + DrawableCompat.setTint(binding.audioOutputButton.getDrawable(), Color.WHITE); + } + private void handleFromNotification() { int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1}); diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt index eaf999a53..d6198977f 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt @@ -2,9 +2,7 @@ * Nextcloud Talk application * * @author Marcel Hibbe - * @author Andy Scherzinger - * Copyright (C) 2021 Marcel Hibbe - * Copyright (C) 2021 Andy Scherzinger + * Copyright (C) 2022 Marcel Hibbe * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +21,10 @@ package com.nextcloud.talk.ui.dialog import android.os.Bundle +import android.util.Log import android.view.View import android.view.ViewGroup +import androidx.core.content.ContextCompat import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.nextcloud.talk.R @@ -42,7 +42,52 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call setContentView(dialogAudioOutputBinding.root) window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + highlightActiveOutputChannel() + initClickListeners() + } + private fun highlightActiveOutputChannel() { + when (callActivity.audioManager?.resultingAudioDevice) { + MagicAudioManager.AudioDevice.BLUETOOTH -> { + dialogAudioOutputBinding.audioOutputBluetoothIcon.setColorFilter( + ContextCompat.getColor( + context, R.color + .colorPrimary + ), android.graphics.PorterDuff.Mode.SRC_IN + ) + dialogAudioOutputBinding.audioOutputBluetoothText.setTextColor( + callActivity.resources.getColor( + R.color + .colorPrimary + ) + ) + } + + MagicAudioManager.AudioDevice.SPEAKER_PHONE -> { + dialogAudioOutputBinding.audioOutputSpeakerIcon.setColorFilter( + ContextCompat.getColor( + context, + R.color.colorPrimary + ), android.graphics.PorterDuff.Mode.SRC_IN + ) + dialogAudioOutputBinding.audioOutputSpeakerText.setTextColor(callActivity.resources.getColor(R.color.colorPrimary)) + } + + MagicAudioManager.AudioDevice.EARPIECE -> { + dialogAudioOutputBinding.audioOutputEarspeakerIcon.setColorFilter( + ContextCompat.getColor( + context, + R.color.colorPrimary + ), android.graphics.PorterDuff.Mode.SRC_IN + ) + dialogAudioOutputBinding.audioOutputEarspeakerText.setTextColor(callActivity.resources.getColor(R.color.colorPrimary)) + } + + else -> Log.d(TAG, "AudioOutputDialog doesn't know this AudioDevice") + } + } + + private fun initClickListeners() { dialogAudioOutputBinding.audioOutputBluetooth.setOnClickListener { callActivity.setAudioOutputChannel(MagicAudioManager.AudioDevice.BLUETOOTH) dismiss() diff --git a/app/src/main/res/layout/dialog_audio_output.xml b/app/src/main/res/layout/dialog_audio_output.xml index 5e6e4ec3f..d9cba1c14 100644 --- a/app/src/main/res/layout/dialog_audio_output.xml +++ b/app/src/main/res/layout/dialog_audio_output.xml @@ -57,7 +57,7 @@ android:layout_height="wrap_content" android:contentDescription="@null" android:src="@drawable/ic_baseline_bluetooth_audio_24" - app:tint="@color/colorPrimary" /> + app:tint="#99ffffff" /> + app:tint="#99ffffff" /> + app:tint="#99ffffff" /> Date: Tue, 1 Feb 2022 13:41:52 +0100 Subject: [PATCH 05/17] hide unavailable audio output channels Signed-off-by: Marcel Hibbe --- .../com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt index d6198977f..6fdbf8750 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt @@ -42,10 +42,20 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call setContentView(dialogAudioOutputBinding.root) window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + hideUnavailableOutputChannels() highlightActiveOutputChannel() initClickListeners() } + private fun hideUnavailableOutputChannels() { + if (callActivity.audioManager?.audioDevices?.contains(MagicAudioManager.AudioDevice.BLUETOOTH) == false){ + dialogAudioOutputBinding.audioOutputBluetooth.visibility = View.GONE + } + if (callActivity.audioManager?.audioDevices?.contains(MagicAudioManager.AudioDevice.EARPIECE) == false){ + dialogAudioOutputBinding.audioOutputEarspeaker.visibility = View.GONE + } + } + private fun highlightActiveOutputChannel() { when (callActivity.audioManager?.resultingAudioDevice) { MagicAudioManager.AudioDevice.BLUETOOTH -> { From 3587fe6e12f5b9620780eab2793b3ede4b1cc418 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 1 Feb 2022 16:04:10 +0100 Subject: [PATCH 06/17] use speaker if no bluetooth is available Signed-off-by: Marcel Hibbe --- .../java/com/nextcloud/talk/activities/CallActivity.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index aeeda0c53..d85a978ca 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -158,7 +158,7 @@ import okhttp3.Cache; import pub.devrel.easypermissions.AfterPermissionGranted; @AutoInjector(NextcloudTalkApplication.class) -public class CallActivity extends CallBaseActivity { +public class CallActivity extends CallBaseActivity implements MagicAudioManager.AudioManagerEvents { @Inject NcApi ncApi; @@ -256,6 +256,11 @@ public class CallActivity extends CallBaseActivity { private CallActivityBinding binding; + @Override + public void onAudioDeviceChanged(MagicAudioManager.AudioDevice selectedAudioDevice, Set availableAudioDevices) { + setAudioOutputChannel(selectedAudioDevice); + } + @Parcel public enum CallStatus { CONNECTING, CALLING_TIMEOUT, JOINED, IN_CONVERSATION, RECONNECTING, OFFLINE, LEAVING, PUBLISHER_FAILED From 338f06dda125b752a61da319b9888389dde25653 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 1 Feb 2022 17:03:15 +0100 Subject: [PATCH 07/17] update UI if audio output device changed Signed-off-by: Marcel Hibbe --- .../talk/activities/CallActivity.java | 38 ++++++++++--------- .../talk/ui/dialog/AudioOutputDialog.kt | 9 ++++- .../talk/webrtc/MagicAudioManager.java | 16 ++++---- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index d85a978ca..4929df393 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -158,7 +158,7 @@ import okhttp3.Cache; import pub.devrel.easypermissions.AfterPermissionGranted; @AutoInjector(NextcloudTalkApplication.class) -public class CallActivity extends CallBaseActivity implements MagicAudioManager.AudioManagerEvents { +public class CallActivity extends CallBaseActivity { @Inject NcApi ncApi; @@ -256,10 +256,7 @@ public class CallActivity extends CallBaseActivity implements MagicAudioManager. private CallActivityBinding binding; - @Override - public void onAudioDeviceChanged(MagicAudioManager.AudioDevice selectedAudioDevice, Set availableAudioDevices) { - setAudioOutputChannel(selectedAudioDevice); - } + private AudioOutputDialog audioOutputDialog; @Parcel public enum CallStatus { @@ -336,9 +333,10 @@ public class CallActivity extends CallBaseActivity implements MagicAudioManager. private void initClickListeners() { binding.pictureInPictureButton.setOnClickListener(l -> enterPipMode()); - binding.audioOutputButton.setOnClickListener(v -> new AudioOutputDialog( - this - ).show()); + binding.audioOutputButton.setOnClickListener(v -> { + audioOutputDialog = new AudioOutputDialog(this); + audioOutputDialog.show(); + }); binding.microphoneButton.setOnClickListener(l -> onMicrophoneClick()); binding.microphoneButton.setOnLongClickListener(l -> { @@ -457,13 +455,14 @@ public class CallActivity extends CallBaseActivity implements MagicAudioManager. } public void setAudioOutputChannel(MagicAudioManager.AudioDevice selectedAudioDevice) { - if (audioManager == null) { - return; + if (audioManager != null) { + audioManager.selectAudioDevice(selectedAudioDevice); + updateAudioOutputButton(audioManager.getResultingAudioDevice()); } + } - audioManager.selectAudioDevice(selectedAudioDevice); - - switch (audioManager.getResultingAudioDevice()) { + private void updateAudioOutputButton(MagicAudioManager.AudioDevice activeAudioDevice) { + switch (activeAudioDevice) { case BLUETOOTH: binding.audioOutputButton.getHierarchy().setPlaceholderImage( AppCompatResources.getDrawable(context, R.drawable.ic_baseline_bluetooth_audio_24)); @@ -749,7 +748,7 @@ public class CallActivity extends CallBaseActivity implements MagicAudioManager. final MagicAudioManager.AudioDevice device, final Set availableDevices) { Log.d(TAG, "onAudioManagerDevicesChanged: " + availableDevices + ", " - + "selected: " + device); + + "result: " + device); final boolean shouldDisableProximityLock = (device.equals(MagicAudioManager.AudioDevice.WIRED_HEADSET) || device.equals(MagicAudioManager.AudioDevice.SPEAKER_PHONE) @@ -760,6 +759,11 @@ public class CallActivity extends CallBaseActivity implements MagicAudioManager. } else { powerManagerUtils.updatePhoneState(PowerManagerUtils.PhoneState.WITH_PROXIMITY_SENSOR_LOCK); } + + if (audioOutputDialog != null){ + audioOutputDialog.updateOutputDeviceList(); + } + updateAudioOutputButton(device); } @@ -1675,10 +1679,10 @@ public class CallActivity extends CallBaseActivity implements MagicAudioManager. Log.d(TAG, " currentSessionId is " + currentSessionId); for (HashMap participant : users) { - long inCallFlag = (long)participant.get("inCall"); + long inCallFlag = (long) participant.get("inCall"); if (!participant.get("sessionId").equals(currentSessionId)) { boolean isNewSession; - Log.d(TAG, " inCallFlag of participant " + participant.get("sessionId").toString().substring(0,4) + " : " + inCallFlag); + Log.d(TAG, " inCallFlag of participant " + participant.get("sessionId").toString().substring(0, 4) + " : " + inCallFlag); isNewSession = inCallFlag != 0; if (isNewSession) { @@ -1688,7 +1692,7 @@ public class CallActivity extends CallBaseActivity implements MagicAudioManager. } } else { Log.d(TAG, " inCallFlag of currentSessionId: " + inCallFlag); - if (inCallFlag == 0){ + if (inCallFlag == 0) { Log.d(TAG, "Most probably a moderator ended the call for all."); hangup(true); } diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt index 6fdbf8750..9826d753a 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt @@ -42,17 +42,22 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call setContentView(dialogAudioOutputBinding.root) window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) - hideUnavailableOutputChannels() + updateOutputDeviceList() highlightActiveOutputChannel() initClickListeners() } - private fun hideUnavailableOutputChannels() { + fun updateOutputDeviceList() { if (callActivity.audioManager?.audioDevices?.contains(MagicAudioManager.AudioDevice.BLUETOOTH) == false){ dialogAudioOutputBinding.audioOutputBluetooth.visibility = View.GONE + } else { + dialogAudioOutputBinding.audioOutputBluetooth.visibility = View.VISIBLE } + if (callActivity.audioManager?.audioDevices?.contains(MagicAudioManager.AudioDevice.EARPIECE) == false){ dialogAudioOutputBinding.audioOutputEarspeaker.visibility = View.GONE + } else { + dialogAudioOutputBinding.audioOutputEarspeaker.visibility = View.VISIBLE } } diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java b/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java index 7d640591f..0dbd54fbf 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java @@ -59,7 +59,7 @@ public class MagicAudioManager { private final MagicBluetoothManager bluetoothManager; private boolean controlSpeakerByProximitySensor; private AudioManager audioManager; - private AudioManagerEvents audioManagerEvents; + private AudioManagerListener audioManagerListener; private AudioManagerState amState; private int savedAudioMode = AudioManager.MODE_INVALID; private boolean savedIsSpeakerPhoneOn = false; @@ -147,7 +147,7 @@ public class MagicAudioManager { } @SuppressLint("WrongConstant") - public void start(AudioManagerEvents audioManagerEvents) { + public void start(AudioManagerListener audioManagerListener) { Log.d(TAG, "start"); ThreadUtils.checkIsOnMainThread(); if (amState == AudioManagerState.RUNNING) { @@ -157,7 +157,7 @@ public class MagicAudioManager { // TODO(henrika): perhaps call new method called preInitAudio() here if UNINITIALIZED. Log.d(TAG, "AudioManager starts..."); - this.audioManagerEvents = audioManagerEvents; + this.audioManagerListener = audioManagerListener; amState = AudioManagerState.RUNNING; // Store current audio state so we can restore it when stop() is called. @@ -276,7 +276,7 @@ public class MagicAudioManager { powerManagerUtils.updatePhoneState(PowerManagerUtils.PhoneState.IDLE); - audioManagerEvents = null; + audioManagerListener = null; Log.d(TAG, "AudioManager stopped"); } @@ -462,7 +462,7 @@ public class MagicAudioManager { // Correct user selected audio devices if needed. if (userSelectedAudioDevice == AudioDevice.BLUETOOTH && bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_UNAVAILABLE) { - userSelectedAudioDevice = AudioDevice.NONE; + userSelectedAudioDevice = AudioDevice.SPEAKER_PHONE; } if (userSelectedAudioDevice == AudioDevice.SPEAKER_PHONE && hasWiredHeadset) { userSelectedAudioDevice = AudioDevice.WIRED_HEADSET; @@ -539,9 +539,9 @@ public class MagicAudioManager { Log.d(TAG, "New device status: " + "available=" + audioDevices + ", " + "resulting(new)=" + newResultingAudioDevice); - if (audioManagerEvents != null) { + if (audioManagerListener != null) { // Notify a listening client that audio device has been changed. - audioManagerEvents.onAudioDeviceChanged(resultingAudioDevice, audioDevices); + audioManagerListener.onAudioDeviceChanged(resultingAudioDevice, audioDevices); } } Log.d(TAG, "--- updateAudioDeviceState done"); @@ -567,7 +567,7 @@ public class MagicAudioManager { /** * Selected audio device change event. */ - public static interface AudioManagerEvents { + public static interface AudioManagerListener { // Callback fired once audio device is changed or list of available audio devices changed. void onAudioDeviceChanged( AudioDevice selectedAudioDevice, Set availableAudioDevices); From a34eb89570416d453a492599de85a09f7c68e519 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 1 Feb 2022 18:20:32 +0100 Subject: [PATCH 08/17] modify behaviour of proximity sensor use proximity sensor only if it is a voiceOnly call and userSelectedAudioDevice was SPEAKER_PHONE Signed-off-by: Marcel Hibbe --- .../talk/activities/CallActivity.java | 4 +- .../talk/ui/dialog/AudioOutputDialog.kt | 2 +- .../talk/webrtc/MagicAudioManager.java | 77 ++++++++----------- 3 files changed, 36 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index 4929df393..cbcf78fcf 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -412,7 +412,7 @@ public class CallActivity extends CallBaseActivity { // Create and audio manager that will take care of audio routing, // audio modes, audio device enumeration etc. - audioManager = MagicAudioManager.create(getApplicationContext(), !isVoiceOnlyCall); + audioManager = MagicAudioManager.create(getApplicationContext(), isVoiceOnlyCall); // Store existing audio settings and change audio mode to // MODE_IN_COMMUNICATION for best possible VoIP performance. Log.d(TAG, "Starting the audio manager..."); @@ -457,7 +457,7 @@ public class CallActivity extends CallBaseActivity { public void setAudioOutputChannel(MagicAudioManager.AudioDevice selectedAudioDevice) { if (audioManager != null) { audioManager.selectAudioDevice(selectedAudioDevice); - updateAudioOutputButton(audioManager.getResultingAudioDevice()); + updateAudioOutputButton(audioManager.getCurrentAudioDevice()); } } diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt index 9826d753a..74933562a 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt @@ -62,7 +62,7 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call } private fun highlightActiveOutputChannel() { - when (callActivity.audioManager?.resultingAudioDevice) { + when (callActivity.audioManager?.currentAudioDevice) { MagicAudioManager.AudioDevice.BLUETOOTH -> { dialogAudioOutputBinding.audioOutputBluetoothIcon.setColorFilter( ContextCompat.getColor( diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java b/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java index 0dbd54fbf..ff9543401 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java @@ -57,7 +57,7 @@ public class MagicAudioManager { private static final String TAG = "MagicAudioManager"; private final Context magicContext; private final MagicBluetoothManager bluetoothManager; - private boolean controlSpeakerByProximitySensor; + private boolean useProximitySensor; private AudioManager audioManager; private AudioManagerListener audioManagerListener; private AudioManagerState amState; @@ -67,7 +67,7 @@ public class MagicAudioManager { private boolean hasWiredHeadset = false; private AudioDevice userSelectedAudioDevice; - private AudioDevice resultingAudioDevice; + private AudioDevice currentAudioDevice; private MagicProximitySensor proximitySensor = null; @@ -90,7 +90,7 @@ public class MagicAudioManager { powerManagerUtils = new PowerManagerUtils(); powerManagerUtils.updatePhoneState(PowerManagerUtils.PhoneState.WITH_PROXIMITY_SENSOR_LOCK); - controlSpeakerByProximitySensor = useProximitySensor; + this.useProximitySensor = useProximitySensor; updateAudioDeviceState(); // Create and initialize the proximity sensor. @@ -118,27 +118,24 @@ public class MagicAudioManager { * e.g. from "NEAR to FAR" or from "FAR to NEAR". */ private void onProximitySensorChangedState() { - - if (!controlSpeakerByProximitySensor) { + if (!useProximitySensor) { return; } - // The proximity sensor should only be activated when there are exactly two - // available audio devices. - if (audioDevices.size() == 2 && audioDevices.contains(MagicAudioManager.AudioDevice.EARPIECE) - && audioDevices.contains(MagicAudioManager.AudioDevice.SPEAKER_PHONE)) { + if (userSelectedAudioDevice.equals(AudioDevice.SPEAKER_PHONE) + && audioDevices.contains(AudioDevice.EARPIECE) + && audioDevices.contains(AudioDevice.SPEAKER_PHONE)) { + if (proximitySensor.sensorReportsNearState()) { - // Sensor reports that a "handset is being held up to a person's ear", - // or "something is covering the light sensor". - setAudioDeviceInternal(MagicAudioManager.AudioDevice.EARPIECE); + setAudioDeviceInternal(AudioDevice.EARPIECE); + Log.d(TAG,"switched to EARPIECE because userSelectedAudioDevice was SPEAKER_PHONE and proximity=near"); EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType .SENSOR_NEAR, null, null, null, null)); } else { - // Sensor reports that a "handset is removed from a person's ear", or - // "the light sensor is no longer covered". setAudioDeviceInternal(MagicAudioManager.AudioDevice.SPEAKER_PHONE); + Log.d(TAG,"switched to SPEAKER_PHONE because userSelectedAudioDevice was SPEAKER_PHONE and proximity=far"); EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType .SENSOR_FAR, null, null, null, null)); @@ -226,7 +223,7 @@ public class MagicAudioManager { // Set initial device states. userSelectedAudioDevice = AudioDevice.NONE; - resultingAudioDevice = AudioDevice.NONE; + currentAudioDevice = AudioDevice.NONE; audioDevices.clear(); // Initialize and start Bluetooth if a BT device is available or initiate @@ -285,21 +282,16 @@ public class MagicAudioManager { /** * Changes selection of the currently active audio device. */ - private void setAudioDeviceInternal(AudioDevice device) { - Log.d(TAG, "setAudioDeviceInternal(device=" + device + ")"); + private void setAudioDeviceInternal(AudioDevice audioDevice) { + Log.d(TAG, "setAudioDeviceInternal(device=" + audioDevice + ")"); - if (audioDevices.contains(device)) { - - switch (device) { + if (audioDevices.contains(audioDevice)) { + switch (audioDevice) { case SPEAKER_PHONE: setSpeakerphoneOn(true); break; case EARPIECE: - setSpeakerphoneOn(false); - break; case WIRED_HEADSET: - setSpeakerphoneOn(false); - break; case BLUETOOTH: setSpeakerphoneOn(false); break; @@ -307,7 +299,7 @@ public class MagicAudioManager { Log.e(TAG, "Invalid audio device selection"); break; } - resultingAudioDevice = device; + currentAudioDevice = audioDevice; } } @@ -322,11 +314,11 @@ public class MagicAudioManager { userSelectedAudioDevice = device; - if (device == AudioDevice.SPEAKER_PHONE) { - controlSpeakerByProximitySensor = true; - } else { - controlSpeakerByProximitySensor = false; - } +// if (device == AudioDevice.SPEAKER_PHONE) { +// controlSpeakerByProximitySensor = true; +// } else { +// controlSpeakerByProximitySensor = false; +// } updateAudioDeviceState(); } @@ -342,9 +334,9 @@ public class MagicAudioManager { /** * Returns the currently selected audio device. */ - public AudioDevice getResultingAudioDevice() { + public AudioDevice getCurrentAudioDevice() { ThreadUtils.checkIsOnMainThread(); - return resultingAudioDevice; + return currentAudioDevice; } /** @@ -424,12 +416,9 @@ public class MagicAudioManager { + "BT state=" + bluetoothManager.getState()); Log.d(TAG, "Device status: " + "available=" + audioDevices + ", " - + "resulting(current)=" + resultingAudioDevice + ", " + + "current=" + currentAudioDevice + ", " + "user selected=" + userSelectedAudioDevice); - - - if (bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_AVAILABLE || bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_UNAVAILABLE || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_DISCONNECTING) { @@ -514,34 +503,34 @@ public class MagicAudioManager { // Update selected audio device. - AudioDevice newResultingAudioDevice; + AudioDevice newCurrentAudioDevice; if (bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTED) { // If a Bluetooth is connected, then it should be used as output audio // device. Note that it is not sufficient that a headset is available; // an active SCO channel must also be up and running. - newResultingAudioDevice = AudioDevice.BLUETOOTH; + newCurrentAudioDevice = AudioDevice.BLUETOOTH; } else if (hasWiredHeadset) { // If a wired headset is connected, but Bluetooth is not, then wired headset is used as // audio device. - newResultingAudioDevice = AudioDevice.WIRED_HEADSET; + newCurrentAudioDevice = AudioDevice.WIRED_HEADSET; } else { // No wired headset and no Bluetooth, hence the audio-device list can contain speaker // phone (on a tablet), or speaker phone and earpiece (on mobile phone). // |defaultAudioDevice| contains either AudioDevice.SPEAKER_PHONE or AudioDevice.EARPIECE // depending on the user's selection. - newResultingAudioDevice = userSelectedAudioDevice; + newCurrentAudioDevice = userSelectedAudioDevice; } // Switch to new device but only if there has been any changes. - if (newResultingAudioDevice != resultingAudioDevice || audioDeviceSetUpdated) { + if (newCurrentAudioDevice != currentAudioDevice || audioDeviceSetUpdated) { // Do the required device switch. - setAudioDeviceInternal(newResultingAudioDevice); + setAudioDeviceInternal(newCurrentAudioDevice); Log.d(TAG, "New device status: " + "available=" + audioDevices + ", " - + "resulting(new)=" + newResultingAudioDevice); + + "current(new)=" + newCurrentAudioDevice); if (audioManagerListener != null) { // Notify a listening client that audio device has been changed. - audioManagerListener.onAudioDeviceChanged(resultingAudioDevice, audioDevices); + audioManagerListener.onAudioDeviceChanged(currentAudioDevice, audioDevices); } } Log.d(TAG, "--- updateAudioDeviceState done"); From 51df0e67f41887a5a679b6a5aaece2ffd3a5b58d Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 1 Feb 2022 19:12:48 +0100 Subject: [PATCH 09/17] add UI logic for wired headset if wired headset is plugged in hide earpiece and speaker icons if wired headset is plugged out show earpiece and speaker icons Signed-off-by: Marcel Hibbe --- .../talk/activities/CallActivity.java | 18 ++++++---- .../talk/ui/dialog/AudioOutputDialog.kt | 32 ++++++++++++++++-- .../drawable/ic_baseline_headset_mic_24.xml | 10 ++++++ .../main/res/layout/dialog_audio_output.xml | 33 +++++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 5 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 app/src/main/res/drawable/ic_baseline_headset_mic_24.xml diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index cbcf78fcf..ef0b9a612 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -475,6 +475,10 @@ public class CallActivity extends CallBaseActivity { binding.audioOutputButton.getHierarchy().setPlaceholderImage( AppCompatResources.getDrawable(context, R.drawable.ic_baseline_phone_in_talk_24)); break; + case WIRED_HEADSET: + binding.audioOutputButton.getHierarchy().setPlaceholderImage( + AppCompatResources.getDrawable(context, R.drawable.ic_baseline_headset_mic_24)); + break; default: Log.e(TAG, "Icon for audio output not available"); break; @@ -745,14 +749,14 @@ public class CallActivity extends CallBaseActivity { } private void onAudioManagerDevicesChanged( - final MagicAudioManager.AudioDevice device, + final MagicAudioManager.AudioDevice currentDevice, final Set availableDevices) { Log.d(TAG, "onAudioManagerDevicesChanged: " + availableDevices + ", " - + "result: " + device); + + "currentDevice: " + currentDevice); - final boolean shouldDisableProximityLock = (device.equals(MagicAudioManager.AudioDevice.WIRED_HEADSET) - || device.equals(MagicAudioManager.AudioDevice.SPEAKER_PHONE) - || device.equals(MagicAudioManager.AudioDevice.BLUETOOTH)); + final boolean shouldDisableProximityLock = (currentDevice.equals(MagicAudioManager.AudioDevice.WIRED_HEADSET) + || currentDevice.equals(MagicAudioManager.AudioDevice.SPEAKER_PHONE) + || currentDevice.equals(MagicAudioManager.AudioDevice.BLUETOOTH)); if (shouldDisableProximityLock) { powerManagerUtils.updatePhoneState(PowerManagerUtils.PhoneState.WITHOUT_PROXIMITY_SENSOR_LOCK); @@ -760,10 +764,10 @@ public class CallActivity extends CallBaseActivity { powerManagerUtils.updatePhoneState(PowerManagerUtils.PhoneState.WITH_PROXIMITY_SENSOR_LOCK); } - if (audioOutputDialog != null){ + if (audioOutputDialog != null) { audioOutputDialog.updateOutputDeviceList(); } - updateAudioOutputButton(device); + updateAudioOutputButton(currentDevice); } diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt index 74933562a..efb3d65b8 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt @@ -43,22 +43,37 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) updateOutputDeviceList() - highlightActiveOutputChannel() initClickListeners() } fun updateOutputDeviceList() { - if (callActivity.audioManager?.audioDevices?.contains(MagicAudioManager.AudioDevice.BLUETOOTH) == false){ + if (callActivity.audioManager?.audioDevices?.contains(MagicAudioManager.AudioDevice.BLUETOOTH) == false) { dialogAudioOutputBinding.audioOutputBluetooth.visibility = View.GONE } else { dialogAudioOutputBinding.audioOutputBluetooth.visibility = View.VISIBLE } - if (callActivity.audioManager?.audioDevices?.contains(MagicAudioManager.AudioDevice.EARPIECE) == false){ + if (callActivity.audioManager?.audioDevices?.contains(MagicAudioManager.AudioDevice.EARPIECE) == false) { dialogAudioOutputBinding.audioOutputEarspeaker.visibility = View.GONE } else { dialogAudioOutputBinding.audioOutputEarspeaker.visibility = View.VISIBLE } + + if (callActivity.audioManager?.audioDevices?.contains(MagicAudioManager.AudioDevice.SPEAKER_PHONE) == false) { + dialogAudioOutputBinding.audioOutputSpeaker.visibility = View.GONE + } else { + dialogAudioOutputBinding.audioOutputSpeaker.visibility = View.VISIBLE + } + + if (callActivity.audioManager?.currentAudioDevice?.equals(MagicAudioManager.AudioDevice.WIRED_HEADSET) == true) { + dialogAudioOutputBinding.audioOutputEarspeaker.visibility = View.GONE + dialogAudioOutputBinding.audioOutputSpeaker.visibility = View.GONE + dialogAudioOutputBinding.audioOutputWiredHeadset.visibility = View.VISIBLE + } else { + dialogAudioOutputBinding.audioOutputWiredHeadset.visibility = View.GONE + } + + highlightActiveOutputChannel() } private fun highlightActiveOutputChannel() { @@ -98,6 +113,17 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call dialogAudioOutputBinding.audioOutputEarspeakerText.setTextColor(callActivity.resources.getColor(R.color.colorPrimary)) } + MagicAudioManager.AudioDevice.WIRED_HEADSET -> { + dialogAudioOutputBinding.audioOutputWiredHeadsetIcon.setColorFilter( + ContextCompat.getColor( + context, + R.color.colorPrimary + ), android.graphics.PorterDuff.Mode.SRC_IN + ) + dialogAudioOutputBinding.audioOutputWiredHeadsetText.setTextColor(callActivity.resources.getColor(R.color + .colorPrimary)) + } + else -> Log.d(TAG, "AudioOutputDialog doesn't know this AudioDevice") } } diff --git a/app/src/main/res/drawable/ic_baseline_headset_mic_24.xml b/app/src/main/res/drawable/ic_baseline_headset_mic_24.xml new file mode 100644 index 000000000..31cc591d0 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_headset_mic_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/dialog_audio_output.xml b/app/src/main/res/layout/dialog_audio_output.xml index d9cba1c14..6b136a302 100644 --- a/app/src/main/res/layout/dialog_audio_output.xml +++ b/app/src/main/res/layout/dialog_audio_output.xml @@ -138,4 +138,37 @@ + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 00e94ad71..2bef3843a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -498,5 +498,6 @@ Speaker Phone Audio output + Wired headset From 7f0980e6d22c8f0cf8b8504794f54a3476b7da2c Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 1 Feb 2022 19:14:21 +0100 Subject: [PATCH 10/17] format code + fix klint/findbugs warnings remove hardcodings Signed-off-by: Marcel Hibbe remove hardcodings Signed-off-by: Marcel Hibbe --- .../talk/activities/CallActivity.java | 4 +- .../talk/ui/dialog/AudioOutputDialog.kt | 39 ++++---- .../talk/webrtc/MagicAudioManager.java | 88 ++++++++----------- .../drawable/ic_baseline_attachment_24.xml | 26 ------ .../main/res/layout/dialog_audio_output.xml | 24 +++-- app/src/main/res/values/colors.xml | 2 + scripts/analysis/findbugs-results.txt | 2 +- 7 files changed, 78 insertions(+), 107 deletions(-) delete mode 100644 app/src/main/res/drawable/ic_baseline_attachment_24.xml diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index ef0b9a612..2080ef4af 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -377,8 +377,8 @@ public class CallActivity extends CallBaseActivity { boolean camera2EnumeratorIsSupported = false; try { camera2EnumeratorIsSupported = Camera2Enumerator.isSupported(this); - } catch (final Throwable throwable) { - Log.w(TAG, "Camera2Enumerator threw an error"); + } catch (final Throwable t) { + Log.w(TAG, "Camera2Enumerator threw an error", t); } if (camera2EnumeratorIsSupported) { diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt index efb3d65b8..be3976b9c 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt @@ -65,7 +65,10 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call dialogAudioOutputBinding.audioOutputSpeaker.visibility = View.VISIBLE } - if (callActivity.audioManager?.currentAudioDevice?.equals(MagicAudioManager.AudioDevice.WIRED_HEADSET) == true) { + if (callActivity.audioManager?.currentAudioDevice?.equals( + MagicAudioManager.AudioDevice.WIRED_HEADSET + ) == true + ) { dialogAudioOutputBinding.audioOutputEarspeaker.visibility = View.GONE dialogAudioOutputBinding.audioOutputSpeaker.visibility = View.GONE dialogAudioOutputBinding.audioOutputWiredHeadset.visibility = View.VISIBLE @@ -81,15 +84,13 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call MagicAudioManager.AudioDevice.BLUETOOTH -> { dialogAudioOutputBinding.audioOutputBluetoothIcon.setColorFilter( ContextCompat.getColor( - context, R.color - .colorPrimary - ), android.graphics.PorterDuff.Mode.SRC_IN + context, + R.color.colorPrimary + ), + android.graphics.PorterDuff.Mode.SRC_IN ) dialogAudioOutputBinding.audioOutputBluetoothText.setTextColor( - callActivity.resources.getColor( - R.color - .colorPrimary - ) + callActivity.resources.getColor(R.color.colorPrimary) ) } @@ -98,9 +99,12 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call ContextCompat.getColor( context, R.color.colorPrimary - ), android.graphics.PorterDuff.Mode.SRC_IN + ), + android.graphics.PorterDuff.Mode.SRC_IN + ) + dialogAudioOutputBinding.audioOutputSpeakerText.setTextColor( + callActivity.resources.getColor(R.color.colorPrimary) ) - dialogAudioOutputBinding.audioOutputSpeakerText.setTextColor(callActivity.resources.getColor(R.color.colorPrimary)) } MagicAudioManager.AudioDevice.EARPIECE -> { @@ -108,9 +112,12 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call ContextCompat.getColor( context, R.color.colorPrimary - ), android.graphics.PorterDuff.Mode.SRC_IN + ), + android.graphics.PorterDuff.Mode.SRC_IN + ) + dialogAudioOutputBinding.audioOutputEarspeakerText.setTextColor( + callActivity.resources.getColor(R.color.colorPrimary) ) - dialogAudioOutputBinding.audioOutputEarspeakerText.setTextColor(callActivity.resources.getColor(R.color.colorPrimary)) } MagicAudioManager.AudioDevice.WIRED_HEADSET -> { @@ -118,10 +125,12 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call ContextCompat.getColor( context, R.color.colorPrimary - ), android.graphics.PorterDuff.Mode.SRC_IN + ), + android.graphics.PorterDuff.Mode.SRC_IN + ) + dialogAudioOutputBinding.audioOutputWiredHeadsetText.setTextColor( + callActivity.resources.getColor(R.color.colorPrimary) ) - dialogAudioOutputBinding.audioOutputWiredHeadsetText.setTextColor(callActivity.resources.getColor(R.color - .colorPrimary)) } else -> Log.d(TAG, "AudioOutputDialog doesn't know this AudioDevice") diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java b/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java index ff9543401..866e5c6ce 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java @@ -41,8 +41,10 @@ import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.os.Build; import android.util.Log; + import com.nextcloud.talk.events.PeerConnectionEvent; import com.nextcloud.talk.utils.power.PowerManagerUtils; + import org.greenrobot.eventbus.EventBus; import org.webrtc.ThreadUtils; @@ -114,8 +116,8 @@ public class MagicAudioManager { } /** - * This method is called when the proximity sensor reports a state change, - * e.g. from "NEAR to FAR" or from "FAR to NEAR". + * This method is called when the proximity sensor reports a state change, e.g. from "NEAR to FAR" or from "FAR to + * NEAR". */ private void onProximitySensorChangedState() { if (!useProximitySensor) { @@ -128,17 +130,17 @@ public class MagicAudioManager { if (proximitySensor.sensorReportsNearState()) { setAudioDeviceInternal(AudioDevice.EARPIECE); - Log.d(TAG,"switched to EARPIECE because userSelectedAudioDevice was SPEAKER_PHONE and proximity=near"); + Log.d(TAG, "switched to EARPIECE because userSelectedAudioDevice was SPEAKER_PHONE and proximity=near"); EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .SENSOR_NEAR, null, null, null, null)); + .SENSOR_NEAR, null, null, null, null)); } else { setAudioDeviceInternal(MagicAudioManager.AudioDevice.SPEAKER_PHONE); - Log.d(TAG,"switched to SPEAKER_PHONE because userSelectedAudioDevice was SPEAKER_PHONE and proximity=far"); + Log.d(TAG, "switched to SPEAKER_PHONE because userSelectedAudioDevice was SPEAKER_PHONE and proximity=far"); EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .SENSOR_FAR, null, null, null, null)); + .SENSOR_FAR, null, null, null, null)); } } } @@ -206,7 +208,7 @@ public class MagicAudioManager { // Request audio playout focus (without ducking) and install listener for changes in focus. int result = audioManager.requestAudioFocus(audioFocusChangeListener, - AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); + AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { Log.d(TAG, "Audio focus request granted for VOICE_CALL streams"); } else { @@ -311,15 +313,7 @@ public class MagicAudioManager { if (!audioDevices.contains(device)) { Log.e(TAG, "Can not select " + device + " from available " + audioDevices); } - userSelectedAudioDevice = device; - -// if (device == AudioDevice.SPEAKER_PHONE) { -// controlSpeakerByProximitySensor = true; -// } else { -// controlSpeakerByProximitySensor = false; -// } - updateAudioDeviceState(); } @@ -383,11 +377,9 @@ public class MagicAudioManager { } /** - * Checks whether a wired headset is connected or not. - * This is not a valid indication that audio playback is actually over - * the wired headset as audio routing depends on other conditions. We - * only use it as an early indicator (during initialization) of an attached - * wired headset. + * Checks whether a wired headset is connected or not. This is not a valid indication that audio playback is + * actually over the wired headset as audio routing depends on other conditions. We only use it as an early + * indicator (during initialization) of an attached wired headset. */ @Deprecated private boolean hasWiredHeadset() { @@ -412,24 +404,24 @@ public class MagicAudioManager { public void updateAudioDeviceState() { ThreadUtils.checkIsOnMainThread(); Log.d(TAG, "--- updateAudioDeviceState: " - + "wired headset=" + hasWiredHeadset + ", " - + "BT state=" + bluetoothManager.getState()); + + "wired headset=" + hasWiredHeadset + ", " + + "BT state=" + bluetoothManager.getState()); Log.d(TAG, "Device status: " - + "available=" + audioDevices + ", " - + "current=" + currentAudioDevice + ", " - + "user selected=" + userSelectedAudioDevice); + + "available=" + audioDevices + ", " + + "current=" + currentAudioDevice + ", " + + "user selected=" + userSelectedAudioDevice); if (bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_AVAILABLE - || bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_UNAVAILABLE - || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_DISCONNECTING) { + || bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_UNAVAILABLE + || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_DISCONNECTING) { bluetoothManager.updateDevice(); } Set newAudioDevices = new HashSet<>(); if (bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTED - || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTING - || bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_AVAILABLE) { + || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTING + || bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_AVAILABLE) { newAudioDevices.add(AudioDevice.BLUETOOTH); } @@ -447,7 +439,6 @@ public class MagicAudioManager { audioDevices = newAudioDevices; - // Correct user selected audio devices if needed. if (userSelectedAudioDevice == AudioDevice.BLUETOOTH && bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_UNAVAILABLE) { @@ -461,29 +452,27 @@ public class MagicAudioManager { } - - // Need to start Bluetooth if it is available and user either selected it explicitly or // user did not select any output device. boolean needBluetoothAudioStart = - bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_AVAILABLE - && (userSelectedAudioDevice == AudioDevice.NONE - || userSelectedAudioDevice == AudioDevice.BLUETOOTH); + bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_AVAILABLE + && (userSelectedAudioDevice == AudioDevice.NONE + || userSelectedAudioDevice == AudioDevice.BLUETOOTH); // Need to stop Bluetooth audio if user selected different device and // Bluetooth SCO connection is established or in the process. boolean needBluetoothAudioStop = - (bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTED - || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTING) - && (userSelectedAudioDevice != AudioDevice.NONE - && userSelectedAudioDevice != AudioDevice.BLUETOOTH); + (bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTED + || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTING) + && (userSelectedAudioDevice != AudioDevice.NONE + && userSelectedAudioDevice != AudioDevice.BLUETOOTH); if (bluetoothManager.getState() == MagicBluetoothManager.State.HEADSET_AVAILABLE - || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTING - || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTED) { + || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTING + || bluetoothManager.getState() == MagicBluetoothManager.State.SCO_CONNECTED) { Log.d(TAG, "Need BT audio: start=" + needBluetoothAudioStart + ", " - + "stop=" + needBluetoothAudioStop + ", " - + "BT state=" + bluetoothManager.getState()); + + "stop=" + needBluetoothAudioStop + ", " + + "BT state=" + bluetoothManager.getState()); } // Start or stop Bluetooth SCO connection given states set earlier. @@ -494,8 +483,8 @@ public class MagicAudioManager { // Attempt to start Bluetooth SCO audio (takes a few second to start). if (needBluetoothAudioStart && - !needBluetoothAudioStop && - !bluetoothManager.startScoAudio()) { + !needBluetoothAudioStop && + !bluetoothManager.startScoAudio()) { // Remove BLUETOOTH from list of available devices since SCO failed. audioDevices.remove(AudioDevice.BLUETOOTH); audioDeviceSetUpdated = true; @@ -526,8 +515,8 @@ public class MagicAudioManager { // Do the required device switch. setAudioDeviceInternal(newCurrentAudioDevice); Log.d(TAG, "New device status: " - + "available=" + audioDevices + ", " - + "current(new)=" + newCurrentAudioDevice); + + "available=" + audioDevices + ", " + + "current(new)=" + newCurrentAudioDevice); if (audioManagerListener != null) { // Notify a listening client that audio device has been changed. audioManagerListener.onAudioDeviceChanged(currentAudioDevice, audioDevices); @@ -537,8 +526,7 @@ public class MagicAudioManager { } /** - * AudioDevice is the names of possible audio devices that we currently - * support. + * AudioDevice is the names of possible audio devices that we currently support. */ public enum AudioDevice { SPEAKER_PHONE, WIRED_HEADSET, EARPIECE, BLUETOOTH, NONE @@ -559,7 +547,7 @@ public class MagicAudioManager { public static interface AudioManagerListener { // Callback fired once audio device is changed or list of available audio devices changed. void onAudioDeviceChanged( - AudioDevice selectedAudioDevice, Set availableAudioDevices); + AudioDevice selectedAudioDevice, Set availableAudioDevices); } /* Receiver which handles changes in wired headset availability. */ diff --git a/app/src/main/res/drawable/ic_baseline_attachment_24.xml b/app/src/main/res/drawable/ic_baseline_attachment_24.xml deleted file mode 100644 index 91664a98e..000000000 --- a/app/src/main/res/drawable/ic_baseline_attachment_24.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - diff --git a/app/src/main/res/layout/dialog_audio_output.xml b/app/src/main/res/layout/dialog_audio_output.xml index 6b136a302..d9a2b8eb1 100644 --- a/app/src/main/res/layout/dialog_audio_output.xml +++ b/app/src/main/res/layout/dialog_audio_output.xml @@ -2,9 +2,7 @@ ~ Nextcloud Talk application ~ ~ @author Marcel Hibbe - ~ @author Andy Scherzinger - ~ Copyright (C) 2021 Andy Scherzinger - ~ Copyright (C) 2021 Marcel Hibbe + ~ Copyright (C) 2022 Marcel Hibbe ~ ~ This program is free software: you can redistribute it and/or modify ~ it under the terms of the GNU General Public License as published by @@ -25,7 +23,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="#121212" + android:background="@color/bg_call_screen_dialog" android:orientation="vertical" android:paddingBottom="@dimen/standard_padding"> @@ -36,7 +34,7 @@ android:padding="@dimen/standard_padding" android:text="@string/audio_output_dialog_headline" android:textAlignment="viewStart" - android:textColor="#99ffffff" + android:textColor="@color/grey_600" android:textSize="@dimen/bottom_sheet_text_size" /> + app:tint="@color/grey_600" /> @@ -90,7 +88,7 @@ android:layout_height="wrap_content" android:contentDescription="@null" android:src="@drawable/ic_volume_up_white_24dp" - app:tint="#99ffffff" /> + app:tint="@color/grey_600" /> @@ -123,7 +121,7 @@ android:layout_height="wrap_content" android:contentDescription="@null" android:src="@drawable/ic_baseline_phone_in_talk_24" - app:tint="#99ffffff" /> + app:tint="@color/grey_600" /> @@ -156,7 +154,7 @@ android:layout_height="wrap_content" android:contentDescription="@null" android:src="@drawable/ic_baseline_headset_mic_24" - app:tint="#99ffffff" /> + app:tint="@color/grey_600" /> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 61726802b..b8b7d9532 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -78,6 +78,8 @@ #800082C9 #46ffffff + #121212 + #ffffffff #BF999999 #FFCC00 diff --git a/scripts/analysis/findbugs-results.txt b/scripts/analysis/findbugs-results.txt index 8d28c8c9e..4a722e9c7 100644 --- a/scripts/analysis/findbugs-results.txt +++ b/scripts/analysis/findbugs-results.txt @@ -1 +1 @@ -554 \ No newline at end of file +552 \ No newline at end of file From 3e22741c1dab8fb07e9be93bf38f9d1731c424f4 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 7 Feb 2022 14:07:07 +0100 Subject: [PATCH 11/17] adjust audio output to latest material design bottom sheet specs Signed-off-by: Andy Scherzinger --- .../main/res/layout/dialog_audio_output.xml | 59 ++++++++----------- app/src/main/res/values/colors.xml | 4 ++ app/src/main/res/values/dimens.xml | 1 + 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/app/src/main/res/layout/dialog_audio_output.xml b/app/src/main/res/layout/dialog_audio_output.xml index d9a2b8eb1..9b76d863d 100644 --- a/app/src/main/res/layout/dialog_audio_output.xml +++ b/app/src/main/res/layout/dialog_audio_output.xml @@ -25,28 +25,26 @@ android:layout_height="wrap_content" android:background="@color/bg_call_screen_dialog" android:orientation="vertical" - android:paddingBottom="@dimen/standard_padding"> + android:paddingStart="@dimen/standard_padding" + android:paddingEnd="@dimen/standard_padding" + android:paddingBottom="@dimen/standard_half_padding"> @@ -73,13 +72,10 @@ @@ -106,13 +103,10 @@ @@ -139,13 +134,10 @@ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index b8b7d9532..8b059a897 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -40,6 +40,10 @@ #99000000 #61000000 + + #deffffff + #99ffffff + #FFFFFF diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index e52c554ed..4e0ef28cf 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -23,6 +23,7 @@ 16dp 72dp + 56dp 48dp 48dp From 86f2c563c3016115479ad32fe658a815db701e96 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 7 Feb 2022 14:15:32 +0100 Subject: [PATCH 12/17] adjust attachment sheet to latest material design bottom sheet specs Signed-off-by: Andy Scherzinger --- app/src/main/res/layout/dialog_attachment.xml | 58 ++++++++----------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/app/src/main/res/layout/dialog_attachment.xml b/app/src/main/res/layout/dialog_attachment.xml index 502d92456..c4d67d0f2 100644 --- a/app/src/main/res/layout/dialog_attachment.xml +++ b/app/src/main/res/layout/dialog_attachment.xml @@ -27,13 +27,15 @@ android:layout_height="wrap_content" android:background="@color/bg_bottom_sheet" android:orientation="vertical" - android:paddingBottom="@dimen/standard_padding"> + android:paddingStart="@dimen/standard_padding" + android:paddingEnd="@dimen/standard_padding" + android:paddingBottom="@dimen/standard_half_padding"> Date: Mon, 7 Feb 2022 14:41:32 +0100 Subject: [PATCH 13/17] Adjust bottom sheet item height to material 3 Signed-off-by: Andy Scherzinger --- app/src/main/res/layout/dialog_attachment.xml | 12 ++++++------ app/src/main/res/layout/dialog_audio_output.xml | 10 +++++----- app/src/main/res/values/dimens.xml | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/src/main/res/layout/dialog_attachment.xml b/app/src/main/res/layout/dialog_attachment.xml index c4d67d0f2..ae946d2d8 100644 --- a/app/src/main/res/layout/dialog_attachment.xml +++ b/app/src/main/res/layout/dialog_attachment.xml @@ -34,7 +34,7 @@ 16dp 72dp - 56dp + 56dp 48dp 48dp From e2e4f691437d141b8e6fd7c8ceb019df62afdc5b Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 7 Feb 2022 21:00:50 +0100 Subject: [PATCH 14/17] Adjust bottom sheet item to material 3 Signed-off-by: Andy Scherzinger --- app/src/main/res/layout/menu_item_sheet.xml | 37 +++++++++++++-------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/app/src/main/res/layout/menu_item_sheet.xml b/app/src/main/res/layout/menu_item_sheet.xml index caa3612d5..04d629a1a 100644 --- a/app/src/main/res/layout/menu_item_sheet.xml +++ b/app/src/main/res/layout/menu_item_sheet.xml @@ -2,6 +2,8 @@ ~ Nextcloud Talk application ~ ~ @author Mario Danic + ~ @author Andy Scherzinger + ~ Copyright (C) 2022 Andy Scherzinger ~ Copyright (C) 2017-2019 Mario Danic ~ ~ This program is free software: you can redistribute it and/or modify @@ -18,27 +20,36 @@ ~ along with this program. If not, see . --> - - + android:layout_height="56dp" + android:gravity="center_vertical"> + + tools:src="@drawable/ic_delete_grey600_24dp" /> + - - \ No newline at end of file + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="start|center_vertical" + android:paddingStart="@dimen/standard_double_padding" + android:paddingEnd="@dimen/standard_padding" + android:textAlignment="viewStart" + android:textColor="@color/high_emphasis_text" + android:textSize="@dimen/bottom_sheet_text_size" + tools:text="Menu item" /> + + From 741b6fefc9455d62980b66a5d8d05749376ddeda Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 7 Feb 2022 21:18:52 +0100 Subject: [PATCH 15/17] Adjust conversation list bottom sheet item to material 3 Signed-off-by: Andy Scherzinger --- .../java/com/nextcloud/talk/adapters/items/MenuItem.java | 2 +- app/src/main/res/layout/rv_item_menu.xml | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/MenuItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/MenuItem.java index 33f335bd2..c7107010f 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/MenuItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/MenuItem.java @@ -50,7 +50,7 @@ public class MenuItem extends AbstractFlexibleItem this.title = title; this.tag = tag; this.icon = icon; - padding = (int) DisplayUtils.convertDpToPixel(16, + padding = (int) DisplayUtils.convertDpToPixel(32, NextcloudTalkApplication.Companion.getSharedApplication().getApplicationContext()); } diff --git a/app/src/main/res/layout/rv_item_menu.xml b/app/src/main/res/layout/rv_item_menu.xml index 1807c7580..7e9ec7fd0 100644 --- a/app/src/main/res/layout/rv_item_menu.xml +++ b/app/src/main/res/layout/rv_item_menu.xml @@ -24,7 +24,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@color/bg_default"> + android:background="@color/bg_default" + android:minHeight="@dimen/bottom_sheet_item_height"> From 4ca9ef75596951c4852e2ad579bf7c6dbcdc6c35 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 7 Feb 2022 21:29:46 +0100 Subject: [PATCH 16/17] bump lint score Signed-off-by: Andy Scherzinger --- scripts/analysis/lint-results.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/analysis/lint-results.txt b/scripts/analysis/lint-results.txt index 96101281e..de06c6be4 100644 --- a/scripts/analysis/lint-results.txt +++ b/scripts/analysis/lint-results.txt @@ -1,2 +1,2 @@ DO NOT TOUCH; GENERATED BY DRONE - Lint Report: 1 error and 222 warnings + Lint Report: 1 error and 223 warnings From 1395d82592af8ce0bcb4b1297f16a32598da4032 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 8 Feb 2022 11:15:50 +0100 Subject: [PATCH 17/17] bump detekt to 1.19.0 Signed-off-by: Andy Scherzinger --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 50d2871e9..66b057b22 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ buildscript { classpath 'com.android.tools.build:gradle:4.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}" classpath 'gradle.plugin.com.github.spotbugs.snom:spotbugs-gradle-plugin:4.7.5' - classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.18.1" + classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.19.0" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files