Skip to content

Commit

Permalink
Add fabric support for maintainVisibleContentPosition on Android (fac…
Browse files Browse the repository at this point in the history
…ebook#35994)

Summary:
Implement a few missing bits for `maintainVisibleContentPosition` to work with fabric. The main thing needed is to add 2 fabric renderer listener methods to allow to hook into specific parts of the rendering process. We need some code to execute before view updates are executed and after view updates are executed. The current methods that are exposed do not work for this case. `willDispatchViewUpdates` is called from JS thread, and there doesn't seem to be a way to add UI blocks that will be executed at the right time like we do in paper. `didDispatchMountItems` is called for every frame which we don't want and will cause lots of overhead.

After that we simply need to call the right methods in the new renderer listener methods.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID] [ADDED] - Add fabric support for maintainVisibleContentPosition on Android

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

Pull Request resolved: facebook#35994

Test Plan: Tested in RN tester maintainVisibleContentPosition example on Android with fabric enabled.

Reviewed By: cipolleschi

Differential Revision: D44131763

Pulled By: cortinico

fbshipit-source-id: 32c0b5867d460537b18a70d472fd58052da6cf80
  • Loading branch information
janicduplessis authored and OlimpiaZurek committed May 22, 2023
1 parent 7fe091b commit 01d000c
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,16 @@ public void didScheduleMountItems(UIManager uiManager) {
mCurrentFrameNumber++;
}

@Override
public void willMountItems(UIManager uiManager) {
// noop
}

@Override
public void didMountItems(UIManager uiManager) {
// noop
}

// For FabricUIManager only
@Override
@UiThread
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,33 @@ public interface UIManagerListener {
/**
* Called right before view updates are dispatched at the end of a batch. This is useful if a
* module needs to add UIBlocks to the queue before it is flushed.
*
* <p>This is called by Paper only.
*/
void willDispatchViewUpdates(UIManager uiManager);
/* Called right after view updates are dispatched for a frame. */
/**
* Called on UIThread right before view updates are executed.
*
* <p>This is called by Fabric only.
*/
void willMountItems(UIManager uiManager);
/**
* Called on UIThread right after view updates are executed.
*
* <p>This is called by Fabric only.
*/
void didMountItems(UIManager uiManager);
/**
* Called on UIThread right after view updates are dispatched for a frame. Note that this will be
* called for every frame even if there are no updates.
*
* <p>This is called by Fabric only.
*/
void didDispatchMountItems(UIManager uiManager);
/* Called right after scheduleMountItems is called in Fabric, after a new tree is committed. */
/**
* Called right after scheduleMountItems is called in Fabric, after a new tree is committed.
*
* <p>This is called by Fabric only.
*/
void didScheduleMountItems(UIManager uiManager);
}
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,20 @@ public Map<String, Long> getPerformanceCounters() {
}

private class MountItemDispatchListener implements MountItemDispatcher.ItemDispatchListener {
@Override
public void willMountItems() {
for (UIManagerListener listener : mListeners) {
listener.willMountItems(FabricUIManager.this);
}
}

@Override
public void didMountItems() {
for (UIManagerListener listener : mListeners) {
listener.didMountItems(FabricUIManager.this);
}
}

@Override
public void didDispatchMountItems() {
for (UIManagerListener listener : mListeners) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ private boolean dispatchMountItems() {
return false;
}

mItemDispatchListener.willMountItems();

// As an optimization, execute all ViewCommands first
// This should be:
// 1) Performant: ViewCommands are often a replacement for SetNativeProps, which we've always
Expand Down Expand Up @@ -298,6 +300,9 @@ private boolean dispatchMountItems() {
}
mBatchedExecutionTime += SystemClock.uptimeMillis() - batchedExecutionStartTime;
}

mItemDispatchListener.didMountItems();

Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);

return true;
Expand Down Expand Up @@ -414,6 +419,10 @@ private static void printMountItem(MountItem mountItem, String prefix) {
}

public interface ItemDispatchListener {
void willMountItems();

void didMountItems();

void didDispatchMountItems();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.facebook.react.bridge.UIManagerListener;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.react.uimanager.common.ViewUtil;
import com.facebook.react.views.scroll.ReactScrollViewHelper.HasSmoothScroll;
import com.facebook.react.views.view.ReactViewGroup;
Expand Down Expand Up @@ -89,6 +90,14 @@ public void stop() {
* been updated.
*/
public void updateScrollPosition() {
// On Fabric this will be called internally in `didMountItems`.
if (ViewUtil.getUIManagerType(mScrollView.getId()) == UIManagerType.FABRIC) {
return;
}
updateScrollPositionInternal();
}

private void updateScrollPositionInternal() {
if (mConfig == null || mFirstVisibleView == null || mPrevFirstVisibleFrame == null) {
return;
}
Expand Down Expand Up @@ -169,6 +178,16 @@ public void run() {
});
}

@Override
public void willMountItems(UIManager uiManager) {
computeTargetView();
}

@Override
public void didMountItems(UIManager uiManager) {
updateScrollPositionInternal();
}

@Override
public void didDispatchMountItems(UIManager uiManager) {
// noop
Expand Down

0 comments on commit 01d000c

Please sign in to comment.