Make android sdk crashless
Summary: This diff wraps all the important places where the java code is called in a try-catch block in order to avoid flipper bringing down an app. Reviewed By: jknoxville Differential Revision: D12839504 fbshipit-source-id: 4711bccbe6d50094d76ed7ecd1eb652cefc2a090
This commit is contained in:
committed by
Facebook Github Bot
parent
bcf6479a5e
commit
ddbb3c7f89
@@ -1,11 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the MIT license found in the LICENSE
|
* This source code is licensed under the MIT license found in the LICENSE
|
||||||
* file in the root directory of this source tree.
|
* file in the root directory of this source tree.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#ifdef FLIPPER_OSS
|
#ifdef FLIPPER_OSS
|
||||||
@@ -30,6 +29,14 @@ using namespace facebook::flipper;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
void handleException(const std::exception& e) {
|
||||||
|
// TODO: T35898390, report and log the exception in scribe
|
||||||
|
// TODO: T35898500, send flipper notification
|
||||||
|
std::string message = "Exception caught in C++ and suppressed: ";
|
||||||
|
message += e.what();
|
||||||
|
__android_log_write(ANDROID_LOG_ERROR, "FLIPPER", message.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
class JEventBase : public jni::HybridClass<JEventBase> {
|
class JEventBase : public jni::HybridClass<JEventBase> {
|
||||||
public:
|
public:
|
||||||
constexpr static auto kJavaDescriptor = "Lcom/facebook/flipper/android/EventBase;";
|
constexpr static auto kJavaDescriptor = "Lcom/facebook/flipper/android/EventBase;";
|
||||||
@@ -186,22 +193,45 @@ class JFlipperPlugin : public jni::JavaClass<JFlipperPlugin> {
|
|||||||
|
|
||||||
std::string identifier() const {
|
std::string identifier() const {
|
||||||
static const auto method = javaClassStatic()->getMethod<std::string()>("getId");
|
static const auto method = javaClassStatic()->getMethod<std::string()>("getId");
|
||||||
return method(self())->toStdString();
|
try {
|
||||||
|
return method(self())->toStdString();
|
||||||
|
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void didConnect(std::shared_ptr<FlipperConnection> conn) {
|
void didConnect(std::shared_ptr<FlipperConnection> conn) {
|
||||||
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JFlipperConnection::javaobject>)>("onConnect");
|
auto method =
|
||||||
method(self(), JFlipperConnectionImpl::newObjectCxxArgs(conn));
|
javaClassStatic()
|
||||||
|
->getMethod<void(jni::alias_ref<JFlipperConnection::javaobject>)>(
|
||||||
|
"onConnect");
|
||||||
|
try {
|
||||||
|
method(self(), JFlipperConnectionImpl::newObjectCxxArgs(conn));
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void didDisconnect() {
|
void didDisconnect() {
|
||||||
static const auto method = javaClassStatic()->getMethod<void()>("onDisconnect");
|
static const auto method = javaClassStatic()->getMethod<void()>("onDisconnect");
|
||||||
method(self());
|
try {
|
||||||
|
method(self());
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool runInBackground() {
|
bool runInBackground() {
|
||||||
static const auto method = javaClassStatic()->getMethod<jboolean()>("runInBackground");
|
static const auto method =
|
||||||
|
javaClassStatic()->getMethod<jboolean()>("runInBackground");
|
||||||
|
try {
|
||||||
return method(self()) == JNI_TRUE;
|
return method(self()) == JNI_TRUE;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -210,20 +240,41 @@ class JFlipperStateUpdateListener : public jni::JavaClass<JFlipperStateUpdateLis
|
|||||||
constexpr static auto kJavaDescriptor = "Lcom/facebook/flipper/core/FlipperStateUpdateListener;";
|
constexpr static auto kJavaDescriptor = "Lcom/facebook/flipper/core/FlipperStateUpdateListener;";
|
||||||
|
|
||||||
void onUpdate() {
|
void onUpdate() {
|
||||||
static const auto method = javaClassStatic()->getMethod<void()>("onUpdate");
|
try {
|
||||||
method(self());
|
static const auto method =
|
||||||
|
javaClassStatic()->getMethod<void()>("onUpdate");
|
||||||
|
method(self());
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void onStepStarted(std::string step) {
|
void onStepStarted(std::string step) {
|
||||||
static const auto method = javaClassStatic()->getMethod<void(std::string)>("onStepStarted");
|
try {
|
||||||
method(self(), step);
|
static const auto method =
|
||||||
|
javaClassStatic()->getMethod<void(std::string)>("onStepStarted");
|
||||||
|
method(self(), step);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void onStepSuccess(std::string step) {
|
void onStepSuccess(std::string step) {
|
||||||
static const auto method = javaClassStatic()->getMethod<void(std::string)>("onStepSuccess");
|
try {
|
||||||
method(self(), step);
|
static const auto method =
|
||||||
|
javaClassStatic()->getMethod<void(std::string)>("onStepSuccess");
|
||||||
|
method(self(), step);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void onStepFailed(std::string step, std::string errorMessage) {
|
void onStepFailed(std::string step, std::string errorMessage) {
|
||||||
static const auto method = javaClassStatic()->getMethod<void(std::string, std::string)>("onStepFailed");
|
try {
|
||||||
method(self(), step, errorMessage);
|
static const auto method =
|
||||||
|
javaClassStatic()->getMethod<void(std::string, std::string)>(
|
||||||
|
"onStepFailed");
|
||||||
|
method(self(), step, errorMessage);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -295,65 +346,116 @@ class JFlipperClient : public jni::HybridClass<JFlipperClient> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static jni::alias_ref<JFlipperClient::javaobject> getInstance(jni::alias_ref<jclass>) {
|
static jni::alias_ref<JFlipperClient::javaobject> getInstance(jni::alias_ref<jclass>) {
|
||||||
static auto client = make_global(newObjectCxxArgs());
|
try {
|
||||||
return client;
|
static auto client = make_global(newObjectCxxArgs());
|
||||||
|
return client;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
FlipperClient::instance()->start();
|
try {
|
||||||
|
FlipperClient::instance()->start();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop() {
|
void stop() {
|
||||||
FlipperClient::instance()->stop();
|
try {
|
||||||
|
FlipperClient::instance()->stop();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addPlugin(jni::alias_ref<JFlipperPlugin> plugin) {
|
void addPlugin(jni::alias_ref<JFlipperPlugin> plugin) {
|
||||||
auto wrapper = std::make_shared<JFlipperPluginWrapper>(make_global(plugin));
|
try {
|
||||||
FlipperClient::instance()->addPlugin(wrapper);
|
auto wrapper =
|
||||||
|
std::make_shared<JFlipperPluginWrapper>(make_global(plugin));
|
||||||
|
FlipperClient::instance()->addPlugin(wrapper);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void removePlugin(jni::alias_ref<JFlipperPlugin> plugin) {
|
void removePlugin(jni::alias_ref<JFlipperPlugin> plugin) {
|
||||||
auto client = FlipperClient::instance();
|
try {
|
||||||
client->removePlugin(client->getPlugin(plugin->identifier()));
|
auto client = FlipperClient::instance();
|
||||||
|
client->removePlugin(client->getPlugin(plugin->identifier()));
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void subscribeForUpdates(jni::alias_ref<JFlipperStateUpdateListener> stateListener) {
|
void subscribeForUpdates(jni::alias_ref<JFlipperStateUpdateListener> stateListener) {
|
||||||
auto client = FlipperClient::instance();
|
try {
|
||||||
mStateListener = std::make_shared<AndroidFlipperStateUpdateListener>(stateListener);
|
auto client = FlipperClient::instance();
|
||||||
client->setStateListener(mStateListener);
|
mStateListener =
|
||||||
|
std::make_shared<AndroidFlipperStateUpdateListener>(stateListener);
|
||||||
|
client->setStateListener(mStateListener);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsubscribe() {
|
void unsubscribe() {
|
||||||
auto client = FlipperClient::instance();
|
try {
|
||||||
mStateListener = nullptr;
|
auto client = FlipperClient::instance();
|
||||||
client->setStateListener(nullptr);
|
mStateListener = nullptr;
|
||||||
|
client->setStateListener(nullptr);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getState() {
|
std::string getState() {
|
||||||
return FlipperClient::instance()->getState();
|
try {
|
||||||
|
return FlipperClient::instance()->getState();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jni::global_ref<JStateSummary::javaobject> getStateSummary() {
|
jni::global_ref<JStateSummary::javaobject> getStateSummary() {
|
||||||
auto summary = jni::make_global(JStateSummary::create());
|
try {
|
||||||
auto elements = FlipperClient::instance()->getStateElements();
|
auto summary = jni::make_global(JStateSummary::create());
|
||||||
for (auto&& element : elements) {
|
auto elements = FlipperClient::instance()->getStateElements();
|
||||||
std::string status;
|
for (auto&& element : elements) {
|
||||||
switch (element.state_) {
|
std::string status;
|
||||||
case State::in_progress: status = "IN_PROGRESS"; break;
|
switch (element.state_) {
|
||||||
case State::failed: status = "FAILED"; break;
|
case State::in_progress:
|
||||||
case State::success: status = "SUCCESS"; break;
|
status = "IN_PROGRESS";
|
||||||
|
break;
|
||||||
|
case State::failed:
|
||||||
|
status = "FAILED";
|
||||||
|
break;
|
||||||
|
case State::success:
|
||||||
|
status = "SUCCESS";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
summary->addEntry(element.name_, status);
|
||||||
}
|
}
|
||||||
summary->addEntry(element.name_, status);
|
return summary;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
return summary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jni::alias_ref<JFlipperPlugin> getPlugin(const std::string& identifier) {
|
jni::alias_ref<JFlipperPlugin> getPlugin(const std::string& identifier) {
|
||||||
auto plugin = FlipperClient::instance()->getPlugin(identifier);
|
try {
|
||||||
if (plugin) {
|
auto plugin = FlipperClient::instance()->getPlugin(identifier);
|
||||||
auto wrapper = std::static_pointer_cast<JFlipperPluginWrapper>(plugin);
|
if (plugin) {
|
||||||
return wrapper->jplugin;
|
auto wrapper = std::static_pointer_cast<JFlipperPluginWrapper>(plugin);
|
||||||
} else {
|
return wrapper->jplugin;
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
handleException(e);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user