-
Notifications
You must be signed in to change notification settings - Fork 24.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Release underlying resources when JS instance is GC'ed on Android
Summary: [Android] [Added] - Release underlying resources when JS instance is GC'ed on Android D15826082 was reverted because it introduced a crash in Ads Manager for Android (see P67222724). This diff fixes the crash and re-applies D15826082. The problem was that `jni::findClassStatic` in the destructor of BlobCollector.cpp couldn't find the Java class `com/facebook/react/modules/blob/BlobModule` and crashed the app. JNI didn't seem to have access to the Java class loader probably because the destructor was called from a non-Java thread (https://our.intern.facebook.com/intern/wiki/Fbjni/environment-and-thread-management/?vitals_event=wiki_click_navigation_link#threads). The fix is to wrap the code in the destructor inside `ThreadScope::WithClassLoader `, which will allow to run code that has full access to Java as though you were running in a Java thread. Reviewed By: shergin Differential Revision: D16122059 fbshipit-source-id: 12f14fa4a58218242a482c2c3e2149bb6770e8ec
- Loading branch information
1 parent
d656878
commit 88e18b6
Showing
11 changed files
with
215 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobCollector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.facebook.react.modules.blob; | ||
|
||
import com.facebook.react.bridge.JavaScriptContextHolder; | ||
import com.facebook.react.bridge.ReactContext; | ||
import com.facebook.soloader.SoLoader; | ||
|
||
/* package */ class BlobCollector { | ||
static { | ||
SoLoader.loadLibrary("reactnativeblob"); | ||
} | ||
|
||
static void install(final ReactContext reactContext, final BlobModule blobModule) { | ||
reactContext.runOnJSQueueThread( | ||
new Runnable() { | ||
@Override | ||
public void run() { | ||
JavaScriptContextHolder jsContext = reactContext.getJavaScriptContextHolder(); | ||
synchronized (jsContext) { | ||
nativeInstall(blobModule, jsContext.get()); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
private static native void nativeInstall(Object blobModule, long jsContext); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/Android.mk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Copyright (c) Facebook, Inc. and its affiliates. | ||
# | ||
# This source code is licensed under the MIT license found in the | ||
# LICENSE file in the root directory of this source tree. | ||
|
||
LOCAL_PATH := $(call my-dir) | ||
|
||
include $(CLEAR_VARS) | ||
|
||
LOCAL_MODULE := reactnativeblob | ||
|
||
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) | ||
|
||
LOCAL_C_INCLUDES := $(LOCAL_PATH) | ||
|
||
LOCAL_CFLAGS += -fvisibility=hidden -fexceptions -frtti | ||
|
||
LOCAL_STATIC_LIBRARIES := libjsi libjsireact jscruntime | ||
LOCAL_SHARED_LIBRARIES := libfolly_json libfb libreactnativejni | ||
|
||
include $(BUILD_SHARED_LIBRARY) |
22 changes: 22 additions & 0 deletions
22
ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BUCK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "FBJNI_TARGET", "react_native_target", "react_native_xplat_target", "rn_xplat_cxx_library") | ||
|
||
rn_xplat_cxx_library( | ||
name = "jni", | ||
srcs = glob(["*.cpp"]), | ||
headers = glob(["*.h"]), | ||
header_namespace = "", | ||
compiler_flags = ["-fexceptions"], | ||
fbandroid_allow_jni_merging = True, | ||
platforms = ANDROID, | ||
soname = "libreactnativeblob.$(ext)", | ||
visibility = [ | ||
"PUBLIC", | ||
], | ||
deps = [ | ||
"fbsource//xplat/folly:molly", | ||
FBJNI_TARGET, | ||
react_native_target("jni/react/jni:jni"), | ||
react_native_xplat_target("jsi:JSCRuntime"), | ||
react_native_xplat_target("jsiexecutor:jsiexecutor"), | ||
], | ||
) |
63 changes: 63 additions & 0 deletions
63
ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright 2004-present Facebook. All Rights Reserved. | ||
// This source code is licensed under the MIT license found in the | ||
// LICENSE file in the root directory of this source tree. | ||
|
||
#include "BlobCollector.h" | ||
|
||
#include <fb/fbjni.h> | ||
#include <memory> | ||
#include <mutex> | ||
|
||
using namespace facebook; | ||
|
||
namespace facebook { | ||
namespace react { | ||
|
||
static constexpr auto kBlobModuleJavaDescriptor = | ||
"com/facebook/react/modules/blob/BlobModule"; | ||
|
||
BlobCollector::BlobCollector( | ||
jni::global_ref<jobject> blobModule, | ||
const std::string &blobId) | ||
: blobModule_(blobModule), blobId_(blobId) {} | ||
|
||
BlobCollector::~BlobCollector() { | ||
jni::ThreadScope::WithClassLoader([&] { | ||
static auto removeMethod = jni::findClassStatic(kBlobModuleJavaDescriptor) | ||
->getMethod<void(jstring)>("remove"); | ||
removeMethod(blobModule_, jni::make_jstring(blobId_).get()); | ||
}); | ||
} | ||
|
||
void BlobCollector::nativeInstall( | ||
jni::alias_ref<jhybridobject> jThis, | ||
jni::alias_ref<jobject> blobModule, | ||
jlong jsContextNativePointer) { | ||
auto &runtime = *((jsi::Runtime *) jsContextNativePointer); | ||
auto blobModuleRef = jni::make_global(blobModule); | ||
runtime.global().setProperty( | ||
runtime, | ||
"__blobCollectorProvider", | ||
jsi::Function::createFromHostFunction( | ||
runtime, | ||
jsi::PropNameID::forAscii(runtime, "__blobCollectorProvider"), | ||
1, | ||
[blobModuleRef]( | ||
jsi::Runtime &rt, | ||
const jsi::Value &thisVal, | ||
const jsi::Value *args, | ||
size_t count) { | ||
auto blobId = args[0].asString(rt).utf8(rt); | ||
auto blobCollector = | ||
std::make_shared<BlobCollector>(blobModuleRef, blobId); | ||
return jsi::Object::createFromHostObject(rt, blobCollector); | ||
})); | ||
} | ||
|
||
void BlobCollector::registerNatives() { | ||
registerHybrid( | ||
{makeNativeMethod("nativeInstall", BlobCollector::nativeInstall)}); | ||
} | ||
|
||
} // namespace react | ||
} // namespace facebook |
39 changes: 39 additions & 0 deletions
39
ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright 2004-present Facebook. All Rights Reserved. | ||
// This source code is licensed under the MIT license found in the | ||
// LICENSE file in the root directory of this source tree. | ||
|
||
#pragma once | ||
|
||
#include <fb/fbjni.h> | ||
#include <jsi/jsi.h> | ||
|
||
namespace facebook { | ||
namespace react { | ||
|
||
class BlobCollector : public jni::HybridClass<BlobCollector>, | ||
public jsi::HostObject { | ||
public: | ||
BlobCollector( | ||
jni::global_ref<jobject> blobManager, | ||
const std::string &blobId); | ||
~BlobCollector(); | ||
|
||
static constexpr auto kJavaDescriptor = | ||
"Lcom/facebook/react/modules/blob/BlobCollector;"; | ||
|
||
static void nativeInstall( | ||
jni::alias_ref<jhybridobject> jThis, | ||
jni::alias_ref<jobject> blobModule, | ||
jlong jsContextNativePointer); | ||
|
||
static void registerNatives(); | ||
|
||
private: | ||
friend HybridBase; | ||
|
||
jni::global_ref<jobject> blobModule_; | ||
const std::string blobId_; | ||
}; | ||
|
||
} // namespace react | ||
} // namespace facebook |
13 changes: 13 additions & 0 deletions
13
ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/OnLoad.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright 2004-present Facebook. All Rights Reserved. | ||
|
||
// This source code is licensed under the MIT license found in the | ||
// LICENSE file in the root directory of this source tree. | ||
|
||
#include <fb/fbjni.h> | ||
|
||
#include "BlobCollector.h" | ||
|
||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { | ||
return facebook::jni::initialize( | ||
vm, [] { facebook::react::BlobCollector::registerNatives(); }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88e18b6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@makovkastar Thanks for your help landing this!
88e18b6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh my.. that... that allows the native side to perform side effects when JS objects are garbage collected...
Mind. Absolutely. Blown.
88e18b6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@janicduplessis thanks for creating this. I am not sure about the process here. Is there anything preventing this from getting merged?