--- /dev/null
+/*
+* 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";
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+<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>
--- /dev/null
+
+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