Skip to content

Commit fef2fb9

Browse files
dmytrorykunfacebook-github-bot
authored andcommitted
Android: Initiate image prefetching on ImageShadowNode layout
Summary: This diff introduces a code path to trigger image prefetching from `ImageShadowNode::layout`. Changelog: [Internal] Differential Revision: D66454087
1 parent d7d66e7 commit fef2fb9

File tree

5 files changed

+110
-12
lines changed

5 files changed

+110
-12
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

+1
Original file line numberDiff line numberDiff line change
@@ -2638,6 +2638,7 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid
26382638
public fun receiveEvent (IILjava/lang/String;ZLcom/facebook/react/bridge/WritableMap;IZ)V
26392639
public fun receiveEvent (ILjava/lang/String;Lcom/facebook/react/bridge/WritableMap;)V
26402640
public fun removeUIManagerEventListener (Lcom/facebook/react/bridge/UIManagerListener;)V
2641+
public fun requestImage (IILcom/facebook/react/common/mapbuffer/ReadableMapBuffer;)V
26412642
public fun resolveCustomDirectEventName (Ljava/lang/String;)Ljava/lang/String;
26422643
public fun resolveView (I)Landroid/view/View;
26432644
public fun sendAccessibilityEvent (II)V

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
import com.facebook.react.uimanager.events.FabricEventDispatcher;
8484
import com.facebook.react.uimanager.events.RCTEventEmitter;
8585
import com.facebook.react.uimanager.events.SynchronousEventReceiver;
86+
import com.facebook.react.views.image.ReactImageManager;
8687
import com.facebook.react.views.text.TextLayoutManager;
8788
import java.util.ArrayList;
8889
import java.util.HashMap;
@@ -872,6 +873,15 @@ public void runGuarded() {
872873
}
873874
}
874875

876+
/**
877+
* This method initiates preloading of an image specified by ImageSource. It can later be consumed
878+
* by an ImageView.
879+
*/
880+
public void requestImage(int surfaceId, int reactTag, ReadableMapBuffer params) {
881+
mMountingManager.experimental_prefetchResource(
882+
mReactApplicationContext, ReactImageManager.REACT_CLASS, surfaceId, reactTag, params);
883+
}
884+
875885
public void setBinding(FabricUIManagerBinding binding) {
876886
mBinding = binding;
877887
}
@@ -954,7 +964,6 @@ public void receiveEvent(
954964
* @param reactTag
955965
* @param eventName
956966
* @param canCoalesceEvent
957-
* @param customCoalesceKey
958967
* @param params
959968
* @param eventCategory
960969
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include "ImageFetcher.h"
9+
#include <react/renderer/imagemanager/conversions.h>
10+
11+
namespace facebook::react {
12+
13+
ImageFetcher::ImageFetcher(const ContextContainer::Shared& contextContainer) {
14+
fabricUIManager_ =
15+
contextContainer->at<jni::global_ref<jobject>>("FabricUIManager");
16+
requestImage_ =
17+
fabricUIManager_->getClass()
18+
->getMethod<void(SurfaceId, Tag, JReadableMapBuffer::javaobject)>(
19+
"requestImage");
20+
}
21+
22+
ImageRequest ImageFetcher::requestImage(
23+
const ImageSource& imageSource,
24+
const ImageRequestParams& imageRequestParams,
25+
SurfaceId surfaceId,
26+
Tag tag) const {
27+
auto serializedImageRequest =
28+
serializeImageRequest(imageSource, imageRequestParams);
29+
30+
auto readableMapBuffer =
31+
JReadableMapBuffer::createWithContents(std::move(serializedImageRequest));
32+
33+
requestImage_(fabricUIManager_, surfaceId, tag, readableMapBuffer.get());
34+
35+
auto telemetry = std::make_shared<ImageTelemetry>(surfaceId);
36+
37+
return {imageSource, telemetry};
38+
}
39+
} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
#include <fbjni/fbjni.h>
11+
12+
#include <react/common/mapbuffer/JReadableMapBuffer.h>
13+
#include <react/jni/ReadableNativeMap.h>
14+
#include <react/renderer/imagemanager/ImageRequest.h>
15+
#include <react/renderer/imagemanager/ImageRequestParams.h>
16+
#include <react/utils/ContextContainer.h>
17+
18+
namespace facebook::react {
19+
20+
class ImageFetcher {
21+
public:
22+
ImageFetcher(const ContextContainer::Shared& contextContainer);
23+
ImageFetcher(const ImageFetcher&) = delete;
24+
ImageFetcher& operator=(const ImageFetcher&) = delete;
25+
ImageFetcher(ImageFetcher&&) = default;
26+
~ImageFetcher() = default;
27+
28+
void discardImageRequest(const std::string& imageRequestCacheKey) const;
29+
30+
ImageRequest requestImage(
31+
const ImageSource& imageSource,
32+
const ImageRequestParams& imageRequestParams,
33+
SurfaceId surfaceId,
34+
Tag tag) const;
35+
36+
private:
37+
jni::global_ref<jobject> fabricUIManager_;
38+
jni::JMethod<void(SurfaceId, Tag, JReadableMapBuffer::javaobject)>
39+
requestImage_;
40+
};
41+
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/ImageManager.cpp

+19-11
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@
77

88
#include "ImageManager.h"
99

10+
#include <react/featureflags/ReactNativeFeatureFlags.h>
11+
#include "ImageFetcher.h"
12+
1013
namespace facebook::react {
1114

12-
ImageManager::ImageManager(
13-
const ContextContainer::Shared& /*contextContainer*/) {
14-
// Silence unused-private-field warning.
15-
(void)self_;
16-
// Not implemented.
17-
}
15+
ImageManager::ImageManager(const ContextContainer::Shared& contextContainer)
16+
: self_(new ImageFetcher(contextContainer)) {}
1817

19-
ImageManager::~ImageManager() = default;
18+
ImageManager::~ImageManager() {
19+
// NOLINT(cppcoreguidelines-no-malloc)
20+
free(self_);
21+
}
2022

2123
ImageRequest ImageManager::requestImage(
2224
const ImageSource& imageSource,
@@ -26,10 +28,16 @@ ImageRequest ImageManager::requestImage(
2628

2729
ImageRequest ImageManager::requestImage(
2830
const ImageSource& imageSource,
29-
SurfaceId /*surfaceId*/,
30-
const ImageRequestParams& /*imageRequestParams*/,
31-
Tag /* tag */) const {
32-
return {imageSource, nullptr, {}};
31+
SurfaceId surfaceId,
32+
const ImageRequestParams& imageRequestParams,
33+
Tag tag) const {
34+
if (ReactNativeFeatureFlags::enableImagePrefetchingAndroid()) {
35+
// NOLINT(cppcoreguidelines-pro-type-cstyle-cast)
36+
return ((ImageFetcher*)self_)
37+
->requestImage(imageSource, imageRequestParams, surfaceId, tag);
38+
} else {
39+
return {imageSource, nullptr, {}};
40+
}
3341
}
3442

3543
} // namespace facebook::react

0 commit comments

Comments
 (0)