Skip to content

Commit

Permalink
Android: Initiate image prefetching on ImageShadowNode layout (facebo…
Browse files Browse the repository at this point in the history
…ok#47932)

Summary:

This diff introduces a code path to trigger image prefetching from `ImageShadowNode::layout`.
Changelog: [Internal]

Reviewed By: javache

Differential Revision: D66454087
  • Loading branch information
dmytrorykun authored and facebook-github-bot committed Dec 3, 2024
1 parent 318db8e commit 7fb8128
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 12 deletions.
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

0 comments on commit 7fb8128

Please sign in to comment.