Skip to content

Commit

Permalink
Windows 10 RTM Release - February 2017 Update
Browse files Browse the repository at this point in the history
  • Loading branch information
oldnewthing committed Feb 9, 2017
1 parent 079d8e8 commit 4c824c9
Show file tree
Hide file tree
Showing 40 changed files with 302 additions and 169 deletions.
2 changes: 1 addition & 1 deletion Samples/Accelerometer/js/js/scenario1_DataEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
// This is the event handler for VisibilityChanged events. You would register for these notifications
// if handling sensor data when the app is not visible could cause unintended actions in the app.
if (!scenarioDisable.disabled) {
if (document.msVisibilityState === "visible") {
if (document.visibilityState === "visible") {
// Re-enable sensor input. No need to restore the desired reportInterval (it is restored for us upon app resume)
accelerometer.addEventListener("readingchanged", onDataChanged);
} else {
Expand Down
2 changes: 1 addition & 1 deletion Samples/Accelerometer/js/js/scenario2_ShakeEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
// This is the event handler for VisibilityChanged events. You would register for these notifications
// if handling sensor data when the app is not visible could cause unintended actions in the app.
if (!scenarioDisable.disabled) {
if (document.msVisibilityState === "visible") {
if (document.visibilityState === "visible") {
// Re-enable sensor input
accelerometer.addEventListener("shaken", onShaken);
} else {
Expand Down
2 changes: 1 addition & 1 deletion Samples/Accelerometer/js/js/scenario3_Polling.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
// This is the event handler for VisibilityChanged events. You would register for these notifications
// if handling sensor data when the app is not visible could cause unintended actions in the app.
if (!scenarioDisable.disabled) {
if (document.msVisibilityState === "visible") {
if (document.visibilityState === "visible") {
// Resume polling. No need to restore the desired reportInterval (it is restored for us upon app resume)
intervalId = setInterval(getCurrentReading, reportInterval);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
// This is the event handler for VisibilityChanged events. You would register for these notifications
// if handling sensor data when the app is not visible could cause unintended actions in the app.
if (!scenarioDisable.disabled) {
if (document.msVisibilityState === "visible") {
if (document.visibilityState === "visible") {
// Re-enable sensor input. No need to restore the desired reportInterval (it is restored for us upon app resume)
accelerometerOriginal.addEventListener("readingchanged", onDataChangedOriginal);
accelerometerReadingTransform.addEventListener("readingchanged", onDataChangedReadingTransform);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
// This is the event handler for VisibilityChanged events. You would register for these notifications
// if handling sensor data when the app is not visible could cause unintended actions in the app.
if (!scenarioDisable.disabled) {
if (document.msVisibilityState === "visible") {
if (document.visibilityState === "visible") {
// Re-enable sensor input. No need to restore the desired reportInterval (it is restored for us upon app resume)
accelerometer.addEventListener("readingchanged", onDataChanged);
} else {
Expand Down
2 changes: 1 addition & 1 deletion Samples/Altimeter/js/js/scenario1_DataEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
// This is the event handler for VisibilityChanged events. You would register for these notifications
// if handling sensor data when the app is not visible could cause unintended actions in the app.
if (document.getElementById("scenario1Open").disabled) {
if (document.msVisibilityState === "visible") {
if (document.visibilityState === "visible") {
// Re-enable sensor input. No need to restore the desired desiredReportIntervalMs (it is restored for us upon app resume)
altimeter.addEventListener("readingchanged", onDataChanged);
} else {
Expand Down
2 changes: 1 addition & 1 deletion Samples/Barometer/js/js/scenario1_DataEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
// This is the event handler for VisibilityChanged events. You would register for these notifications
// if handling sensor data when the app is not visible could cause unintended actions in the app.
if (document.getElementById("scenario1Open").disabled) {
if (document.msVisibilityState === "visible") {
if (document.visibilityState === "visible") {
// Re-enable sensor input. No need to restore the desired desiredReportIntervalMs (it is restored for us upon app resume)
barometer.addEventListener("readingchanged", onDataChanged);
} else {
Expand Down
115 changes: 77 additions & 38 deletions Samples/CameraStarterKit/cpp/MainPage.xaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,10 @@ MainPage::MainPage()

// Do not cache the state of the UI when suspending/navigating
Page::NavigationCacheMode = Navigation::NavigationCacheMode::Disabled;

// Useful to know when to initialize/clean up the camera
_applicationSuspendingEventToken =
Application::Current->Suspending += ref new SuspendingEventHandler(this, &MainPage::Application_Suspending);
_applicationResumingEventToken =
Application::Current->Resuming += ref new EventHandler<Object^>(this, &MainPage::Application_Resuming);
}

MainPage::~MainPage()
{
Application::Current->Suspending -= _applicationSuspendingEventToken;
Application::Current->Resuming -= _applicationResumingEventToken;
}

/// <summary>
Expand Down Expand Up @@ -433,6 +425,48 @@ void MainPage::UpdateCaptureControls()
}
}

/// <summary>
/// Initialize or clean up the camera and our UI,
/// depending on the page state.
/// </summary>
/// <returns></returns>
Concurrency::task<void> MainPage::SetUpBasedOnStateAsync()
{
// Avoid reentrancy: Wait until nobody else is in this function.
while (!_setupTask.is_done())
{
return _setupTask.then([this]() { return SetUpBasedOnStateAsync(); },
task_continuation_context::get_current_winrt_context());
}

// We want our UI to be active if
// * We are the current active page.
// * The window is visible.
// * The app is not suspending.
bool wantUIActive = _isActivePage && Window::Current->Visible && !_isSuspending;

if (_isUIActive != wantUIActive)
{
_isUIActive = wantUIActive;

if (wantUIActive)
{
_setupTask = SetupUiAsync().then([this]()
{
return InitializeCameraAsync();
}, task_continuation_context::get_current_winrt_context());
}
else
{
_setupTask = CleanupCameraAsync().then([this]()
{
return CleanupUiAsync();
}, task_continuation_context::get_current_winrt_context());
}
}
return _setupTask;
}

/// <summary>
/// Attempts to lock the page orientation, hide the StatusBar (on Phone) and registers event handlers for hardware buttons and orientation sensors
/// </summary>
Expand All @@ -458,7 +492,7 @@ task<void> MainPage::SetupUiAsync()
}
else
{
return EmptyTask();
return task_from_result();
}
}

Expand All @@ -480,7 +514,7 @@ task<void> MainPage::CleanupUiAsync()
}
else
{
return EmptyTask();
return task_from_result();
}
}

Expand Down Expand Up @@ -553,16 +587,6 @@ void MainPage::WriteException(Exception^ ex)
OutputDebugString(wStringstream.str().c_str());
}

/// <summary>
/// Sometimes we need to conditionally return a task. If certain parameters are not met we cannot
/// return null, but we can return a task that does nothing.
/// </summary>
/// <returns></returns>
task<void> MainPage::EmptyTask()
{
return create_task([] {});
}

/// <summary>
/// Calculates the current camera orientation from the device orientation by taking into account whether the camera is external or facing the user
/// </summary>
Expand Down Expand Up @@ -705,29 +729,31 @@ void MainPage::UpdateButtonOrientation()

void MainPage::Application_Suspending(Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e)
{
// Handle global application events only if this page is active
if (Frame->CurrentSourcePageType.Name == Interop::TypeName(MainPage::typeid).Name)
_isSuspending = true;

auto deferral = e->SuspendingOperation->GetDeferral();
Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([this, deferral]()
{
auto deferral = e->SuspendingOperation->GetDeferral();
CleanupUiAsync()
.then([this, deferral]()
{
CleanupCameraAsync();
}).then([this, deferral]()
SetUpBasedOnStateAsync().then([deferral]()
{
deferral->Complete();
});
}
}));
}

void MainPage::Application_Resuming(Platform::Object^ sender, Platform::Object^ args)
{
// Handle global application events only if this page is active
if (Frame->CurrentSourcePageType.Name == Interop::TypeName(MainPage::typeid).Name)
_isSuspending = false;

Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([this]()
{
SetupUiAsync();
InitializeCameraAsync();
}
SetUpBasedOnStateAsync();
}));
}

void MainPage::Window_VisibilityChanged(Object^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ e)
{
SetUpBasedOnStateAsync();
}

void MainPage::DisplayInformation_OrientationChanged(DisplayInformation^ sender, Object^ args)
Expand Down Expand Up @@ -857,13 +883,26 @@ void MainPage::MediaCapture_Failed(Capture::MediaCapture ^currentCaptureObject,

void MainPage::OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e)
{
SetupUiAsync();
InitializeCameraAsync();

// Useful to know when to initialize/clean up the camera
_applicationSuspendingEventToken =
Application::Current->Suspending += ref new SuspendingEventHandler(this, &MainPage::Application_Suspending);
_applicationResumingEventToken =
Application::Current->Resuming += ref new EventHandler<Object^>(this, &MainPage::Application_Resuming);
_windowVisibilityChangedEventToken =
Window::Current->VisibilityChanged += ref new WindowVisibilityChangedEventHandler(this, &MainPage::Window_VisibilityChanged);

_isActivePage = true;
SetUpBasedOnStateAsync();
}

void MainPage::OnNavigatingFrom(Windows::UI::Xaml::Navigation::NavigatingCancelEventArgs^ e)
{
// Handling of this event is included for completeness, as it will only fire when navigating between pages and this sample only includes one page
CleanupCameraAsync();
CleanupUiAsync();
Application::Current->Suspending -= _applicationSuspendingEventToken;
Application::Current->Resuming -= _applicationResumingEventToken;
Window::Current->VisibilityChanged -= _windowVisibilityChangedEventToken;

_isActivePage = false;
SetUpBasedOnStateAsync();
}
10 changes: 9 additions & 1 deletion Samples/CameraStarterKit/cpp/MainPage.xaml.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ namespace CameraStarterKit
bool _isPreviewing;
bool _isRecording;

// UI state
bool _isSuspending = false;
bool _isActivePage = false;
bool _isUIActive = false;
concurrency::task<void> _setupTask = concurrency::task_from_result();

// Information about the camera device
bool _externalCamera;
bool _mirroringPreview;
Expand All @@ -55,6 +61,7 @@ namespace CameraStarterKit
// Event tokens
Windows::Foundation::EventRegistrationToken _applicationSuspendingEventToken;
Windows::Foundation::EventRegistrationToken _applicationResumingEventToken;
Windows::Foundation::EventRegistrationToken _windowVisibilityChangedEventToken;
Windows::Foundation::EventRegistrationToken _mediaControlPropChangedEventToken;
Windows::Foundation::EventRegistrationToken _displayInformationEventToken;
Windows::Foundation::EventRegistrationToken _recordLimitationExceededEventToken;
Expand All @@ -76,13 +83,13 @@ namespace CameraStarterKit
Concurrency::task<Windows::Devices::Enumeration::DeviceInformation^> FindCameraDeviceByPanelAsync(Windows::Devices::Enumeration::Panel panel);
Concurrency::task<void> ReencodeAndSavePhotoAsync(Windows::Storage::Streams::IRandomAccessStream^ stream, Windows::Storage::FileProperties::PhotoOrientation photoOrientation);
void UpdateCaptureControls();
Concurrency::task<void> SetUpBasedOnStateAsync();
Concurrency::task<void> SetupUiAsync();
Concurrency::task<void> CleanupUiAsync();
void RegisterEventHandlers();
void UnregisterEventHandlers();
void WriteLine(Platform::String^ str);
void WriteException(Platform::Exception^ ex);
Concurrency::task<void> EmptyTask();

// Rotation helpers
Windows::Devices::Sensors::SimpleOrientation GetCameraOrientation();
Expand All @@ -94,6 +101,7 @@ namespace CameraStarterKit
// UI event handlers
void Application_Suspending(Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
void Application_Resuming(Object^ sender, Object^ args);
void Window_VisibilityChanged(Object^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ e);
void DisplayInformation_OrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Object^ args);
void PhotoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void VideoButton_Tapped(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
Expand Down
Loading

0 comments on commit 4c824c9

Please sign in to comment.