/** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.react.uimanager.debug; import javax.annotation.Nullable; import android.util.SparseArray; import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.JSApplicationCausedNativeException; import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.module.annotations.ReactModule; /** * Native module that can asynchronously request the owners hierarchy of a react tag. * * Example returned owner hierarchy: ['RootView', 'Dialog', 'TitleView', 'Text'] */ @ReactModule(name = "DebugComponentOwnershipModule") public class DebugComponentOwnershipModule extends ReactContextBaseJavaModule { public interface RCTDebugComponentOwnership extends JavaScriptModule { void getOwnerHierarchy(int requestID, int tag); } /** * Callback for when we receive the ownership hierarchy in native code. * * NB: {@link #onOwnerHierarchyLoaded} will be called on the native modules thread! */ public static interface OwnerHierarchyCallback { void onOwnerHierarchyLoaded(int tag, @Nullable ReadableArray owners); } private final SparseArray<OwnerHierarchyCallback> mRequestIdToCallback = new SparseArray<>(); private @Nullable RCTDebugComponentOwnership mRCTDebugComponentOwnership; private int mNextRequestId = 0; public DebugComponentOwnershipModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public void initialize() { super.initialize(); mRCTDebugComponentOwnership = getReactApplicationContext(). getJSModule(RCTDebugComponentOwnership.class); } @Override public void onCatalystInstanceDestroy() { super.onCatalystInstanceDestroy(); mRCTDebugComponentOwnership = null; } @ReactMethod public synchronized void receiveOwnershipHierarchy( int requestId, int tag, @Nullable ReadableArray owners) { OwnerHierarchyCallback callback = mRequestIdToCallback.get(requestId); if (callback == null) { throw new JSApplicationCausedNativeException( "Got receiveOwnershipHierarchy for invalid request id: " + requestId); } mRequestIdToCallback.delete(requestId); callback.onOwnerHierarchyLoaded(tag, owners); } /** * Request to receive the component hierarchy for a particular tag. * * Example returned owner hierarchy: ['RootView', 'Dialog', 'TitleView', 'Text'] * * NB: The callback provided will be invoked on the native modules thread! */ public synchronized void loadComponentOwnerHierarchy(int tag, OwnerHierarchyCallback callback) { int requestId = mNextRequestId; mNextRequestId++; mRequestIdToCallback.put(requestId, callback); Assertions.assertNotNull(mRCTDebugComponentOwnership).getOwnerHierarchy(requestId, tag); } @Override public String getName() { return "DebugComponentOwnershipModule"; } }