Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android: Initiate image prefetching on ImageShadowNode layout #47932

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -2612,6 +2612,7 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid
public fun dispatchCommand (IILcom/facebook/react/bridge/ReadableArray;)V
public fun dispatchCommand (IILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
public fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
public fun experimental_prefetchResource (Ljava/lang/String;IILcom/facebook/react/common/mapbuffer/ReadableMapBuffer;)V
public fun getColor (I[Ljava/lang/String;)I
public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher;
public fun getInspectorDataForInstance (ILandroid/view/View;)Lcom/facebook/react/bridge/ReadableMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,16 @@ public void runGuarded() {
}
}

/**
* This method initiates preloading of an image specified by ImageSource. It can later be consumed
* by an ImageView.
*/
public void experimental_prefetchResource(
String componentName, int surfaceId, int reactTag, ReadableMapBuffer params) {
mMountingManager.experimental_prefetchResource(
mReactApplicationContext, componentName, surfaceId, reactTag, params);
}

public void setBinding(FabricUIManagerBinding binding) {
mBinding = binding;
}
Expand Down Expand Up @@ -960,7 +970,6 @@ public void receiveEvent(
* @param reactTag
* @param eventName
* @param canCoalesceEvent
* @param customCoalesceKey
* @param params
* @param eventCategory
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ target_include_directories(react_render_imagemanager

target_link_libraries(react_render_imagemanager
folly_runtime
mapbufferjni
react_debug
react_render_core
react_render_debug
react_render_graphics
react_render_mounting
reactnativejni
yoga)
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include "ImageFetcher.h"
#include <react/renderer/imagemanager/conversions.h>

namespace facebook::react {

ImageRequest ImageFetcher::requestImage(
const ImageSource& imageSource,
const ImageRequestParams& imageRequestParams,
SurfaceId surfaceId,
Tag tag) const {
auto fabricUIManager_ =
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
static auto requestImage =
fabricUIManager_->getClass()
->getMethod<void(
std::string, SurfaceId, Tag, JReadableMapBuffer::javaobject)>(
"experimental_prefetchResource");

auto serializedImageRequest =
serializeImageRequest(imageSource, imageRequestParams);

auto readableMapBuffer =
JReadableMapBuffer::createWithContents(std::move(serializedImageRequest));

requestImage(
fabricUIManager_,
"RCTImageView",
surfaceId,
tag,
readableMapBuffer.get());

auto telemetry = std::make_shared<ImageTelemetry>(surfaceId);

return {imageSource, telemetry};
}
} // namespace facebook::react
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <fbjni/fbjni.h>

#include <react/common/mapbuffer/JReadableMapBuffer.h>
#include <react/jni/ReadableNativeMap.h>
#include <react/renderer/imagemanager/ImageRequest.h>
#include <react/renderer/imagemanager/ImageRequestParams.h>
#include <react/utils/ContextContainer.h>

#include <utility>

namespace facebook::react {

class ImageFetcher {
public:
ImageFetcher(ContextContainer::Shared contextContainer)
: contextContainer_(std::move(contextContainer)) {}

ImageRequest requestImage(
const ImageSource& imageSource,
const ImageRequestParams& imageRequestParams,
SurfaceId surfaceId,
Tag tag) const;

private:
ContextContainer::Shared contextContainer_;
};
} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@

#include "ImageManager.h"

#include <react/featureflags/ReactNativeFeatureFlags.h>
#include "ImageFetcher.h"

namespace facebook::react {

ImageManager::ImageManager(
const ContextContainer::Shared& /*contextContainer*/) {
// Silence unused-private-field warning.
(void)self_;
// Not implemented.
}
ImageManager::ImageManager(const ContextContainer::Shared& contextContainer)
: self_(new ImageFetcher(contextContainer)) {}

ImageManager::~ImageManager() = default;
ImageManager::~ImageManager() {
// @lint-ignore CLANGTIDY cppcoreguidelines-no-malloc
free(self_);
}

ImageRequest ImageManager::requestImage(
const ImageSource& imageSource,
Expand All @@ -26,10 +28,16 @@ ImageRequest ImageManager::requestImage(

ImageRequest ImageManager::requestImage(
const ImageSource& imageSource,
SurfaceId /*surfaceId*/,
const ImageRequestParams& /*imageRequestParams*/,
Tag /* tag */) const {
return {imageSource, nullptr, {}};
SurfaceId surfaceId,
const ImageRequestParams& imageRequestParams,
Tag tag) const {
if (ReactNativeFeatureFlags::enableImagePrefetchingAndroid()) {
// @lint-ignore CLANGTIDY cppcoreguidelines-pro-type-cstyle-cast
return ((ImageFetcher*)self_)
->requestImage(imageSource, imageRequestParams, surfaceId, tag);
} else {
return {imageSource, nullptr, {}};
}
}

} // namespace facebook::react
Loading