From fd8e26f1dfefe10332f6e87b4ca7744b857bb6d9 Mon Sep 17 00:00:00 2001 From: reunion-maestro-bot Date: Tue, 9 Jul 2024 19:32:34 +0000 Subject: [PATCH] Syncing content from committish f48678bcc836e2f37bf1d8fe6a9736d729750365 --- controls/dev/WebView2/WebView2.cpp | 129 ++++++++++++++---- controls/dev/WebView2/WebView2.h | 2 +- dxaml/xcp/components/imaging/ImageCache.cpp | 41 ++++-- .../xcp/components/imaging/ImageProvider.cpp | 14 +- .../imaging/SoftwareBitmapSource.cpp | 10 +- dxaml/xcp/core/core/elements/imagesource.cpp | 86 ++++++++---- .../imaging/ImagingProvider/ImageProvider.cpp | 16 ++- .../ImagingProvider/LoadedImageSurface.cpp | 18 ++- eng/Version.Details.xml | 8 +- 9 files changed, 240 insertions(+), 84 deletions(-) diff --git a/controls/dev/WebView2/WebView2.cpp b/controls/dev/WebView2/WebView2.cpp index 0a7f2213af..de20cd8fb0 100644 --- a/controls/dev/WebView2/WebView2.cpp +++ b/controls/dev/WebView2/WebView2.cpp @@ -19,6 +19,10 @@ #include "Windows.Globalization.h" #include #include "MuxcTraceLogging.h" +#include + +// Bug 51787766: [1.5 Servicing] [GitHub #2330][Acc][PowerBI][UWP MSAA][Amazon Prime] Initial focus not set to WebView2 when WV2 is the only control +#define WINAPPSDK_CHANGEID_51787766 51787766 using namespace Microsoft::WRL; @@ -563,44 +567,91 @@ void WebView2::RegisterCoreEventHandlers() if (moveFocusRequestedReason == winrt::CoreWebView2MoveFocusReason::Next || moveFocusRequestedReason == winrt::CoreWebView2MoveFocusReason::Previous) { - winrt::FocusNavigationDirection xamlDirection{ moveFocusRequestedReason == winrt::CoreWebView2MoveFocusReason::Next ? - winrt::FocusNavigationDirection::Next : winrt::FocusNavigationDirection::Previous }; - winrt::FindNextElementOptions findNextElementOptions; winrt::XamlRoot xamlRoot = strongThis->XamlRoot(); if (xamlRoot) { + winrt::FocusNavigationDirection xamlDirection = moveFocusRequestedReason == winrt::CoreWebView2MoveFocusReason::Next + ? winrt::FocusNavigationDirection::Next + : winrt::FocusNavigationDirection::Previous; + + winrt::FindNextElementOptions findNextElementOptions; findNextElementOptions.SearchRoot(xamlRoot.Content()); + winrt::DependencyObject nextElement = winrt::FocusManager::FindNextElement(xamlDirection, findNextElementOptions); - if (nextElement) + + if (WinAppSdk::Containment::IsChangeEnabled()) { - // TODO_WebView2: We should check TryMoveFocusAsync() result before returning since FindNextElement() - // only finds the next focusable element, but does not guarantee that we can - // actually focus on it (eg it could be empty/in the process of loading). - // Waiting on this result via winrt/cpp coroutine results in the WINRT_ASSERT - // warning about a blocking wait on UI Thread. - // - // We will address this scenario properly as part of: - // Task 23157748: WebView2 should implement IInternalCoreWindowFocus (use Xaml's unified focus model) - // - // For now, we'll assign the return value of TryMoveFocusAsync() to a dummy variable - // in order to avoid the code analysis error C26444: - // - // https://docs.microsoft.com/en-us/cpp/code-quality/c26444?view=vs-2019 - - // If core webview is also losing focus via something other than TAB (web LostFocus event fired) - // and the TAB handling is arriving later (eg due to longer MOJO delay), skip manually moving Xaml Focus to next element. - auto focusedElement = winrt::FocusManager::GetFocusedElement(xamlRoot).try_as(); - auto thisElement = strongThis->try_as(); - if (thisElement == focusedElement) + winrt::DependencyObject focusedElement = winrt::FocusManager::GetFocusedElement(xamlRoot).try_as(); + if (nextElement && nextElement != focusedElement) + { + // TODO_WebView2: We should check TryMoveFocusAsync() result before returning since FindNextElement() + // only finds the next focusable element, but does not guarantee that we can + // actually focus on it (eg it could be empty/in the process of loading). + // Waiting on this result via winrt/cpp coroutine results in the WINRT_ASSERT + // warning about a blocking wait on UI Thread. + // + // We will address this scenario properly as part of: + // Task 23157748: WebView2 should implement IInternalCoreWindowFocus (use Xaml's unified focus model) + // + // For now, we'll assign the return value of TryMoveFocusAsync() to a dummy variable + // in order to avoid the code analysis error C26444: + // + // https://docs.microsoft.com/en-us/cpp/code-quality/c26444?view=vs-2019 + + // If core webview is also losing focus via something other than TAB (web LostFocus event fired) + // and the TAB handling is arriving later (eg due to longer MOJO delay), skip manually moving Xaml Focus to next element. + winrt::DependencyObject thisElement = strongThis->try_as(); + if (thisElement == focusedElement) + { + // Move focus to the next XAML element + const auto _ = winrt::FocusManager::TryMoveFocusAsync(xamlDirection, findNextElementOptions); + } + } + else { - const auto _ = winrt::FocusManager::TryMoveFocusAsync(xamlDirection, findNextElementOptions); + // Handle the case where there is no "next" focusable XAML element (WebView2 is first/last/only element), + // which we are in if FindNextElement() returns either null or the (already focused) WebView2. The appropriate + // behavior here is to cycle focus inside the webview, "wrapping around" to the other end (regardless of + // WebView2.KeyboardNavigationMode).To achieve this, manually Call MoveFocus() in the specified direction. + strongThis->MoveFocusIntoCoreWebView2(moveFocusRequestedReason); } + // Always mark the args handled to prevent CoreWebView2Controller's "default behavior" which breaks XAML focus expectations (by explicitly changing HWND focus) + // More info: https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2movefocusrequestedeventargs?view=webview2-winrt-1.0.2535.41#handled args.Handled(TRUE); } + else + { + if (nextElement) + { + // TODO_WebView2: We should check TryMoveFocusAsync() result before returning since FindNextElement() + // only finds the next focusable element, but does not guarantee that we can + // actually focus on it (eg it could be empty/in the process of loading). + // Waiting on this result via winrt/cpp coroutine results in the WINRT_ASSERT + // warning about a blocking wait on UI Thread. + // + // We will address this scenario properly as part of: + // Task 23157748: WebView2 should implement IInternalCoreWindowFocus (use Xaml's unified focus model) + // + // For now, we'll assign the return value of TryMoveFocusAsync() to a dummy variable + // in order to avoid the code analysis error C26444: + // + // https://docs.microsoft.com/en-us/cpp/code-quality/c26444?view=vs-2019 + + // If core webview is also losing focus via something other than TAB (web LostFocus event fired) + // and the TAB handling is arriving later (eg due to longer MOJO delay), skip manually moving Xaml Focus to next element. + auto focusedElement = winrt::FocusManager::GetFocusedElement(xamlRoot).try_as(); + auto thisElement = strongThis->try_as(); + if (thisElement == focusedElement) + { + const auto _ = winrt::FocusManager::TryMoveFocusAsync(xamlDirection, findNextElementOptions); + } + + args.Handled(TRUE); + } + // If nextElement is null, focus is maintained in Anaheim by not marking Handled. + } } - - // If nextElement is null, focus is maintained in Anaheim by not marking Handled. } } } }); @@ -1246,15 +1297,35 @@ void WebView2::FireCoreWebView2Initialized(winrt::hresult exception) m_coreWebView2InitializedEventSource(*this, *eventArgs); } -void WebView2::HandleGotFocus(const winrt::Windows::Foundation::IInspectable&, const winrt::RoutedEventArgs&) noexcept +void WebView2::MoveFocusIntoCoreWebView2(winrt::CoreWebView2MoveFocusReason reason) { - if (m_coreWebView && m_xamlFocusChangeInfo.m_isPending) + if (m_coreWebView && m_coreWebViewController) { CoreWebView2RunIgnoreInvalidStateSync( [&]() { - m_coreWebViewController.MoveFocus(m_xamlFocusChangeInfo.m_storedMoveFocusReason); + m_coreWebViewController.MoveFocus(reason); }); + } +} + +void WebView2::HandleGotFocus(const winrt::Windows::Foundation::IInspectable&, const winrt::RoutedEventArgs&) noexcept +{ + if (m_coreWebView && m_xamlFocusChangeInfo.m_isPending) + { + if (WinAppSdk::Containment::IsChangeEnabled()) + { + MoveFocusIntoCoreWebView2(m_xamlFocusChangeInfo.m_storedMoveFocusReason); + } + else + { + CoreWebView2RunIgnoreInvalidStateSync( + [&]() + { + m_coreWebViewController.MoveFocus(m_xamlFocusChangeInfo.m_storedMoveFocusReason); + }); + } + m_xamlFocusChangeInfo.m_isPending = false; } } diff --git a/controls/dev/WebView2/WebView2.h b/controls/dev/WebView2/WebView2.h index 5faaf0311a..c03950cbc7 100644 --- a/controls/dev/WebView2/WebView2.h +++ b/controls/dev/WebView2/WebView2.h @@ -115,7 +115,7 @@ class WebView2 : void UpdateSourceInternal(); void FireCoreProcessFailedEvent(const winrt::CoreWebView2ProcessFailedEventArgs& args); void FireCoreWebView2Initialized(winrt::hresult exception); - + void MoveFocusIntoCoreWebView2(winrt::CoreWebView2MoveFocusReason reason); void UpdateDefaultVisualBackgroundColor(); HWND GetHostHwnd() noexcept; diff --git a/dxaml/xcp/components/imaging/ImageCache.cpp b/dxaml/xcp/components/imaging/ImageCache.cpp index 7f38afdca6..aaa457bc79 100644 --- a/dxaml/xcp/components/imaging/ImageCache.cpp +++ b/dxaml/xcp/components/imaging/ImageCache.cpp @@ -26,6 +26,11 @@ #include #include #include +#include + +// Telemetry: Image Decoding Activity is skipped in WinAppSDK 1.5.5+ Servicing releases to avoid crashing +// Bug 44612834: [1.5 servicing] [Watson Failure] caused by FAIL_FAST_FATAL_APP_EXIT_c0000409_Microsoft.UI.Xaml.dll!ImagingTelemetry::ImageDecodeActivity::Split +#define WINAPPSDK_CHANGEID_44612834 44612834 typedef ImageAsyncCallback ImageCacheAsyncTask; @@ -341,17 +346,20 @@ _Check_return_ HRESULT ImageCache::TriggerProcessDecodeRequests() { if (!m_hasProcessDecodeRequestsTask) { - // This ImageCache may be associated with multiple ImageSources (i.e. the same image decoding to multiple - // different sizes). Telemetry is associated with the decoded image, so report telemetry for all the - // decodes that will be triggered by this ImageCache. - for (ImageDecodeRequest* decodeRequest : m_decodeRequests) + if (!WinAppSdk::Containment::IsChangeEnabled()) { - const auto& decodeParams = decodeRequest->GetDecodeParams(); + // This ImageCache may be associated with multiple ImageSources (i.e. the same image decoding to multiple + // different sizes). Telemetry is associated with the decoded image, so report telemetry for all the + // decodes that will be triggered by this ImageCache. + for (ImageDecodeRequest* decodeRequest : m_decodeRequests) + { + const auto& decodeParams = decodeRequest->GetDecodeParams(); - // The call below won't actually AV if there's nothing logging an ETW trace. Assert it explicitly so we - // crash consistently if it's null. - ASSERT(decodeParams->GetDecodeActivity()); - decodeParams->GetDecodeActivity()->QueueProcessDecodeRequests(decodeParams->GetImageId(), decodeParams->GetStrSource().GetBuffer()); + // The call below won't actually AV if there's nothing logging an ETW trace. Assert it explicitly so we + // crash consistently if it's null. + ASSERT(decodeParams->GetDecodeActivity()); + decodeParams->GetDecodeActivity()->QueueProcessDecodeRequests(decodeParams->GetImageId(), decodeParams->GetStrSource().GetBuffer()); + } } auto task = make_xref(this, &ImageCache::ProcessDecodeRequests); @@ -372,10 +380,13 @@ _Check_return_ HRESULT ImageCache::ProcessDecodeRequests() { m_hasProcessDecodeRequestsTask = FALSE; - for (ImageDecodeRequest* decodeRequest : m_decodeRequests) + if (!WinAppSdk::Containment::IsChangeEnabled()) { - const auto& decodeParams = decodeRequest->GetDecodeParams(); - decodeParams->GetDecodeActivity()->ProcessDecodeRequests(decodeParams->GetImageId(), decodeParams->GetStrSource().GetBuffer(), m_State); + for (ImageDecodeRequest* decodeRequest : m_decodeRequests) + { + const auto& decodeParams = decodeRequest->GetDecodeParams(); + decodeParams->GetDecodeActivity()->ProcessDecodeRequests(decodeParams->GetImageId(), decodeParams->GetStrSource().GetBuffer(), m_State); + } } // @@ -487,7 +498,11 @@ _Check_return_ HRESULT ImageCache::BeginDecode( const auto& decodeParams = decodeRequest->GetDecodeParams(); const std::shared_ptr& decodeActivity = decodeParams->GetDecodeActivity(); - decodeActivity->QueueDecodeFromImageCache(decodeParams->GetImageId(), decodeParams->GetStrSource().GetBuffer()); + if (decodeActivity) + { + decodeActivity->QueueDecodeFromImageCache(decodeParams->GetImageId(), decodeParams->GetStrSource().GetBuffer()); + } + auto parseHR = m_encodedImageData->Parse(m_core->GetGraphicsDevice(), m_core->GetContentRootMaxSize()); if (FAILED(parseHR)) diff --git a/dxaml/xcp/components/imaging/ImageProvider.cpp b/dxaml/xcp/components/imaging/ImageProvider.cpp index faae3c7887..dec2498297 100644 --- a/dxaml/xcp/components/imaging/ImageProvider.cpp +++ b/dxaml/xcp/components/imaging/ImageProvider.cpp @@ -14,6 +14,11 @@ #include "ImageProvider.h" #include "ImageDecodeRequest.h" #include "ImageDecodeParams.h" +#include + +// Telemetry: Image Decoding Activity is skipped in WinAppSDK 1.5.5+ Servicing releases to avoid crashing +// Bug 44612834: [1.5 servicing] [Watson Failure] caused by FAIL_FAST_FATAL_APP_EXIT_c0000409_Microsoft.UI.Xaml.dll!ImagingTelemetry::ImageDecodeActivity::Split +#define WINAPPSDK_CHANGEID_44612834 44612834 _Check_return_ HRESULT ImageProvider::CopyImage( @@ -37,12 +42,19 @@ ImageProvider::CopyImage( std::shared_ptr& ImageProvider::GetDecodeActivity() { - EnsureDecodeActivity(); + if (!WinAppSdk::Containment::IsChangeEnabled()) + { + EnsureDecodeActivity(); + } + return m_decodeActivity; } void ImageProvider::EnsureDecodeActivity() { + // Telemetry: Image Decoding Activity is skipped in WinAppSDK 1.5.5+ Servicing releases to avoid crashing bug 44612834. + ASSERT(!WinAppSdk::Containment::IsChangeEnabled()); + if (!m_decodeActivity) { m_decodeActivity = std::make_shared(ImagingTelemetry::ImageDecodeActivity::Start()); diff --git a/dxaml/xcp/components/imaging/SoftwareBitmapSource.cpp b/dxaml/xcp/components/imaging/SoftwareBitmapSource.cpp index 7588b24540..0e94967cd7 100644 --- a/dxaml/xcp/components/imaging/SoftwareBitmapSource.cpp +++ b/dxaml/xcp/components/imaging/SoftwareBitmapSource.cpp @@ -128,7 +128,10 @@ CSoftwareBitmapSource::SetBitmap( { ASSERT(m_spAbortableImageOperation == nullptr); - GetContext()->GetImageProvider()->GetDecodeActivity()->SetSoftwareBitmap(reinterpret_cast(this)); + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->SetSoftwareBitmap(reinterpret_cast(this)); + } IFC_RETURN(ReloadSource(false /* forceCopyToSoftwareSurface */)); } @@ -178,7 +181,10 @@ _Check_return_ HRESULT CSoftwareBitmapSource::OnSoftwareBitmapImageAvailable(_In attemptCopyToSoftwareSurfaceInstead = true; - GetContext()->GetImageProvider()->GetDecodeActivity()->SoftwareBitmapFallbackAfterUploadError(reinterpret_cast(this), uploadHResult); + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->SoftwareBitmapFallbackAfterUploadError(reinterpret_cast(this), uploadHResult); + } // Force a copy into a software surface, which will never hit a device lost error. We'll upload this into a // hardware surface later on a UI thread frame. diff --git a/dxaml/xcp/core/core/elements/imagesource.cpp b/dxaml/xcp/core/core/elements/imagesource.cpp index 3f3a368939..2644397c1c 100644 --- a/dxaml/xcp/core/core/elements/imagesource.cpp +++ b/dxaml/xcp/core/core/elements/imagesource.cpp @@ -219,7 +219,10 @@ HRESULT CImageSource::SetupImageSource( } } - GetContext()->GetImageProvider()->GetDecodeActivity()->SetUriSource(reinterpret_cast(this), m_strSource.GetBuffer()); + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->SetUriSource(reinterpret_cast(this), m_strSource.GetBuffer()); + } } } @@ -304,8 +307,11 @@ CImageSource::OnImageAvailableCommon( HRESULT hrImageResult = pResponse->GetDecodingResult(); - GetContext()->GetImageProvider()->GetDecodeActivity()->DecodeResultAvailable(reinterpret_cast(this), hrImageResult); - // TODO: Trace the surface upload as well. + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->DecodeResultAvailable(reinterpret_cast(this), hrImageResult); + // TODO: Trace the surface upload as well. + } if (SUCCEEDED(hrImageResult)) { @@ -652,23 +658,28 @@ _Check_return_ HRESULT CImageSource::SetImageCache(xref_ptr imageCac SetBitmapState(BitmapImageState::Downloading); - m_imageMetadataView = m_imageCache->GetMetadataView(GetContext()->GetImageProvider()->GetDecodeActivity(), reinterpret_cast(this)); + const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity(); + + m_imageMetadataView = m_imageCache->GetMetadataView(decodeActivity, reinterpret_cast(this)); m_imageMetadataView->SetGraphicsDevice(GetContext()->GetGraphicsDevice()); m_imageMetadataView->SetMaxRootSize(GetContext()->GetContentRootMaxSize()); m_imageMetadataView->AddImageViewListener(*this); - if (m_imageMetadataView->GetImageMetadata() || FAILED(m_imageMetadataView->GetHR(GetContext()->GetImageProvider()->GetDecodeActivity(), reinterpret_cast(this)))) + if (m_imageMetadataView->GetImageMetadata() || FAILED(m_imageMetadataView->GetHR(decodeActivity, reinterpret_cast(this)))) { // We already have metadata available, so this doesn't need to be downloaded. Go straight to // OnImageViewUpdated (which gets called when the download completes). - GetContext()->GetImageProvider()->GetDecodeActivity()->FoundCompletedDownload(reinterpret_cast(this)); + if (decodeActivity) + { + decodeActivity->FoundCompletedDownload(reinterpret_cast(this)); + } IFC_RETURN(OnImageViewUpdated(*m_imageMetadataView)); } - else + else if (decodeActivity) { // The ImageCache doesn't have metadata yet, so the download is still in progress. We'll wait for the // existing download to complete and be notified via OnImageViewUpdated afterwards (the // AddImageViewListener call above puts us in the list of things to notify once download completes). - GetContext()->GetImageProvider()->GetDecodeActivity()->WaitForDownloadInProgress(reinterpret_cast(this)); + decodeActivity->WaitForDownloadInProgress(reinterpret_cast(this)); } } else @@ -708,7 +719,10 @@ CImageSource::SetSource( // Clear the existing URI source. m_strSource.Reset(); - GetContext()->GetImageProvider()->GetDecodeActivity()->SetStreamSource(reinterpret_cast(this)); + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->SetStreamSource(reinterpret_cast(this)); + } // OnSourceSet() is called when we have a stream source. We don't do any automatic // reloading for a stream source, so unregister from the reload manager. @@ -1266,7 +1280,10 @@ CImageSource::SetValue(_In_ const SetValueParams& args) //------------------------------------------------------------------------ _Check_return_ HRESULT CImageSource::OnUriSourceChanged(bool retainPlaybackState) { - GetContext()->GetImageProvider()->GetDecodeActivity()->SetUriSource(reinterpret_cast(this), m_strSource.GetBuffer()); + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->SetUriSource(reinterpret_cast(this), m_strSource.GetBuffer()); + } // We may keep the HW surface to avoid flickering when switching URIs. IFC_RETURN(ResetForSourceChange( @@ -2531,12 +2548,15 @@ CImageSource::RequestDecode( ASSERT(false); } - GetContext()->GetImageProvider()->GetDecodeActivity()->RequestDecodeToRenderSize( - reinterpret_cast(this), - imageState, - requestWidth, - requestHeight, - m_fDecodeToRenderSize); + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->RequestDecodeToRenderSize( + reinterpret_cast(this), + imageState, + requestWidth, + requestHeight, + m_fDecodeToRenderSize); + } IFC_RETURN(DecodeToRenderSize(requestWidth, requestHeight, retainPlaybackState)); } @@ -2548,7 +2568,10 @@ _Check_return_ HRESULT CImageSource::OnImageViewUpdated(ImageViewBase& sender) { ASSERT(m_imageMetadataView.get() == &sender); - GetContext()->GetImageProvider()->GetDecodeActivity()->ImageDownloadCompleteNotification(reinterpret_cast(this), m_strSource.GetBuffer(), m_fDecodeToRenderSize); + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->ImageDownloadCompleteNotification(reinterpret_cast(this), m_strSource.GetBuffer(), m_fDecodeToRenderSize); + } if (ShouldContinueAsyncAction()) { @@ -2709,14 +2732,17 @@ CImageSource::DecodeToRenderSize( m_pendingDecodeForLostSoftwareSurface = FALSE; - GetContext()->GetImageProvider()->GetDecodeActivity()->DecodeToRenderSizeStart( - reinterpret_cast(this), - imageSourceWidth, - imageSourceHeight, - newWidth, - newHeight, - imageMetadata->width, - imageMetadata->height); + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->DecodeToRenderSizeStart( + reinterpret_cast(this), + imageSourceWidth, + imageSourceHeight, + newWidth, + newHeight, + imageMetadata->width, + imageMetadata->height); + } // Keep this old event for now. There are tests listening for it. TraceDecodeToRenderSizeBegin1( @@ -2763,7 +2789,10 @@ CImageSource::DecodeToRenderSize( TraceDecodeToRenderSizeEnd(reinterpret_cast(this), m_strSource.GetBuffer()); - GetContext()->GetImageProvider()->GetDecodeActivity()->DecodeToRenderSizeStop(reinterpret_cast(this)); + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->DecodeToRenderSizeStop(reinterpret_cast(this)); + } } return S_OK; @@ -3955,5 +3984,8 @@ void CImageSource::TraceDecodeToRenderSizeDisqualified(ImageDecodeBoundsFinder:: break; } - GetContext()->GetImageProvider()->GetDecodeActivity()->DecodeToRenderSizeDisqualified(reinterpret_cast(this), description); + if (const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity()) + { + decodeActivity->DecodeToRenderSizeDisqualified(reinterpret_cast(this), description); + } } diff --git a/dxaml/xcp/core/imaging/ImagingProvider/ImageProvider.cpp b/dxaml/xcp/core/imaging/ImagingProvider/ImageProvider.cpp index f073ef3313..114958c3c8 100644 --- a/dxaml/xcp/core/imaging/ImagingProvider/ImageProvider.cpp +++ b/dxaml/xcp/core/imaging/ImagingProvider/ImageProvider.cpp @@ -199,7 +199,10 @@ ImageProvider::GetImage( imageCache->SetEncodedImageData(spEncodedImageData); - decodeActivity->CreateImageCacheFromExistingEncodedData(spDecodeParams->GetImageId(), spDecodeParams->GetStrSource().GetBuffer()); + if (decodeActivity) + { + decodeActivity->CreateImageCacheFromExistingEncodedData(spDecodeParams->GetImageId(), spDecodeParams->GetStrSource().GetBuffer()); + } IFC_RETURN(imageCache->GetImage(spDecodeParams, spImageAvailableCallback, spAbortableImageOperation)); } @@ -442,7 +445,10 @@ ImageProvider::EnsureCacheEntry( if (imageCache == nullptr) { - decodeActivity->CreateImageCache(imageId, strUri.GetBuffer()); + if (decodeActivity) + { + decodeActivity->CreateImageCache(imageId, strUri.GetBuffer()); + } imageCache = make_xref( strCacheKey, @@ -463,7 +469,11 @@ ImageProvider::EnsureCacheEntry( } else { - decodeActivity->FoundImageCache(imageId, strUri.GetBuffer()); + if (decodeActivity) + { + decodeActivity->FoundImageCache(imageId, strUri.GetBuffer()); + } + *pCacheHit = true; } diff --git a/dxaml/xcp/core/imaging/ImagingProvider/LoadedImageSurface.cpp b/dxaml/xcp/core/imaging/ImagingProvider/LoadedImageSurface.cpp index 6819fe602e..ff515e3aff 100644 --- a/dxaml/xcp/core/imaging/ImagingProvider/LoadedImageSurface.cpp +++ b/dxaml/xcp/core/imaging/ImagingProvider/LoadedImageSurface.cpp @@ -221,10 +221,15 @@ _Check_return_ HRESULT CLoadedImageSurface::InitFromUri(xstring_ptr uri) { IFCEXPECTRC_RETURN(!m_closed, RO_E_CLOSED); - GetContext()->GetImageProvider()->GetDecodeActivity()->SetLoadedImageSurfaceUri(reinterpret_cast(this), uri.GetBuffer()); + const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity(); + + if (decodeActivity) + { + decodeActivity->SetLoadedImageSurfaceUri(reinterpret_cast(this), uri.GetBuffer()); + } auto core = GetContext(); - IFC_RETURN(GetImageCache(*core, uri, GetContext()->GetImageProvider()->GetDecodeActivity(), reinterpret_cast(this), m_imageCache.ReleaseAndGetAddressOf())); + IFC_RETURN(GetImageCache(*core, uri, decodeActivity, reinterpret_cast(this), m_imageCache.ReleaseAndGetAddressOf())); // Start asynchronous download/decode operation IFC_RETURN(GetImageDescription(*m_imageCache)); @@ -245,10 +250,15 @@ _Check_return_ HRESULT CLoadedImageSurface::InitFromMemory(_In_ wistd::unique_pt { IFCEXPECTRC_RETURN(!m_closed, RO_E_CLOSED); - GetContext()->GetImageProvider()->GetDecodeActivity()->SetLoadedImageSurfaceMemory(reinterpret_cast(this)); + const auto& decodeActivity = GetContext()->GetImageProvider()->GetDecodeActivity(); + + if (decodeActivity) + { + decodeActivity->SetLoadedImageSurfaceMemory(reinterpret_cast(this)); + } auto core = GetContext(); - IFC_RETURN(GetImageCache(*core, xstring_ptr::NullString() /* uri */, GetContext()->GetImageProvider()->GetDecodeActivity(), reinterpret_cast(this), m_imageCache.ReleaseAndGetAddressOf())); + IFC_RETURN(GetImageCache(*core, xstring_ptr::NullString() /* uri */, decodeActivity, reinterpret_cast(this), m_imageCache.ReleaseAndGetAddressOf())); // Set encoded data to skip async downloading m_imageCache->SetEncodedImageData(std::make_shared(std::move(rawData))); diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9e1039d0e9..c1335168bf 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -2,15 +2,15 @@ - + https://dev.azure.com/microsoft/ProjectReunion/_git/WindowsAppSDK - f2f6538eacbbe1632040c207cde16b5413fb07bf + ad621f84e7cc1b2c4e2409f82582cda4570f22d9 - + https://dev.azure.com/microsoft/LiftedIXP/_git/DCPP 8ae48bdfe2603ad520a56f5bcd40e136c2026c0e - + https://dev.azure.com/microsoft/LiftedIXP/_git/DCPP 8ae48bdfe2603ad520a56f5bcd40e136c2026c0e