Skip to content

Instantly share code, notes, and snippets.

@mattdot
Last active August 29, 2015 14:05
Show Gist options
  • Save mattdot/f5f415e2f4646d5d7c51 to your computer and use it in GitHub Desktop.
Save mattdot/f5f415e2f4646d5d7c51 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Windows.Devices.Enumeration;
using Windows.Media.Devices;
namespace HeadphoneJackDetection
{
public sealed class JackPrescenceEventArgs : EventArgs
{
public bool IsPresent { get; set; }
}
public delegate void JackPresenceChangedEventHandler(object sender, JackPrescenceEventArgs args);
public sealed class JackPrescenceWatcher
{
private const string AudioEndpointFormFactorProperty = "{1da5d803-d492-4edd-8c23-e0c0ffee7f0e} 0";
private static readonly string[] props = new string[] {
AudioEndpointFormFactorProperty, //"PKEY_AudioEndpoint_FormFactor",
};
private Windows.Devices.Enumeration.DeviceWatcher watcher;
public JackPrescenceWatcher()
{
//var selector = MediaDevice.GetAudioRenderSelector();
var selector = "System.Devices.InterfaceClassGuid:=\"{e6327cad-dcec-4949-ae8a-991e976a79d2}\"";
watcher = DeviceInformation.CreateWatcher(selector, props);
watcher.Added += HandleDeviceAdded;
watcher.Updated += HandleDeviceUpdated;
watcher.Removed += HandleDeviceRemoved;
}
/// <summary>
/// Start watching for insertion or removal
/// </summary>
public void Start()
{
watcher.Start();
}
/// <summary>
/// Stop watching for insertion or removal
/// </summary>
public void Stop()
{
watcher.Stop();
}
/// <summary>
/// Raised when an insertion or removal is deteced from the headphone jack.
/// </summary>
public event JackPresenceChangedEventHandler JackPresenceChanged;
private void OnJackPresenceChanged(bool isPresent)
{
if (null != this.JackPresenceChanged)
{
this.JackPresenceChanged(this, new JackPrescenceEventArgs { IsPresent = isPresent });
}
}
private async void HandleDeviceUpdated(DeviceWatcher sender, DeviceInformationUpdate args)
{
var info = await Windows.Devices.Enumeration.DeviceInformation.CreateFromIdAsync(args.Id, props);
OnDeviceChanged(args.Id, info);
}
private void HandleDeviceAdded(Windows.Devices.Enumeration.DeviceWatcher sender, Windows.Devices.Enumeration.DeviceInformation args)
{
OnDeviceChanged(args.Id, args);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
/// <remarks>
/// may need to watch for known devices getting physically removed from the system. In that case
/// info will be null and we'll only have id to know it was removed. May need to keep a cache
/// of known deviceId's to watch for physical removal of one we care about. Unlikely scenario for
/// the whole headphone jack to be removed, but possible.
/// </remarks>
async void HandleDeviceRemoved(DeviceWatcher sender, DeviceInformationUpdate args)
{
var info = await Windows.Devices.Enumeration.DeviceInformation.CreateFromIdAsync(args.Id, props);
OnDeviceChanged(args.Id, info);
}
private void OnDeviceChanged(string deviceId, DeviceInformation info)
{
object temp;
if (null != info)
{
if (info.Properties.TryGetValue(AudioEndpointFormFactorProperty, out temp))
{
AudioEndpointFormFactor ff = (AudioEndpointFormFactor)Convert.ToInt32(temp);
if (ff == AudioEndpointFormFactor.Headphones || ff == AudioEndpointFormFactor.Headset)
{
if (info.Properties.TryGetValue("System.Devices.InterfaceEnabled", out temp))
{
bool isInserted = (bool)temp;
OnJackPresenceChanged(isInserted);
}
}
}
}
}
private enum AudioEndpointFormFactor
{
RemoteNetworkDevice = 0,
Speakers = 1,
LineLevel = 2,
Headphones = 3,
Microphone = 4,
Headset = 5,
Handset = 6,
UnknownDigitalPassthrough = 7,
SPDIF = 8,
DigitalAudioDisplayDeviceHDMI = 9,
UnknownFormFactor = 10
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment