Convert com.facebook.react.devsupport.inspector to Kotlin (#49087)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49087

I'm moving the whole module to be in Kotlin and updating the BUCK file.
Those files also have 0 usages in OSS so not a breaking change.

Changelog:
[Internal] [Changed] -

Reviewed By: robhogan

Differential Revision: D68953731

fbshipit-source-id: d8238bf805661cbdd6fb070a60f3e32b44ec9832
This commit is contained in:
Nicola Corti
2025-01-31 07:50:28 -08:00
committed by Facebook GitHub Bot
parent 5c2153784d
commit d37a8d2830
5 changed files with 124 additions and 135 deletions
@@ -2325,16 +2325,17 @@ public class com/facebook/react/devsupport/StackTraceHelper$StackFrameImpl : com
public fun toJSON ()Lorg/json/JSONObject;
}
public class com/facebook/react/devsupport/inspector/InspectorNetworkHelper {
public static fun loadNetworkResource (Ljava/lang/String;Lcom/facebook/react/devsupport/inspector/InspectorNetworkRequestListener;)V
public final class com/facebook/react/devsupport/inspector/InspectorNetworkHelper {
public static final field INSTANCE Lcom/facebook/react/devsupport/inspector/InspectorNetworkHelper;
public static final fun loadNetworkResource (Ljava/lang/String;Lcom/facebook/react/devsupport/inspector/InspectorNetworkRequestListener;)V
}
public class com/facebook/react/devsupport/inspector/InspectorNetworkRequestListener {
public final class com/facebook/react/devsupport/inspector/InspectorNetworkRequestListener {
public fun <init> (Lcom/facebook/jni/HybridData;)V
public fun onCompletion ()V
public fun onData (Ljava/lang/String;)V
public fun onError (Ljava/lang/String;)V
public fun onHeaders (ILjava/util/Map;)V
public final fun onCompletion ()V
public final fun onData (Ljava/lang/String;)V
public final fun onError (Ljava/lang/String;)V
public final fun onHeaders (ILjava/util/Map;)V
}
public abstract interface class com/facebook/react/devsupport/interfaces/BundleLoadCallback {
@@ -1,94 +0,0 @@
/*
* 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.
*/
package com.facebook.react.devsupport.inspector;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class InspectorNetworkHelper {
private static OkHttpClient client;
private InspectorNetworkHelper() {}
public static void loadNetworkResource(String url, InspectorNetworkRequestListener listener) {
if (client == null) {
client =
new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read
.build();
}
Request request;
try {
request = new Request.Builder().url(url).build();
} catch (IllegalArgumentException e) {
listener.onError("Not a valid URL: " + url);
return;
}
// TODO(T196951523): Assign cancel function to listener
Call call = client.newCall(request);
call.enqueue(
new Callback() {
@Override
public void onFailure(Call call, IOException e) {
if (call.isCanceled()) {
return;
}
listener.onError(e.getMessage());
}
@Override
public void onResponse(Call call, Response response) {
Headers headers = response.headers();
HashMap<String, String> headersMap = new HashMap<>();
for (String name : headers.names()) {
headersMap.put(name, headers.get(name));
}
listener.onHeaders(response.code(), headersMap);
try (ResponseBody responseBody = response.body()) {
if (responseBody != null) {
InputStream inputStream = responseBody.byteStream();
int chunkSize = 1024;
byte[] buffer = new byte[chunkSize];
int bytesRead;
try {
while ((bytesRead = inputStream.read(buffer)) != -1) {
String chunk = new String(buffer, 0, bytesRead);
listener.onData(chunk);
}
} finally {
inputStream.close();
}
}
listener.onCompletion();
} catch (IOException e) {
listener.onError(e.getMessage());
}
}
});
}
}
@@ -0,0 +1,88 @@
/*
* 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.
*/
@file:Suppress("DEPRECATION_ERROR") // Conflicting okhttp versions
package com.facebook.react.devsupport.inspector
import java.io.IOException
import java.util.concurrent.TimeUnit
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
public object InspectorNetworkHelper {
private lateinit var client: OkHttpClient
@JvmStatic
public fun loadNetworkResource(url: String, listener: InspectorNetworkRequestListener) {
if (!::client.isInitialized) {
client =
OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read
.build()
}
val request =
try {
Request.Builder().url(url).build()
} catch (e: IllegalArgumentException) {
listener.onError("Not a valid URL: $url")
return
}
// TODO(T196951523): Assign cancel function to listener
val call = client.newCall(request)
call.enqueue(
object : Callback {
override fun onFailure(call: Call, e: IOException) {
if (call.isCanceled()) {
return
}
listener.onError(e.message)
}
override fun onResponse(call: Call, response: Response) {
val headers = response.headers()
val headersMap = HashMap<String?, String?>()
for (name in headers.names()) {
headersMap[name] = headers[name]
}
listener.onHeaders(response.code(), headersMap)
try {
response.body().use { responseBody ->
if (responseBody != null) {
val inputStream = responseBody.byteStream()
val chunkSize = 1024
val buffer = ByteArray(chunkSize)
var bytesRead: Int
inputStream.use { stream ->
while ((stream.read(buffer).also { bytesRead = it }) != -1) {
val chunk = String(buffer, 0, bytesRead)
listener.onData(chunk)
}
}
}
listener.onCompletion()
}
} catch (e: IOException) {
listener.onError(e.message)
}
}
})
}
}
@@ -1,34 +0,0 @@
/*
* 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.
*/
package com.facebook.react.devsupport.inspector;
import androidx.annotation.Nullable;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStripAny;
import java.util.Map;
/**
* JNI wrapper for {@code jsinspectormodern::NetworkRequestListener}. Handles the {@code
* ScopedExecutor} callback use on the C++ side.
*/
@DoNotStripAny
public class InspectorNetworkRequestListener {
private final HybridData mHybridData;
public InspectorNetworkRequestListener(HybridData hybridData) {
mHybridData = hybridData;
}
public native void onHeaders(int httpStatusCode, Map<String, String> headers);
public native void onData(String data);
public native void onError(@Nullable String message);
public native void onCompletion();
}
@@ -0,0 +1,28 @@
/*
* 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.
*/
package com.facebook.react.devsupport.inspector
import com.facebook.jni.HybridData
import com.facebook.proguard.annotations.DoNotStrip
import com.facebook.proguard.annotations.DoNotStripAny
/**
* JNI wrapper for `jsinspectormodern::NetworkRequestListener`. Handles the `ScopedExecutor`
* callback use on the C++ side.
*/
@DoNotStripAny
public class InspectorNetworkRequestListener
public constructor(@field:DoNotStrip private val mHybridData: HybridData) {
public external fun onHeaders(httpStatusCode: Int, headers: Map<String?, String?>?)
public external fun onData(data: String?)
public external fun onError(message: String?)
public external fun onCompletion()
}