using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Android;
using UnityEngine.UI;
///
/// This class is used to manage the microphone settings in the UI.
///
namespace Convai.Scripts.Utils
{
public class UIMicrophoneSettings : MonoBehaviour
{
[Tooltip("Dropdown to select the microphone device to use.")]
[SerializeField] private TMP_Dropdown _microphoneSelectDropdown;
[Tooltip("Button to control the recording.")]
[SerializeField] private Button _recordControllerButton;
[Tooltip("Text to display the status of the recording system.")]
[SerializeField] private TextMeshProUGUI _recordSystemStatusText;
///
/// Image component of the recording control button.
///
private Image _buttonImage;
///
/// Text component of the recording control button.
///
private TextMeshProUGUI _buttonText;
///
/// Reference to the MicrophoneManager to subscribe to its events.
///
private MicrophoneTestController _microphoneTestController;
///
/// Index of the selected microphone device.
///
private int _selectedMicrophoneDeviceNumber;
///
/// Initialize references.
///
private void Awake()
{
_microphoneTestController = GetComponent();
_buttonImage = _recordControllerButton.GetComponent();
_buttonText = _recordControllerButton.GetComponentInChildren();
RequestMicrophonePermissions();
}
///
/// Request Microphone permissions on Android or iOS.
///
private void RequestMicrophonePermissions()
{
#if UNITY_ANDROID
if (Permission.HasUserAuthorizedPermission(Permission.Microphone))
{
// Initialize Microphone devices if permission is already granted.
InitializeMicrophoneDevices();
}
else
{
// Request Microphone permission with callback
var callbacks = new PermissionCallbacks();
callbacks.PermissionGranted += PermissionCallbacks_PermissionGranted;
callbacks.PermissionDenied += s => ShowNoMicrophoneDetectedNotification();
callbacks.PermissionDeniedAndDontAskAgain += s => ShowNoMicrophoneDetectedNotification();
Permission.RequestUserPermission(Permission.Microphone, callbacks);
}
#elif UNITY_IOS
// Check Microphone permission on iOS and start coroutine to request permission if not granted.
StartCoroutine(iOSTryToAccessMicrophone());
#endif
}
///
/// Show notification when no microphone is detected.
///
private void ShowNoMicrophoneDetectedNotification()
{
NotificationSystemHandler.Instance.NotificationRequest(NotificationType.NoMicrophoneDetected);
_recordSystemStatusText.text = "No Microphone Detected...";
}
///
/// Subscribe to events when this component is enabled.
///
private void OnEnable()
{
_microphoneTestController.OnRecordStarted += MicrophoneTestControllerOnRecordStarted;
_microphoneTestController.OnRecordCompleted += MicrophoneTestControllerOnRecordCompleted;
_microphoneTestController.OnAudioClipCompleted += MicrophoneTestControllerOnAudioClipCompleted;
UISaveLoadSystem.Instance.OnLoad += UISaveLoadSystem_OnLoad;
UISaveLoadSystem.Instance.OnSave += UISaveLoadSystem_OnSave;
#if !UNITY_ANDROID && !UNITY_IOS
InitializeMicrophoneDevices();
#endif
}
///
/// Unsubscribe from events when this component is disabled.
///
private void OnDisable()
{
_microphoneTestController.OnRecordStarted -= MicrophoneTestControllerOnRecordStarted;
_microphoneTestController.OnRecordCompleted -= MicrophoneTestControllerOnRecordCompleted;
_microphoneTestController.OnAudioClipCompleted -= MicrophoneTestControllerOnAudioClipCompleted;
UISaveLoadSystem.Instance.OnLoad -= UISaveLoadSystem_OnLoad;
UISaveLoadSystem.Instance.OnSave -= UISaveLoadSystem_OnSave;
}
///
/// Initialize the dropdown with available microphone devices after obtaining permission.
///
private void InitializeMicrophoneDevices()
{
_microphoneSelectDropdown.ClearOptions();
_microphoneSelectDropdown.AddOptions(new List(Microphone.devices));
_microphoneSelectDropdown.onValueChanged.AddListener(ChangeSelectedDevice);
_recordSystemStatusText.text = "Waiting For Record...";
// Checking if system has at-least one microphone to record the audio
if (!MicrophoneManager.Instance.HasAnyMicrophoneDevices())
{
ShowNoMicrophoneDetectedNotification();
}
}
///
/// Coroutine to check and request Microphone permission on iOS.
///
private IEnumerator iOSTryToAccessMicrophone()
{
if (Application.HasUserAuthorization(UserAuthorization.Microphone))
{
InitializeMicrophoneDevices();
}
else
{
yield return Application.RequestUserAuthorization(UserAuthorization.Microphone);
if (Application.HasUserAuthorization(UserAuthorization.Microphone))
{
InitializeMicrophoneDevices();
}
else
{
ShowNoMicrophoneDetectedNotification();
}
}
}
///
/// Callback when Microphone permission is granted on Android.
///
/// Permission string
private void PermissionCallbacks_PermissionGranted(string obj)
{
InitializeMicrophoneDevices();
Debug.Log("Permission Granted!!!");
}
///
/// Event handler when the selected microphone device is changed.
///
private void ChangeSelectedDevice(int selectedDeviceNumber)
{
_selectedMicrophoneDeviceNumber = selectedDeviceNumber;
MicrophoneManager.Instance.SetSelectedMicrophoneIndex(selectedDeviceNumber);
UISaveLoadSystem.Instance.SelectedMicrophoneDeviceNumber = _selectedMicrophoneDeviceNumber;
Logger.Info("Microphone Device Updated.", Logger.LogCategory.Character);
}
///
/// Event handler when saved data is loaded.
///
private void UISaveLoadSystem_OnLoad()
{
_microphoneSelectDropdown.value = UISaveLoadSystem.Instance.SelectedMicrophoneDeviceNumber;
Logger.Info("Loaded Microphone Device. ", Logger.LogCategory.Character);
}
///
/// Event handler when data is saved.
///
private void UISaveLoadSystem_OnSave()
{
UISaveLoadSystem.Instance.SelectedMicrophoneDeviceNumber = _microphoneSelectDropdown.value;
}
///
/// Event handler when a recording is started.
///
private void MicrophoneTestControllerOnRecordStarted()
{
_recordSystemStatusText.text = "Recording...";
_buttonImage.color = Color.red;
_buttonText.text = "Stop";
_buttonText.color = new Color(1, 1, 1);
}
///
/// Event handler when a recording is completed.
///
private void MicrophoneTestControllerOnRecordCompleted()
{
_recordSystemStatusText.text = "Playing...";
_buttonImage.color = Color.green;
_buttonText.text = "Rec";
_buttonText.color = new Color(0.14f, 0.14f, 0.14f);
}
///
/// Event handler when the audio clip playback is completed.
///
private void MicrophoneTestControllerOnAudioClipCompleted()
{
_recordSystemStatusText.text = "Waiting For Record...";
}
///
/// Returns the microphone selection dropdown object.
///
public TMP_Dropdown GetMicrophoneSelectDropdown()
{
return _microphoneSelectDropdown;
}
///
/// Returns the record control button object.
///
public Button GetRecordControllerButton()
{
return _recordControllerButton;
}
///
/// Returns the selected microphone device name.
///
public string GetSelectedMicrophoneDeviceName()
{
if (_selectedMicrophoneDeviceNumber < 0 || _selectedMicrophoneDeviceNumber >= _microphoneSelectDropdown.options.Count)
return string.Empty;
return _microphoneSelectDropdown.options[_selectedMicrophoneDeviceNumber].text;
}
}
}