[System.PowerUsage] Introduce Tizen.System.PowerUsage (#1512)
authorpvschakradhar <48746416+pvschakradhar@users.noreply.github.com>
Mon, 13 Apr 2020 03:58:37 +0000 (09:28 +0530)
committerGitHub <noreply@github.com>
Mon, 13 Apr 2020 03:58:37 +0000 (09:28 +0530)
* Addition of Tizen.System.PowerUsage

Addition of Tizen.System.PowerUsage

* Variables renaming and addition of DateTimeOffset

Variables renaming and addition of DateTimeOffset

* Change of  dll to Tizen.System.PowerUsage.dll and  RecordNotFound exception handling

Change of  dll to Tizen.System.PowerUsage.dll and  RecordNotFound exception handling

* Rearrangement for code readability and adition of ArgumentNullException

Rearrangement for code readability and adition of ArgumentNullException

* change in DateTime.SpecifyKind and correction in copyright

change in DateTime.SpecifyKind and correction in copyright

* removal of specify kind in DateTime

removal of specify kind in DateTime

src/Tizen.System.PowerUsage/Interop/Interop.Libraries.cs [new file with mode: 0644]
src/Tizen.System.PowerUsage/Interop/Interop.PowerUsage.cs [new file with mode: 0644]
src/Tizen.System.PowerUsage/PowerUsage/PowerUsage.cs [new file with mode: 0644]
src/Tizen.System.PowerUsage/PowerUsage/PowerUsageExceptionFactory.cs [new file with mode: 0644]
src/Tizen.System.PowerUsage/Tizen.System.PowerUsage.csproj [new file with mode: 0644]
src/Tizen.System.PowerUsage/Tizen.System.PowerUsage.sln [new file with mode: 0644]

diff --git a/src/Tizen.System.PowerUsage/Interop/Interop.Libraries.cs b/src/Tizen.System.PowerUsage/Interop/Interop.Libraries.cs
new file mode 100644 (file)
index 0000000..6271990
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+internal static partial class Interop
+{
+    internal static partial class Libraries
+    {
+        internal const string PowerUsage = "libcapi-system-battery-monitor.so.0";
+    }
+}
diff --git a/src/Tizen.System.PowerUsage/Interop/Interop.PowerUsage.cs b/src/Tizen.System.PowerUsage/Interop/Interop.PowerUsage.cs
new file mode 100644 (file)
index 0000000..fc16a52
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.System;
+
+internal static partial class Interop
+{
+    internal static class PowerUsage
+    {
+        [DllImport(Libraries.PowerUsage, EntryPoint = "battery_monitor_battery_usage_data_destroy")]
+        internal static extern int BatteryUsageDataDestroy(IntPtr dataHandle);
+
+        [DllImport(Libraries.PowerUsage, EntryPoint = "battery_monitor_usage_data_get_power_usage_per_resource")]
+        internal static extern int UsageDataGetPowerUsagePerResource(IntPtr dataHandle, PowerUsageResourceType rtype, out double batteryUsage);
+
+        [DllImport(Libraries.PowerUsage, EntryPoint = "battery_monitor_get_power_usage_by_app_for_all_resources")]
+        internal static extern int GetPowerUsageByAppForAllResources(string appID, long startTime, long endTime, out IntPtr dataHandle);
+
+        [DllImport(Libraries.PowerUsage, EntryPoint = "battery_monitor_get_power_usage_by_app_per_resource")]
+        internal static extern int GetPowerUsageByAppPerResource(string appID, PowerUsageResourceType rtype, long startTime, long endTime, out double batteryUsage);
+
+        [DllImport(Libraries.PowerUsage, EntryPoint = "battery_monitor_get_power_usage_by_app")]
+        internal static extern int GetPowerUsageByApp(string appID, long startTime, long endTime, out double batteryUsage);
+
+        [DllImport(Libraries.PowerUsage, EntryPoint = "battery_monitor_get_power_usage_by_resource")]
+        internal static extern int GetPowerUsageByResource(PowerUsageResourceType rtype, long startTime, long endTime, out double batteryUsage);
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.System.PowerUsage/PowerUsage/PowerUsage.cs b/src/Tizen.System.PowerUsage/PowerUsage/PowerUsage.cs
new file mode 100644 (file)
index 0000000..722f78c
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.System
+{
+    /// <summary>
+    /// Enumeration for battery consuming features.
+    /// </summary>
+    /// <since_tizen> 7 </since_tizen>
+    public enum PowerUsageResourceType
+    {
+        /// <summary>
+        /// Bluetooth Low Energy.
+        /// </summary>
+        Ble = 0,
+
+        /// <summary>
+        /// Wi-Fi.
+        /// </summary>
+        Wifi = 1,
+
+        /// <summary>
+        /// CPU.
+        /// </summary>
+        Cpu = 2,
+
+        /// <summary>
+        /// Display.
+        /// </summary>
+        Display = 3,
+
+        /// <summary>
+        /// Device Network.
+        /// </summary>
+        DeviceNetwork = 4,
+
+        /// <summary>
+        /// GPS Sensor.
+        /// </summary>
+        Gps = 5
+    }
+
+    /// <summary>
+    /// Provides information related to the power consumption by applications or by hardware resources on a battery-powered device for a given duration of time.
+    /// </summary>
+    /// <feature>http://tizen.org/feature/battery</feature>
+    /// <privilege>http://tizen.org/privilege/systemmonitor</privilege>
+    /// <since_tizen> 7 </since_tizen>
+    public static class PowerUsage
+    {
+        /// <summary>
+        /// Gets the battery consumption in mAh(milli-Ampere hour) for the resources specified by the application in custom interval.
+        /// </summary>
+        /// <since_tizen> 7 </since_tizen>
+        /// <param name="appID">Application ID of the application for which battery usage is required.</param>
+        /// <param name="rtypes">list of resource type identifiers like BLE, WiFi, CPU etc.</param>
+        /// <param name="start">Start Time for data in DateTime.</param>
+        /// <param name="end">End Time for data in DateTime.</param>
+        /// <returns>Returns the battery consumption in mAh(milli-Ampere hour) for the resources specified by the application in custom interval.</returns>
+        /// <feature>http://tizen.org/feature/battery</feature>
+        /// <privilege>http://tizen.org/privilege/systemmonitor</privilege>
+        /// <exception cref="ArgumentException">When an invalid parameter value is set.</exception>
+        /// <exception cref="UnauthorizedAccessException">If the privilege is not set.</exception>
+        /// <exception cref="InvalidOperationException">In case of any system error.</exception>
+        /// <exception cref="NotSupportedException">In case power usage is not supported</exception>
+        public static IDictionary<PowerUsageResourceType, double> GetPowerUsage(string appID, IList<PowerUsageResourceType> rtypes, DateTime start, DateTime end)
+        {
+            IntPtr dataHandle = IntPtr.Zero;
+            IDictionary<PowerUsageResourceType, double> batteryUsage = new Dictionary<PowerUsageResourceType, double>();
+            try
+            {
+                PowerUsageError ret = (PowerUsageError)Interop.PowerUsage.GetPowerUsageByAppForAllResources(appID, ((DateTimeOffset)start).ToUnixTimeSeconds(), ((DateTimeOffset)end).ToUnixTimeSeconds(), out dataHandle);
+                if (ret != PowerUsageError.None)
+                {
+                    Log.Error(PowerUsageErrorFactory.LogTag, "Error getting battery usage for all resources" + ret);
+                    throw PowerUsageErrorFactory.ThrowPowerUsageException(ret);
+                }
+
+                if (rtypes != null)
+                {
+                    foreach (PowerUsageResourceType type in rtypes)
+                    {
+                        try
+                        {
+                            batteryUsage[type] = GetPowerUsage(dataHandle, type);
+                        }
+                        catch (InvalidOperationException)
+                        {
+                            Log.Error(PowerUsageErrorFactory.LogTag, $"Error getting battery usage for {type}");
+                        }
+                    }
+                }
+                else
+                {
+                    Log.Error(PowerUsageErrorFactory.LogTag, "Power usage resource types parameter is empty");
+                    throw new ArgumentNullException(nameof(rtypes));
+                }
+            }
+            finally
+            {
+                PowerUsageError ret = (PowerUsageError)Interop.PowerUsage.BatteryUsageDataDestroy(dataHandle);
+                if (ret != PowerUsageError.None)
+                {
+                    Log.Error(PowerUsageErrorFactory.LogTag, "Error in Destroy handle, " + ret);
+                }
+            }
+            return batteryUsage;
+        }
+
+        /// <summary>
+        /// Gets the battery consumption in mAh(milli-Ampere hour) for the specific resource for the given application in custom interval.
+        /// </summary>
+        /// <since_tizen> 7 </since_tizen>
+        /// <param name="appID">Application ID of the application for which battery usage is required.</param>
+        /// <param name="rtype">Identifier of resource type. BLE, WiFi, CPU etc.</param>
+        /// <param name="start">Start Time for data in DateTime.</param>
+        /// <param name="end">End Time for data in DateTime.</param>
+        /// <returns>Returns the battery consumption in mAh(milli-Ampere hour) for the specific resource for the given application in custom interval.</returns>
+        /// <feature>http://tizen.org/feature/battery</feature>
+        /// <privilege>http://tizen.org/privilege/systemmonitor</privilege>
+        /// <exception cref="ArgumentException">When an invalid parameter value is set.</exception>
+        /// <exception cref="UnauthorizedAccessException">If the privilege is not set.</exception>
+        /// <exception cref="InvalidOperationException">In case of any system error.</exception>
+        /// <exception cref="NotSupportedException">In case power usage is not supported</exception>
+        public static double GetPowerUsage(string appID, PowerUsageResourceType rtype, DateTime start, DateTime end)
+        {
+            double batteryUsage = 0;
+            PowerUsageError ret = (PowerUsageError)Interop.PowerUsage.GetPowerUsageByAppPerResource(appID, rtype, ((DateTimeOffset)start).ToUnixTimeSeconds(), ((DateTimeOffset)end).ToUnixTimeSeconds(), out batteryUsage);
+            if (ret != PowerUsageError.None)
+            {
+                if (ret == PowerUsageError.RecordNotFound)
+                {
+                    Log.Error(PowerUsageErrorFactory.LogTag, "Error PowerUsageResourceType is not supported");
+                    throw new ArgumentException($"{rtype} is not supproted", nameof(rtype));
+                }
+                else
+                {
+                    Log.Error(PowerUsageErrorFactory.LogTag, "Error getting battery usage by app per resrource ," + ret);
+                    throw PowerUsageErrorFactory.ThrowPowerUsageException(ret);
+                }
+            }
+            return batteryUsage;
+        }
+
+        /// <summary>
+        /// Gets the total battery usage in mAh(milli-Ampere hour) by an application for certain time interval.
+        /// </summary>
+        /// <since_tizen> 7 </since_tizen>
+        /// <param name="appID">Application ID of the application for which battery usage is required.</param>
+        /// <param name="start">Start Time for data in DateTime.</param>
+        /// <param name="end">End Time for data in DateTime.</param>
+        /// <returns>Returns the total battery usage in mAh(milli-Ampere hour) by an application for certain time interval.</returns>
+        /// <feature>http://tizen.org/feature/battery</feature>
+        /// <privilege>http://tizen.org/privilege/systemmonitor</privilege>
+        /// <exception cref="ArgumentException">When an invalid parameter value is set.</exception>
+        /// <exception cref="UnauthorizedAccessException">If the privilege is not set.</exception>
+        /// <exception cref="InvalidOperationException">In case of any system error.</exception>
+        /// <exception cref="NotSupportedException">In case power usage is not supported</exception>
+        public static double GetPowerUsage(string appID, DateTime start, DateTime end)
+        {
+            double batteryUsage = 0;
+            PowerUsageError ret = (PowerUsageError)Interop.PowerUsage.GetPowerUsageByApp(appID, ((DateTimeOffset)start).ToUnixTimeSeconds(), ((DateTimeOffset)end).ToUnixTimeSeconds(), out batteryUsage);
+            if (ret != PowerUsageError.None)
+            {
+                Log.Error(PowerUsageErrorFactory.LogTag, "Error getting battery usage by app," + ret);
+                throw PowerUsageErrorFactory.ThrowPowerUsageException(ret);
+            }
+            return batteryUsage;
+        }
+
+        /// <summary>
+        /// Gets the battery usage in mAh(milli-Ampere hour) by a resource for certain time interval.
+        /// </summary>
+        /// <since_tizen> 7 </since_tizen>
+        /// <param name="rtype">Identifier of resource type. BLE, WiFi, CPU etc.</param>
+        /// <param name="start">Start Time for data in DateTime.</param>
+        /// <param name="end">End Time for data in DateTime.</param>
+        /// <returns>Returns the battery usage in mAh(milli-Ampere hour) by a resource for certain time interval.</returns>
+        /// <feature>http://tizen.org/feature/battery</feature>
+        /// <privilege>http://tizen.org/privilege/systemmonitor</privilege>
+        /// <exception cref="ArgumentException">When an invalid parameter value is set.</exception>
+        /// <exception cref="UnauthorizedAccessException">If the privilege is not set.</exception>
+        /// <exception cref="InvalidOperationException">In case of any system error.</exception>
+        /// <exception cref="NotSupportedException">In case power usage is not supported</exception>
+        public static double GetPowerUsage(PowerUsageResourceType rtype, DateTime start, DateTime end)
+        {
+            double batteryUsage = 0;
+            PowerUsageError ret = (PowerUsageError)Interop.PowerUsage.GetPowerUsageByResource(rtype, ((DateTimeOffset)start).ToUnixTimeSeconds(), ((DateTimeOffset)end).ToUnixTimeSeconds(), out batteryUsage);
+            if (ret != PowerUsageError.None)
+            {
+                if (ret == PowerUsageError.RecordNotFound)
+                {
+                    Log.Error(PowerUsageErrorFactory.LogTag, "Error PowerUsageResourceType is not supported");
+                    throw new ArgumentException($"{rtype} is not supproted", nameof(rtype));
+                }
+                else
+                {
+                    Log.Error(PowerUsageErrorFactory.LogTag, "Error getting battery usage by resource ," + ret);
+                    throw PowerUsageErrorFactory.ThrowPowerUsageException(ret);
+                }
+            }
+            return batteryUsage;
+        }
+
+        private static double GetPowerUsage(IntPtr dataHandle, PowerUsageResourceType rtype)
+        {
+            double batteryUsage = 0;
+            PowerUsageError ret = (PowerUsageError)Interop.PowerUsage.UsageDataGetPowerUsagePerResource(dataHandle, rtype, out batteryUsage);
+            if (ret != PowerUsageError.None)
+            {
+                Log.Error(PowerUsageErrorFactory.LogTag, "Error getting battery usage for resource" + ret);
+                throw PowerUsageErrorFactory.ThrowPowerUsageException(ret);
+            }
+            return batteryUsage;
+        }
+    }
+}
diff --git a/src/Tizen.System.PowerUsage/PowerUsage/PowerUsageExceptionFactory.cs b/src/Tizen.System.PowerUsage/PowerUsage/PowerUsageExceptionFactory.cs
new file mode 100644 (file)
index 0000000..46c48ba
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.System
+{
+    /// <summary>
+    /// Power Usage error codes.
+    /// </summary>
+    /// <since_tizen> 7 </since_tizen>
+    internal enum PowerUsageError
+    {
+        /// <summary>
+        /// Successful.
+        /// </summary>
+        None = ErrorCode.None,
+
+        /// <summary>
+        /// Out of memory error.
+        /// </summary>
+        OutOfMemory = ErrorCode.OutOfMemory,
+
+        /// <summary>
+        /// Invalid parameter.
+        /// </summary>
+        InvalidParameter = ErrorCode.InvalidParameter,
+
+        /// <summary>
+        /// Permission denied.
+        /// </summary>
+        AcessibilityNotallowed = ErrorCode.PermissionDenied,
+
+        /// <summary>
+        /// Address family not supported.
+        /// </summary>
+        NotSupported = ErrorCode.NotSupported,
+
+        /// <summary>
+        /// Related record does not exist.
+        /// </summary>
+        RecordNotFound = -0x03060000 | 0x01,
+
+        /// <summary>
+        /// DB operation failed .
+        /// </summary>
+        DBFailed = -0x03060000 | 0x02,
+
+        /// <summary>
+        /// DB is not connected.
+        /// </summary>
+        DBNotOpened = -0x03060000 | 0x03,
+
+        /// <summary>
+        /// Internal error for generic use.
+        /// </summary>
+        Internal = -0x03060000 | 0x04
+    }
+
+    internal static class PowerUsageErrorFactory
+    {
+        internal const string LogTag = "Tizen.System.PowerUsage";
+        internal static Exception ThrowPowerUsageException(PowerUsageError errCode)
+        {
+            Log.Error(LogTag, "Throw PowerUsage Exception : " + errCode);
+
+            switch (errCode)
+            {
+                case PowerUsageError.OutOfMemory:
+                    return new InvalidOperationException("Out of memory");
+                case PowerUsageError.InvalidParameter:
+                    return new ArgumentException("Invalid Parameter passed");
+                case PowerUsageError.AcessibilityNotallowed:
+                    return new UnauthorizedAccessException("Permission denied");
+                case PowerUsageError.NotSupported:
+                    return new NotSupportedException("Not supported");
+                case PowerUsageError.RecordNotFound:
+                    return new InvalidOperationException("Related record does not exist");
+                case PowerUsageError.DBFailed:
+                    return new InvalidOperationException("DB operation failed");
+                case PowerUsageError.DBNotOpened:
+                    return new InvalidOperationException("DB is not connected");
+                case PowerUsageError.Internal:
+                    return new InvalidOperationException("Internal error for generic use");
+                default:
+                    return new InvalidOperationException("Unknown Error");
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.System.PowerUsage/Tizen.System.PowerUsage.csproj b/src/Tizen.System.PowerUsage/Tizen.System.PowerUsage.csproj
new file mode 100644 (file)
index 0000000..2648db5
--- /dev/null
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netstandard2.0</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+    <ProjectReference Include="..\Tizen\Tizen.csproj" />
+  </ItemGroup>
+
+
+</Project>
diff --git a/src/Tizen.System.PowerUsage/Tizen.System.PowerUsage.sln b/src/Tizen.System.PowerUsage/Tizen.System.PowerUsage.sln
new file mode 100644 (file)
index 0000000..ff67f39
--- /dev/null
@@ -0,0 +1,69 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26124.0
+MinimumVisualStudioVersion = 15.0.26124.0
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.System.PowerUsage", "Tizen.System.PowerUsage.csproj", "{C4007463-E96F-43B7-91A8-52B94A4951EF}"
+       ProjectSection(ProjectDependencies) = postProject
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC} = {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC} = {BB810DE4-4F52-468F-B68C-408F958CAEFC}
+       EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen", "..\Tizen\Tizen.csproj", "{BB810DE4-4F52-468F-B68C-408F958CAEFC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Log", "..\Tizen.Log\Tizen.Log.csproj", "{64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Debug|x64 = Debug|x64
+               Debug|x86 = Debug|x86
+               Release|Any CPU = Release|Any CPU
+               Release|x64 = Release|x64
+               Release|x86 = Release|x86
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Debug|x64.ActiveCfg = Debug|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Debug|x64.Build.0 = Debug|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Debug|x86.Build.0 = Debug|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Release|Any CPU.Build.0 = Release|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Release|x64.ActiveCfg = Release|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Release|x64.Build.0 = Release|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Release|x86.ActiveCfg = Release|Any CPU
+               {C4007463-E96F-43B7-91A8-52B94A4951EF}.Release|x86.Build.0 = Release|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Debug|x64.ActiveCfg = Debug|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Debug|x64.Build.0 = Debug|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Debug|x86.Build.0 = Debug|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Release|Any CPU.Build.0 = Release|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Release|x64.ActiveCfg = Release|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Release|x64.Build.0 = Release|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Release|x86.ActiveCfg = Release|Any CPU
+               {BB810DE4-4F52-468F-B68C-408F958CAEFC}.Release|x86.Build.0 = Release|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Debug|x64.ActiveCfg = Debug|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Debug|x64.Build.0 = Debug|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Debug|x86.Build.0 = Debug|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Release|Any CPU.Build.0 = Release|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Release|x64.ActiveCfg = Release|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Release|x64.Build.0 = Release|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Release|x86.ActiveCfg = Release|Any CPU
+               {64F7D1C0-2E3C-4E80-B81D-D0B70A3448FC}.Release|x86.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(ExtensibilityGlobals) = postSolution
+               SolutionGuid = {A33C2591-BFEA-4BCC-890D-C205A7D9B990}
+       EndGlobalSection
+EndGlobal