diff --git a/change/react-native-windows-5a821784-ada0-45ea-a602-196b255632ca.json b/change/react-native-windows-5a821784-ada0-45ea-a602-196b255632ca.json new file mode 100644 index 00000000000..0085fe54e01 --- /dev/null +++ b/change/react-native-windows-5a821784-ada0-45ea-a602-196b255632ca.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Move UriHandler registration to PackageProvider", + "packageName": "react-native-windows", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/playground/windows/playground-composition/Playground-Composition.cpp b/packages/playground/windows/playground-composition/Playground-Composition.cpp index 4830d69d2a1..a27422e4085 100644 --- a/packages/playground/windows/playground-composition/Playground-Composition.cpp +++ b/packages/playground/windows/playground-composition/Playground-Composition.cpp @@ -92,10 +92,15 @@ struct EllipseImageHandler : winrt::implements< } }; -void RegisterEllipseUriImageHandler(const winrt::Microsoft::ReactNative::ReactInstanceSettings &settings) noexcept { - winrt::Microsoft::ReactNative::Composition::UriImageManager::AddUriImageProvider( - settings.Properties(), winrt::make()); -} +struct EllipseReactPackageProvider + : winrt::implements { + public: // IReactPackageProvider + void CreatePackage(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept { + // Register ellipse: uri handler for images + packageBuilder.as().AddUriImageProvider( + winrt::make()); + } +}; // Have to use TurboModules to override built in modules.. so the standard attributed package provider doesn't work. struct CompReactPackageProvider @@ -238,7 +243,7 @@ struct WindowData { InstanceSettings(), g_liftedCompositor); // Register ellipse:// uri hander for images - RegisterEllipseUriImageHandler(host.InstanceSettings()); + host.PackageProviders().Append(winrt::make()); auto bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create( g_liftedCompositor, winrt::Microsoft::UI::GetWindowIdFromWindow(hwnd)); diff --git a/vnext/Desktop/ABI/TestController.cpp b/vnext/Desktop/ABI/TestController.cpp index aceb8095f73..63f8971de20 100644 --- a/vnext/Desktop/ABI/TestController.cpp +++ b/vnext/Desktop/ABI/TestController.cpp @@ -96,6 +96,7 @@ msrn::IReactPackageBuilder TestController::CreateReactPackageBuilder() { turboModulesProvider, #ifdef USE_FABRIC std::shared_ptr<::Microsoft::ReactNative::WindowsComponentDescriptorRegistry>{}, + std::shared_ptr{}, #endif true); } diff --git a/vnext/Microsoft.ReactNative.IntegrationTests/ExecuteJsiTests.cpp b/vnext/Microsoft.ReactNative.IntegrationTests/ExecuteJsiTests.cpp index 2b0f40a2f84..55388eef2f8 100644 --- a/vnext/Microsoft.ReactNative.IntegrationTests/ExecuteJsiTests.cpp +++ b/vnext/Microsoft.ReactNative.IntegrationTests/ExecuteJsiTests.cpp @@ -24,17 +24,6 @@ struct TestExecuteJsiModule { TestEventService::LogEvent("initialize", nullptr); } - REACT_METHOD(TestSimpleExecuteJsi, L"testSimpleExecuteJsi") - void TestSimpleExecuteJsi() noexcept { - TestEventService::LogEvent("testSimpleExecuteJsi started", nullptr); - ExecuteJsi(m_reactContext, [](Runtime &rt) { - auto eval = rt.global().getPropertyAsFunction(rt, "eval"); - auto addFunc = eval.call(rt, "(function(x, y) { return x + y; })").getObject(rt).getFunction(rt); - TestCheckEqual(7, addFunc.call(rt, 3, 4).getNumber()); - TestEventService::LogEvent("testSimpleExecuteJsi completed", nullptr); - }); - } - REACT_METHOD(TestHostFunction, L"testHostFunction") void TestHostFunction() noexcept { TestEventService::LogEvent("testHostFunction started", nullptr); @@ -143,8 +132,6 @@ TEST_CLASS (ExecuteJsiTests) { TestEventService::ObserveEvents({ TestEvent{"initialize", nullptr}, - TestEvent{"testSimpleExecuteJsi started", nullptr}, - TestEvent{"testSimpleExecuteJsi completed", nullptr}, TestEvent{"testHostFunction started", nullptr}, TestEvent{"testHostFunction completed", nullptr}, TestEvent{"testHostObject started", nullptr}, diff --git a/vnext/Microsoft.ReactNative.IntegrationTests/ExecuteJsiTests.js b/vnext/Microsoft.ReactNative.IntegrationTests/ExecuteJsiTests.js index 65111d4f7b7..da1486b72f9 100644 --- a/vnext/Microsoft.ReactNative.IntegrationTests/ExecuteJsiTests.js +++ b/vnext/Microsoft.ReactNative.IntegrationTests/ExecuteJsiTests.js @@ -1,8 +1,7 @@ import { TurboModuleRegistry } from 'react-native'; const testExecuteJsiModule = TurboModuleRegistry.getEnforcing('TestExecuteJsiModule'); -testExecuteJsiModule.testSimpleExecuteJsi(); testExecuteJsiModule.testHostFunction(); -testExecuteJsiModule.testHostObject(); +testExecuteJsiModule.testHostObject(); testExecuteJsiModule.testSameJsiRuntime(); testExecuteJsiModule.testExecuteJsiPromise(); diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp index f05da54cf4d..7e061674265 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp @@ -5,7 +5,6 @@ #include "UriImageManager.h" #include "Composition.ImageSource.g.h" -#include "Composition.UriImageManager.g.cpp" #include #include #include @@ -183,8 +182,8 @@ struct DataImageHandler : winrt::implements< } }; -static const ReactPropertyId>> &UriImageManagerPropertyId() noexcept { - static const ReactPropertyId>> prop{ +static const ReactPropertyId>> &UriImageManagerPropertyId() noexcept { + static const ReactPropertyId>> prop{ L"ReactNative", L"UriImageManager"}; return prop; } @@ -194,21 +193,21 @@ UriImageManager::UriImageManager() { m_providers.push_back(winrt::make()); } -winrt::com_ptr UriImageManager::GetOrCreate( +void UriImageManager::Install( + const winrt::Microsoft::ReactNative::ReactPropertyBag &properties, + const std::shared_ptr &manager) noexcept { + properties.Set(UriImageManagerPropertyId(), manager); +} + +std::shared_ptr UriImageManager::Get( const winrt::Microsoft::ReactNative::ReactPropertyBag &properties) noexcept { - auto uriImageManager = - winrt::Microsoft::ReactNative::ReactPropertyBag(properties).GetOrCreate(UriImageManagerPropertyId(), []() { - return winrt::make_self(); - }); - return uriImageManager.Value(); + return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(UriImageManagerPropertyId()).Value(); } -void UriImageManager::AddUriImageProvider( - const winrt::Microsoft::ReactNative::IReactPropertyBag &properties, - const IUriImageProvider &provider) { +void UriImageManager::AddUriImageProvider(const IUriImageProvider &provider) { if (!provider) winrt::throw_hresult(E_INVALIDARG); - GetOrCreate(winrt::Microsoft::ReactNative::ReactPropertyBag(properties))->m_providers.push_back(provider); + m_providers.push_back(provider); } IUriImageProvider UriImageManager::TryGetUriImageProvider( diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager.h b/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager.h index 014df054ae5..a9f49a72b4c 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager.h @@ -2,7 +2,6 @@ // Licensed under the MIT License. #pragma once -#include "Composition.UriImageManager.g.h" #include #include @@ -11,14 +10,16 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation { -struct UriImageManager : UriImageManagerT { +struct UriImageManager { UriImageManager(); - static void AddUriImageProvider( - const winrt::Microsoft::ReactNative::IReactPropertyBag &properties, - const IUriImageProvider &provider); + void AddUriImageProvider(const IUriImageProvider &provider); - static winrt::com_ptr GetOrCreate( + static void Install( + const winrt::Microsoft::ReactNative::ReactPropertyBag &properties, + const std::shared_ptr &manager) noexcept; + + static std::shared_ptr Get( const winrt::Microsoft::ReactNative::ReactPropertyBag &properties) noexcept; IUriImageProvider TryGetUriImageProvider( @@ -33,7 +34,3 @@ winrt::Microsoft::ReactNative::Composition::ImageSource MakeImageSource( const facebook::react::ImageSource &source) noexcept; } // namespace winrt::Microsoft::ReactNative::Composition::implementation - -namespace winrt::Microsoft::ReactNative::Composition::factory_implementation { -struct UriImageManager : UriImageManagerT {}; -} // namespace winrt::Microsoft::ReactNative::Composition::factory_implementation diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager_emptyimpl.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager_emptyimpl.cpp deleted file mode 100644 index 861dfbf9501..00000000000 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UriImageManager_emptyimpl.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#include "pch.h" - -#include "UriImageManager.h" - -#include "Composition.UriImageManager.g.cpp" - -namespace winrt::Microsoft::ReactNative::Composition::implementation { - -void UriImageManager::AddUriImageProvider( - const winrt::Microsoft::ReactNative::IReactPropertyBag &, - const IUriImageProvider &) {} - -} // namespace winrt::Microsoft::ReactNative::Composition::implementation diff --git a/vnext/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp b/vnext/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp index 04d54f287cb..9ec84edaa5d 100644 --- a/vnext/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp @@ -19,8 +19,8 @@ namespace Microsoft::ReactNative { WindowsImageManager::WindowsImageManager(winrt::Microsoft::ReactNative::ReactContext reactContext) : m_reactContext(reactContext) { - m_uriImageManager = winrt::Microsoft::ReactNative::Composition::implementation::UriImageManager::GetOrCreate( - reactContext.Properties()); + m_uriImageManager = + winrt::Microsoft::ReactNative::Composition::implementation::UriImageManager::Get(reactContext.Properties()); } winrt::com_ptr wicBitmapSourceFromStream( diff --git a/vnext/Microsoft.ReactNative/Fabric/WindowsImageManager.h b/vnext/Microsoft.ReactNative/Fabric/WindowsImageManager.h index 0a183084204..669c1a97ffa 100644 --- a/vnext/Microsoft.ReactNative/Fabric/WindowsImageManager.h +++ b/vnext/Microsoft.ReactNative/Fabric/WindowsImageManager.h @@ -19,7 +19,7 @@ struct WindowsImageManager { private: winrt::Microsoft::ReactNative::ReactContext m_reactContext; - winrt::com_ptr m_uriImageManager; + std::shared_ptr m_uriImageManager; }; } // namespace Microsoft::ReactNative diff --git a/vnext/Microsoft.ReactNative/IReactPackageBuilderFabric.idl b/vnext/Microsoft.ReactNative/IReactPackageBuilderFabric.idl index 90cf99572ae..30372775e96 100644 --- a/vnext/Microsoft.ReactNative/IReactPackageBuilderFabric.idl +++ b/vnext/Microsoft.ReactNative/IReactPackageBuilderFabric.idl @@ -2,6 +2,7 @@ // Licensed under the MIT License. import "IReactViewComponentBuilder.idl"; +import "UriImageManager.idl"; #include "DocString.h" @@ -18,6 +19,10 @@ namespace Microsoft.ReactNative { DOC_STRING("Registers a custom native view component.") void AddViewComponent(String componentName, ReactViewComponentProvider componentProvider); + + DOC_STRING( + "Ability to load images using custom Uri protocol handlers. The provider should implement @Composition.IUriImageStreamProvider or @Composition.Experimental.IUriBrushProvider.") + void AddUriImageProvider(Microsoft.ReactNative.Composition.IUriImageProvider provider); }; } // namespace Microsoft.ReactNative diff --git a/vnext/Microsoft.ReactNative/ReactHost/React.h b/vnext/Microsoft.ReactNative/ReactHost/React.h index 5a56fa70482..f909cf9dbcc 100644 --- a/vnext/Microsoft.ReactNative/ReactHost/React.h +++ b/vnext/Microsoft.ReactNative/ReactHost/React.h @@ -32,6 +32,10 @@ #include #include +#ifdef USE_FABRIC +#include +#endif + namespace Mso::React { // Forward declarations @@ -182,6 +186,9 @@ struct ReactOptions { std::shared_ptr ModuleProvider; std::shared_ptr ViewManagerProvider; std::shared_ptr TurboModuleProvider; +#ifdef USE_FABRIC + std::shared_ptr UriImageManager; +#endif //! Identity of the SDX. Must uniquely describe the SDX across the installed product. std::string Identity; diff --git a/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp b/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp index 379b1b2e2f1..c7ff1978f9f 100644 --- a/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +++ b/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp @@ -52,6 +52,7 @@ #include "Unicode.h" #ifdef USE_FABRIC +#include #include #include #include @@ -570,6 +571,8 @@ void ReactInstanceWin::InitializeBridgeless() noexcept { }); InitDevMenu(); + winrt::Microsoft::ReactNative::Composition::implementation::UriImageManager::Install( + ReactPropertyBag(m_reactContext->Properties()), m_options.UriImageManager); m_uiQueue->Post([this, weakThis = Mso::WeakPtr{this}]() noexcept { // Objects that must be created on the UI thread @@ -726,6 +729,10 @@ void ReactInstanceWin::InitializeWithBridge() noexcept { #endif InitDevMenu(); +#ifdef USE_FABRIC + winrt::Microsoft::ReactNative::Composition::implementation::UriImageManager::Install( + ReactPropertyBag(m_reactContext->Properties()), m_options.UriImageManager); +#endif m_uiQueue->Post([this, weakThis = Mso::WeakPtr{this}]() noexcept { // Objects that must be created on the UI thread diff --git a/vnext/Microsoft.ReactNative/ReactNativeHost.cpp b/vnext/Microsoft.ReactNative/ReactNativeHost.cpp index 8fc98d62cc7..781bbd9d657 100644 --- a/vnext/Microsoft.ReactNative/ReactNativeHost.cpp +++ b/vnext/Microsoft.ReactNative/ReactNativeHost.cpp @@ -16,6 +16,7 @@ #ifdef USE_FABRIC #include +#include #include #endif @@ -93,6 +94,8 @@ IAsyncAction ReactNativeHost::ReloadInstance() noexcept { auto turboModulesProvider = std::make_shared(); #ifdef USE_FABRIC + auto uriImageManager = + std::make_shared(); auto componentregistry = std::make_shared<::Microsoft::ReactNative::WindowsComponentDescriptorRegistry>(); auto componentDescriptorRegistry = std::make_shared(); @@ -108,6 +111,7 @@ IAsyncAction ReactNativeHost::ReloadInstance() noexcept { turboModulesProvider, #ifdef USE_FABRIC componentregistry, + uriImageManager, #endif m_instanceSettings.UseWebDebugger()); @@ -164,6 +168,10 @@ IAsyncAction ReactNativeHost::ReloadInstance() noexcept { #endif reactOptions.TurboModuleProvider = turboModulesProvider; +#ifdef USE_FABRIC + reactOptions.UriImageManager = uriImageManager; +#endif + reactOptions.OnInstanceCreated = [](Mso::CntPtr &&context) { auto notifications = context->Notifications(); ReactInstanceSettings::RaiseInstanceCreated( diff --git a/vnext/Microsoft.ReactNative/ReactPackageBuilder.cpp b/vnext/Microsoft.ReactNative/ReactPackageBuilder.cpp index f13dc4c5712..efe880e784f 100644 --- a/vnext/Microsoft.ReactNative/ReactPackageBuilder.cpp +++ b/vnext/Microsoft.ReactNative/ReactPackageBuilder.cpp @@ -22,6 +22,7 @@ ReactPackageBuilder::ReactPackageBuilder( std::shared_ptr const &turboModulesProvider, #ifdef USE_FABRIC std::shared_ptr<::Microsoft::ReactNative::WindowsComponentDescriptorRegistry> const &componentRegistry, + std::shared_ptr const &uriImageManager, #endif bool isWebDebugging) noexcept : m_modulesProvider{modulesProvider}, @@ -31,6 +32,7 @@ ReactPackageBuilder::ReactPackageBuilder( m_turboModulesProvider{turboModulesProvider}, #ifdef USE_FABRIC m_componentRegistry{componentRegistry}, + m_uriImageManager{uriImageManager}, #endif m_isWebDebugging{isWebDebugging} { @@ -63,5 +65,11 @@ void ReactPackageBuilder::AddViewComponent( ReactViewComponentProvider const &viewComponentProvider) noexcept { m_componentRegistry->Add(componentName, viewComponentProvider); } + +void ReactPackageBuilder::AddUriImageProvider( + const winrt::Microsoft::ReactNative::Composition::IUriImageProvider &provider) noexcept { + m_uriImageManager->AddUriImageProvider(provider); +} + #endif } // namespace winrt::Microsoft::ReactNative diff --git a/vnext/Microsoft.ReactNative/ReactPackageBuilder.h b/vnext/Microsoft.ReactNative/ReactPackageBuilder.h index 9790c19f3d6..73f0de1be5a 100644 --- a/vnext/Microsoft.ReactNative/ReactPackageBuilder.h +++ b/vnext/Microsoft.ReactNative/ReactPackageBuilder.h @@ -9,7 +9,9 @@ #endif #include "winrt/Microsoft.ReactNative.h" #ifdef USE_FABRIC +#include #include +#include "winrt/Microsoft.ReactNative.Composition.h" #endif namespace winrt::Microsoft::ReactNative { @@ -30,6 +32,8 @@ struct ReactPackageBuilder : winrt::implements< std::shared_ptr const &turboModulesProvider, #ifdef USE_FABRIC std::shared_ptr<::Microsoft::ReactNative::WindowsComponentDescriptorRegistry> const &componentRegistry, + std::shared_ptr const + &uriImageManager, #endif bool isWebDebugging) noexcept; @@ -43,6 +47,7 @@ struct ReactPackageBuilder : winrt::implements< #ifdef USE_FABRIC // IReactPackageBuilderFabric void AddViewComponent(winrt::hstring componentName, ReactViewComponentProvider const &viewComponentProvider) noexcept; + void AddUriImageProvider(const winrt::Microsoft::ReactNative::Composition::IUriImageProvider &provider) noexcept; #endif // USE_FABRIC private: @@ -54,6 +59,7 @@ struct ReactPackageBuilder : winrt::implements< #ifdef USE_FABRIC std::shared_ptr<::Microsoft::ReactNative::WindowsComponentDescriptorRegistry> m_componentRegistry; + std::shared_ptr m_uriImageManager; #endif const bool m_isWebDebugging; diff --git a/vnext/Microsoft.ReactNative/UriImageManager.idl b/vnext/Microsoft.ReactNative/UriImageManager.idl index 2b599922e91..92cc72e907f 100644 --- a/vnext/Microsoft.ReactNative/UriImageManager.idl +++ b/vnext/Microsoft.ReactNative/UriImageManager.idl @@ -72,14 +72,4 @@ namespace Microsoft.ReactNative.Composition Windows.Foundation.IAsyncOperation GetSourceAsync(Microsoft.ReactNative.IReactContext context, Microsoft.ReactNative.Composition.ImageSource imageSource); } } - - [default_interface] - [webhosthidden] - [experimental] - DOC_STRING( - "Ability to load images using custom Uri protocol handlers. The provider should implement @IUriImageStreamProvider or @Experimental.IUriBrushProvider") - runtimeclass UriImageManager - { - static void AddUriImageProvider(Microsoft.ReactNative.IReactPropertyBag properties, IUriImageProvider provider); - } } // namespace Microsoft.ReactNative.Composition diff --git a/vnext/Shared/Shared.vcxitems b/vnext/Shared/Shared.vcxitems index 510a5f392e4..7a8b26602ad 100644 --- a/vnext/Shared/Shared.vcxitems +++ b/vnext/Shared/Shared.vcxitems @@ -89,11 +89,6 @@ $(ReactNativeWindowsDir)Microsoft.ReactNative\UriImageManager.idl Code - - true - $(ReactNativeWindowsDir)Microsoft.ReactNative\UriImageManager.idl - Code - true