Skip to content

Commit

Permalink
Use context from entry point for prerendering
Browse files Browse the repository at this point in the history
Summary:
Some of the prerendered surfaces rely on Android context being present to have correct theming (e.g. for platform colors) and measurements of platform components. This change uses context provided to initialize the surface as themed context before view is attached.
This way it is possible to configure theming with `ContextThemeWrapper` the same way as Litho does it for prerendering. The assumption is that any kind of customization done through Android theme will be applied from prerendering entry point as well.

Changelog: [Internal] - Use context from surface for prerendering

Reviewed By: mdvacca

Differential Revision: D31906091

fbshipit-source-id: 344fc96eb2f85ba5b762bee64d1a29443b3fd1d3
  • Loading branch information
Andrei Shikov authored and facebook-github-bot committed Oct 26, 2021
1 parent d2c10da commit f58c496
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ public <T extends View> int addRootView(
ThemedReactContext reactContext =
new ThemedReactContext(
mReactApplicationContext, rootView.getContext(), reactRootView.getSurfaceID(), rootTag);
mMountingManager.startSurface(rootTag, rootView, reactContext);
mMountingManager.startSurface(rootTag, reactContext, rootView);
String moduleName = reactRootView.getJSModuleName();
if (ENABLE_FABRIC_LOGS) {
FLog.d(TAG, "Starting surface for module: %s and reactTag: %d", moduleName, rootTag);
Expand Down Expand Up @@ -271,7 +271,7 @@ public <T extends View> int startSurface(
if (ENABLE_FABRIC_LOGS) {
FLog.d(TAG, "Starting surface for module: %s and reactTag: %d", moduleName, rootTag);
}
mMountingManager.startSurface(rootTag, rootView, reactContext);
mMountingManager.startSurface(rootTag, reactContext, rootView);

// If startSurface is executed in the UIThread then, it uses the ViewportOffset from the View,
// Otherwise Fabric relies on calling {@link Binding#setConstraints} method to update the
Expand All @@ -295,18 +295,14 @@ public <T extends View> int startSurface(
return rootTag;
}

public void startSurface(final SurfaceHandler surfaceHandler, final @Nullable View rootView) {
public void startSurface(
final SurfaceHandler surfaceHandler, final Context context, final @Nullable View rootView) {
final int rootTag = ReactRootViewTagGenerator.getNextRootViewTag();

if (rootView == null) {
mMountingManager.startSurface(rootTag);
} else {
Context context = rootView.getContext();
ThemedReactContext reactContext =
new ThemedReactContext(
mReactApplicationContext, context, surfaceHandler.getModuleName(), rootTag);
mMountingManager.startSurface(rootTag, rootView, reactContext);
}
ThemedReactContext reactContext =
new ThemedReactContext(
mReactApplicationContext, context, surfaceHandler.getModuleName(), rootTag);
mMountingManager.startSurface(rootTag, reactContext, rootView);

surfaceHandler.setSurfaceId(rootTag);
if (surfaceHandler instanceof SurfaceHandlerBinding) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,27 +75,21 @@ public MountingManager(
mMountItemExecutor = mountItemExecutor;
}

/** Starts surface and attaches the root view. */
@AnyThread
public void startSurface(
final int surfaceId, @NonNull final View rootView, ThemedReactContext themedReactContext) {
SurfaceMountingManager mountingManager = startSurface(surfaceId);
mountingManager.attachRootView(rootView, themedReactContext);
}

/**
* Starts surface without attaching the view. All view operations executed against that surface
* will be queued until the view is attached.
*/
@AnyThread
public SurfaceMountingManager startSurface(final int surfaceId) {
public SurfaceMountingManager startSurface(
final int surfaceId, ThemedReactContext reactContext, @Nullable View rootView) {
SurfaceMountingManager surfaceMountingManager =
new SurfaceMountingManager(
surfaceId,
mJSResponderHandler,
mViewManagerRegistry,
mRootViewManager,
mMountItemExecutor);
mMountItemExecutor,
reactContext);

// There could technically be a race condition here if addRootView is called twice from
// different threads, though this is (probably) extremely unlikely, and likely an error.
Expand All @@ -111,6 +105,11 @@ public SurfaceMountingManager startSurface(final int surfaceId) {
}

mMostRecentSurfaceMountingManager = mSurfaceIdToManager.get(surfaceId);

if (rootView != null) {
surfaceMountingManager.attachRootView(rootView, reactContext);
}

return surfaceMountingManager;
}

Expand Down Expand Up @@ -314,8 +313,8 @@ public void updateProps(int reactTag, @Nullable ReadableMap props) {
}

/**
* Clears the JS Responder specified by {@link #setJSResponder(int, int, int, boolean)}. After
* this method is called, all the touch events are going to be handled by JS.
* Clears the JS Responder specified by {@link SurfaceMountingManager#setJSResponder}. After this
* method is called, all the touch events are going to be handled by JS.
*/
@UiThread
public void clearJSResponder() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,15 @@ public SurfaceMountingManager(
@NonNull JSResponderHandler jsResponderHandler,
@NonNull ViewManagerRegistry viewManagerRegistry,
@NonNull RootViewManager rootViewManager,
@NonNull MountItemExecutor mountItemExecutor) {
@NonNull MountItemExecutor mountItemExecutor,
@NonNull ThemedReactContext reactContext) {
mSurfaceId = surfaceId;

mJSResponderHandler = jsResponderHandler;
mViewManagerRegistry = viewManagerRegistry;
mRootViewManager = rootViewManager;
mMountItemExecutor = mountItemExecutor;
mThemedReactContext = reactContext;
}

public boolean isStopped() {
Expand Down

0 comments on commit f58c496

Please sign in to comment.