Skip to content

Commit

Permalink
Windows 10 Anniversary Update - March 2017 Update
Browse files Browse the repository at this point in the history
  • Loading branch information
oldnewthing committed Mar 2, 2017
2 parents 2bee2a4 + c857fa2 commit c29f596
Show file tree
Hide file tree
Showing 49 changed files with 1,460 additions and 634 deletions.
3 changes: 2 additions & 1 deletion Samples/Accelerometer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ When you choose the **Enable** button for the **Data Events** option, the app be

When you choose the **Enable** button for the **Shake Events** option, the app displays the cumulative number of shake events each time an event occurs. (The app first increments the event count and then renders the most recent value.)

Note that shake events are not supported in Windows 10 build 10240, so the Shaken event will never be raised, but the sample demonstrates how to handle the event when support for shake is added.
Note that support for the Shaken event is dependent upon hardware and driver support.
In practice, very few accelerometers support the Shaken event.

### Poll Accelerometer Readings

Expand Down
5 changes: 4 additions & 1 deletion Samples/Accelerometer/js/html/scenario2_ShakeEvents.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
<h2 id="sampleHeader" class="win-type-subheader">Description:</h2>
<div id="scenarioDescription">Shake events</div>

<p>Registers an event listener for accelerometer shake events and displays the cumulative count of shake events.</p>
<p>
Registers an event listener for accelerometer shake events and displays the cumulative count of shake events.
Note that not all accelerometers report shake events.
</p>
<p>
<button class="win-button" id="scenarioEnable" disabled>Enable</button>
<button class="win-button" id="scenarioDisable" disabled>Disable</button>
Expand Down
5 changes: 4 additions & 1 deletion Samples/Accelerometer/shared/Scenario2_ShakeEvents.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
<StackPanel>
<TextBlock Text="Description:" Style="{StaticResource SampleHeaderTextStyle}"/>
<TextBlock Style="{StaticResource ScenarioDescriptionTextStyle}" Text="Shake events"/>
<TextBlock TextWrapping="Wrap" Text="Registers an event listener for accelerometer shake events and displays the cumulative count of shake events."/>
<TextBlock TextWrapping="Wrap">
Registers an event listener for accelerometer shake events and displays the cumulative count of shake events.
Note that not all accelerometers report shake events.
</TextBlock>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Button x:Name="ScenarioEnableButton" Content="Enable" Margin="0,0,10,0" Click="{x:Bind ScenarioEnable}" IsEnabled="False"/>
<Button x:Name="ScenarioDisableButton" Content="Disable" Margin="0,0,10,0" Click="{x:Bind ScenarioDisable}" IsEnabled="False"/>
Expand Down
53 changes: 52 additions & 1 deletion Samples/Altimeter/cpp/SampleConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,59 @@

using namespace SDKTemplate;

Platform::Array<Scenario>^ MainPage::scenariosInner = ref new Platform::Array<Scenario>
using namespace Concurrency;
using namespace Platform;
using namespace Windows::Devices::Enumeration;
using namespace Windows::Devices::Sensors;
using namespace Windows::Foundation::Metadata;

Array<Scenario>^ MainPage::scenariosInner = ref new Array<Scenario>
{
{ "Data Events", "SDKTemplate.Scenario1_DataEvents" },
{ "Polling", "SDKTemplate.Scenario2_Polling" }
};

// This works around an issue in the Anniversary Update (1607) in which
// Altimeter::GetDefault() returns a nonfunctional altimeter if the
// system has no altimeter. This issue does not exist in other versions
// of Windows 10, but the workaround is harmless to use even on versions
// which do not have this problem. The workaround returns the default
// altimeter only after we confirm that the system has a working altimeter.

task<Altimeter^> MainPage::GetDefaultAltimeterAsync()
{
// Run this task only once, and cache the result.
static task<Altimeter^> altimeterTask = []()
{
// This workaround is needed only on the Anniversary Update (universal contract 3).
if (!ApiInformation::IsApiContractPresent("Windows.Foundation.UniversalApiContract", 3) ||
ApiInformation::IsApiContractPresent("Windows.Foundation.UniversalApiContract", 4))
{
// The current system does not require the workaround.
return task_from_result(Altimeter::GetDefault());
}

String^ deviceSelector =
// Find all interface classes for altimeter sensors
L"System.Devices.InterfaceClassGuid:=\"{0E903829-FF8A-4A93-97DF-3DCBDE402288}\""
// ... that are present on the system
L" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True";

DeviceWatcher^ watcher = DeviceInformation::CreateWatcher(deviceSelector);
task_completion_event<Altimeter^> tce;
watcher->Added += ref new Windows::Foundation::TypedEventHandler<DeviceWatcher^, DeviceInformation^>(
[tce](DeviceWatcher^, DeviceInformation^) { tce.set(Altimeter::GetDefault()); });
watcher->EnumerationCompleted += ref new Windows::Foundation::TypedEventHandler<DeviceWatcher^, Object^>(
[tce](DeviceWatcher^, Object^) { tce.set(nullptr); });
watcher->Start();

return task<Altimeter^>(tce).then([watcher](task<Altimeter^> previousTask)
{
// No matter what happens, make sure we stop the watcher.
watcher->Stop();
return previousTask;
});
}();

return altimeterTask;
}
2 changes: 2 additions & 0 deletions Samples/Altimeter/cpp/SampleConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ namespace SDKTemplate
}
}

static Concurrency::task<Windows::Devices::Sensors::Altimeter^> GetDefaultAltimeterAsync();

private:
static Platform::Array<Scenario>^ scenariosInner;
};
Expand Down
47 changes: 22 additions & 25 deletions Samples/Altimeter/cpp/Scenario1_DataEvents.xaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,11 @@ using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Navigation;

using namespace Concurrency;

Scenario1_DataEvents::Scenario1_DataEvents() : rootPage(MainPage::Current), desiredReportIntervalMs(0)
{
InitializeComponent();

sensor = Altimeter::GetDefault();
if (nullptr != sensor)
{
// Select a report interval that is both suitable for the purposes of the app and supported by the sensor.
// This value will be used later to activate the sensor.
uint32 minReportIntervalMs = sensor->MinimumReportInterval;
desiredReportIntervalMs = minReportIntervalMs > 1000 ? minReportIntervalMs : 1000;
}
else
{
rootPage->NotifyUser("No altimeter found", NotifyType::ErrorMessage);
}
}

/// <summary>
Expand Down Expand Up @@ -124,21 +113,29 @@ void Scenario1_DataEvents::ReadingChanged(Altimeter^ sender, AltimeterReadingCha

void Scenario1_DataEvents::ScenarioEnable(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (nullptr != sensor)
ScenarioEnableButton->IsEnabled = false;
MainPage::GetDefaultAltimeterAsync().then([this](Altimeter^ result)
{
// Establish the report interval
sensor->ReportInterval = desiredReportIntervalMs;
sensor = result;
if (nullptr != sensor)
{
// Select a report interval that is both suitable for the purposes of the app and supported by the sensor.
uint32 minReportIntervalMs = sensor->MinimumReportInterval;
desiredReportIntervalMs = minReportIntervalMs > 1000 ? minReportIntervalMs : 1000;
sensor->ReportInterval = desiredReportIntervalMs;

visibilityToken = Window::Current->VisibilityChanged::add(ref new WindowVisibilityChangedEventHandler(this, &Scenario1_DataEvents::VisibilityChanged));
readingToken = sensor->ReadingChanged::add(ref new TypedEventHandler<Altimeter^, AltimeterReadingChangedEventArgs^>(this, &Scenario1_DataEvents::ReadingChanged));
visibilityToken = Window::Current->VisibilityChanged::add(ref new WindowVisibilityChangedEventHandler(this, &Scenario1_DataEvents::VisibilityChanged));
readingToken = sensor->ReadingChanged::add(ref new TypedEventHandler<Altimeter^, AltimeterReadingChangedEventArgs^>(this, &Scenario1_DataEvents::ReadingChanged));

ScenarioEnableButton->IsEnabled = false;
ScenarioDisableButton->IsEnabled = true;
}
else
{
rootPage->NotifyUser("No Altimeter found", NotifyType::ErrorMessage);
}
ScenarioEnableButton->IsEnabled = false;
ScenarioDisableButton->IsEnabled = true;
}
else
{
ScenarioEnableButton->IsEnabled = true;
rootPage->NotifyUser("No Altimeter found", NotifyType::ErrorMessage);
}
}, task_continuation_context::get_current_winrt_context());
}

void Scenario1_DataEvents::ScenarioDisable(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
Expand Down
29 changes: 14 additions & 15 deletions Samples/Altimeter/cpp/Scenario2_Polling.xaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

using namespace SDKTemplate;

using namespace Concurrency;
using namespace Platform;
using namespace Windows::Devices::Sensors;
using namespace Windows::Foundation;
Expand All @@ -30,26 +31,24 @@ using namespace Windows::UI::Xaml::Navigation;
Scenario2_Polling::Scenario2_Polling() : rootPage(MainPage::Current)
{
InitializeComponent();

sensor = Altimeter::GetDefault();
if (nullptr == sensor)
{
rootPage->NotifyUser("No altimeter found", NotifyType::ErrorMessage);
}
}

void Scenario2_Polling::ScenarioGetData(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (nullptr != sensor)
MainPage::GetDefaultAltimeterAsync().then([this](Altimeter^ result)
{
AltimeterReading^ reading = sensor->GetCurrentReading();
if (nullptr != reading)
sensor = result;
if (nullptr != sensor)
{
ScenarioOutput_M->Text = reading->AltitudeChangeInMeters.ToString();
AltimeterReading^ reading = sensor->GetCurrentReading();
if (nullptr != reading)
{
ScenarioOutput_M->Text = reading->AltitudeChangeInMeters.ToString();
}
}
}
else
{
rootPage->NotifyUser("No altimeter found", NotifyType::ErrorMessage);
}
else
{
rootPage->NotifyUser("No altimeter found", NotifyType::ErrorMessage);
}
}, task_continuation_context::get_current_winrt_context());
}
1 change: 1 addition & 0 deletions Samples/Altimeter/cpp/Scenario2_Polling.xaml.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace SDKTemplate
SDKTemplate::MainPage^ rootPage;
Windows::UI::Core::CoreDispatcher^ dispatcher;
Windows::Devices::Sensors::Altimeter^ sensor;

void ScenarioGetData(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
};
}
48 changes: 48 additions & 0 deletions Samples/Altimeter/cs/SampleConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Devices.Sensors;
using Windows.Foundation.Metadata;
using Windows.UI.Xaml.Controls;

namespace SDKTemplate
Expand All @@ -24,8 +27,53 @@ public partial class MainPage : Page
new Scenario() { Title = "Data Events", ClassType = typeof(Scenario1_DataEvents) },
new Scenario() { Title = "Polling", ClassType = typeof(Scenario2_Polling) }
};

// This works around an issue in the Anniversary Update (1607) in which
// Altimeter.GetDefault() returns a nonfunctional altimeter if the
// system has no altimeter. This issue does not exist in other versions
// of Windows 10, but the workaround is harmless to use even on versions
// which do not have this problem. The workaround returns the default
// altimeter only after we confirm that the system has a working altimeter.

private static async Task<Altimeter> GetDefaultAltimeterWorkerAsync()
{
// This workaround is needed only on the Anniversary Update (universal contract 3).
if (!ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 3) ||
ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 4))
{
// The current system does not require the workaround.
return Altimeter.GetDefault();
}

var tcs = new TaskCompletionSource<Altimeter>();

string deviceSelector =
// Find all interface classes for altimeter sensors
"System.Devices.InterfaceClassGuid:=\"{0E903829-FF8A-4A93-97DF-3DCBDE402288}\"" +
// ... that are present on the system
" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True";

var watcher = Windows.Devices.Enumeration.DeviceInformation.CreateWatcher(deviceSelector);

watcher.Added += (s, e) => tcs.TrySetResult(Altimeter.GetDefault());
watcher.EnumerationCompleted += (s, e) => tcs.TrySetResult(null);
watcher.Start();
Altimeter altimeter = await tcs.Task;
watcher.Stop();
return altimeter;
}

// Run this task only once, and cache the result.
private static Lazy<Task<Altimeter>> defaultAltimeterLazy =
new Lazy<Task<Altimeter>>(GetDefaultAltimeterWorkerAsync, System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);

public static Task<Altimeter> GetDefaultAltimeterAsync()
{
return defaultAltimeterLazy.Value;
}
}


public class Scenario
{
public string Title { get; set; }
Expand Down
22 changes: 7 additions & 15 deletions Samples/Altimeter/cs/Scenario1_DataEvents.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,6 @@ public sealed partial class Scenario1_DataEvents : Page
public Scenario1_DataEvents()
{
this.InitializeComponent();

sensor = Altimeter.GetDefault();
if (null != sensor)
{
// Select a report interval that is both suitable for the purposes of the app and supported by the sensor.
// This value will be used later to activate the sensor.
uint minReportIntervalMs = sensor.MinimumReportInterval;
desiredReportIntervalMs = minReportIntervalMs > 1000 ? minReportIntervalMs : 1000;
}
else
{
rootPage.NotifyUser("No altimeter found", NotifyType.ErrorMessage);
}
}

/// <summary>
Expand Down Expand Up @@ -124,11 +111,15 @@ await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ScenarioEnable(object sender, RoutedEventArgs e)
private async void ScenarioEnable(object sender, RoutedEventArgs e)
{
ScenarioEnableButton.IsEnabled = false;
sensor = await MainPage.GetDefaultAltimeterAsync();
if (null != sensor)
{
// Establish the report interval
// Set a report interval that is both suitable for the purposes of the app and supported by the sensor.
uint minReportIntervalMs = sensor.MinimumReportInterval;
desiredReportIntervalMs = minReportIntervalMs > 1000 ? minReportIntervalMs : 1000;
sensor.ReportInterval = desiredReportIntervalMs;

Window.Current.VisibilityChanged += new WindowVisibilityChangedEventHandler(VisibilityChanged);
Expand All @@ -139,6 +130,7 @@ private void ScenarioEnable(object sender, RoutedEventArgs e)
}
else
{
ScenarioEnableButton.IsEnabled = true;
rootPage.NotifyUser("No altimeter found", NotifyType.ErrorMessage);
}
}
Expand Down
9 changes: 2 additions & 7 deletions Samples/Altimeter/cs/Scenario2_Polling.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,16 @@ public sealed partial class Scenario2_Polling : Page
public Scenario2_Polling()
{
this.InitializeComponent();

sensor = Altimeter.GetDefault();
if (null == sensor)
{
rootPage.NotifyUser("No altimeter found", NotifyType.ErrorMessage);
}
}

/// <summary>
/// This is the click handler for the 'GetData' button.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ScenarioGetData(object sender, RoutedEventArgs e)
private async void ScenarioGetData(object sender, RoutedEventArgs e)
{
sensor = await MainPage.GetDefaultAltimeterAsync();
if (null != sensor)
{
AltimeterReading reading = sensor.GetCurrentReading();
Expand Down
Loading

0 comments on commit c29f596

Please sign in to comment.