Check if a Capability is enabled in WMAppManifest on Windows Phone 7

While Microsoft provides the handy Capability Detection Tool to determine what Capabilities are required for your application there are scenarios, one being that you are a provider windows phone 7 library, where you may want to check at runtime what capabilities are present in the WMAppManifest.xml. This post will provide a helper class to check each if each capability is present.

Note: This post leverages the great work done by Nick Randolph to gain access to the WMAppManifest.xml for access to the Application Product ID in his blogpost here

The helper class is as follows:

using Microsoft.Xna.Framework;
using System.Linq;
using System.Xml.Linq;
using System.Collections.Generic;

namespace www.NickHarris.NET
{
    public static class CapabilityHelper
    {
        private const string WMAppManifest = "WMAppManifest.xml";
        private const string ID_CAP_NETWORKING = "ID_CAP_NETWORKING";
        private const string ID_CAP_IDENTITY_DEVICE = "ID_CAP_IDENTITY_DEVICE";
        private const string ID_CAP_IDENTITY_USER = "ID_CAP_IDENTITY_USER";
        private const string ID_CAP_LOCATION = "ID_CAP_LOCATION";
        private const string ID_CAP_SENSORS = "ID_CAP_SENSORS";
        private const string ID_CAP_MICROPHONE = "ID_CAP_MICROPHONE";
        private const string ID_CAP_MEDIALIB = "ID_CAP_MEDIALIB";
        private const string ID_CAP_GAMERSERVICES = "ID_CAP_GAMERSERVICES";
        private const string ID_CAP_PHONEDIALER = "ID_CAP_PHONEDIALER";
        private const string ID_CAP_PUSH_NOTIFICATION = "ID_CAP_PUSH_NOTIFICATION";
        private const string ID_CAP_WEBBROWSERCOMPONENT = "ID_CAP_WEBBROWSERCOMPONENT";
        private const string CAPABILITIES = "Capabilities";
        private const string NAME = "Name";

        static CapabilityHelper()
        {
            using (var strm = TitleContainer.OpenStream(WMAppManifest))
            {
                var xml = XElement.Load(strm);
                var capabilities = xml.Descendants(CAPABILITIES).Elements();

                IsNetworkingCapability = CheckCapability(capabilities, ID_CAP_NETWORKING);
                IsDeviceIdentityCapability = CheckCapability(capabilities, ID_CAP_IDENTITY_DEVICE);
                IsUserIdentityCapability = CheckCapability(capabilities, ID_CAP_IDENTITY_USER);
                IsLocationCapability = CheckCapability(capabilities, ID_CAP_LOCATION);
                IsSensorsCapability = CheckCapability(capabilities, ID_CAP_SENSORS);
                IsMicrophoneCapability = CheckCapability(capabilities, ID_CAP_MICROPHONE);
                IsMediaLibCapability = CheckCapability(capabilities, ID_CAP_MEDIALIB);
                IsGamerServicesCapability = CheckCapability(capabilities, ID_CAP_GAMERSERVICES);
                IsPhoneDialerCapability = CheckCapability(capabilities, ID_CAP_PHONEDIALER);
                IsPushNotificationCapability = CheckCapability(capabilities, ID_CAP_PUSH_NOTIFICATION);
                IsWebBrowserComponentCapability = CheckCapability(capabilities, ID_CAP_WEBBROWSERCOMPONENT);
            }
        }

        public static bool IsNetworkingCapability { get; set; }
        public static bool IsDeviceIdentityCapability { get; set; }
        public static bool IsUserIdentityCapability { get; set; }
        public static bool IsLocationCapability { get; set; }
        public static bool IsSensorsCapability { get; set; }
        public static bool IsMicrophoneCapability { get; set; }
        public static bool IsMediaLibCapability { get; set; }
        public static bool IsGamerServicesCapability { get; set; }
        public static bool IsPhoneDialerCapability { get; set; }
        public static bool IsPushNotificationCapability { get; set; }
        public static bool IsWebBrowserComponentCapability { get; set; }

        private static bool CheckCapability(IEnumerable<XElement> capabilities, string capabilityName)
        {
            var capability = capabilities.FirstOrDefault(n => n.Attribute(NAME).Value.Equals(capabilityName));
            return capability != null;
        }      
    }
}

Note: You will need to add a reference to the Microsoft.XNA.Framework.dll for the helper to build. If you are concerned about the warning that shows up when adding a reference to this assembly from within a Silverlight application, rest assured, that it is possible to utilize most, but not all, XNA assemblies in a WP7 Silverlight Application as documented here on msdn. Scroll down to the section Using Classes Across Frameworks to see exclusions.

Usage is then as simple as

   if (!CapabilityHelper.IsUserIdentityCapability)
     //capability not present, do something

Enjoy,
Nick