mirror of
https://github.com/status-im/react-native.git
synced 2025-02-04 21:53:30 +00:00
Add Report Button for Android Redbox, enabled in Ads Manager, Groups and FB4A
Reviewed By: foghina Differential Revision: D3542780 fbshipit-source-id: a0dfb8b8af7a5ae0ca696e84ec4b8795a293c26f
This commit is contained in:
parent
42fc2e80db
commit
75e404bdde
@ -252,6 +252,7 @@ public class DevSupportManagerImpl implements DevSupportManager {
|
||||
// JS errors are reported here after source mapping.
|
||||
if (mRedBoxHandler != null) {
|
||||
mRedBoxHandler.handleRedbox(message, stack, RedBoxHandler.ErrorType.JS);
|
||||
mRedBoxDialog.resetReporting(true);
|
||||
}
|
||||
mRedBoxDialog.show();
|
||||
}
|
||||
@ -276,7 +277,7 @@ public class DevSupportManagerImpl implements DevSupportManager {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mRedBoxDialog == null) {
|
||||
mRedBoxDialog = new RedBoxDialog(mApplicationContext, DevSupportManagerImpl.this);
|
||||
mRedBoxDialog = new RedBoxDialog(mApplicationContext, DevSupportManagerImpl.this, mRedBoxHandler);
|
||||
mRedBoxDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||
}
|
||||
if (mRedBoxDialog.isShowing()) {
|
||||
@ -290,6 +291,9 @@ public class DevSupportManagerImpl implements DevSupportManager {
|
||||
// inside {@link #updateJSError} after source mapping.
|
||||
if (mRedBoxHandler != null && errorType == ErrorType.NATIVE) {
|
||||
mRedBoxHandler.handleRedbox(message, stack, RedBoxHandler.ErrorType.NATIVE);
|
||||
mRedBoxDialog.resetReporting(true);
|
||||
} else {
|
||||
mRedBoxDialog.resetReporting(false);
|
||||
}
|
||||
mRedBoxDialog.show();
|
||||
}
|
||||
|
@ -9,10 +9,15 @@
|
||||
|
||||
package com.facebook.react.devsupport;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.SpannedString;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@ -22,6 +27,7 @@ import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.facebook.common.logging.FLog;
|
||||
@ -30,6 +36,7 @@ import com.facebook.react.R;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.devsupport.StackTraceHelper.StackFrame;
|
||||
import com.facebook.react.devsupport.RedBoxHandler.ReportCompletedListener;
|
||||
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
@ -44,11 +51,59 @@ import org.json.JSONObject;
|
||||
|
||||
private final DevSupportManager mDevSupportManager;
|
||||
private final DoubleTapReloadRecognizer mDoubleTapReloadRecognizer;
|
||||
private final @Nullable RedBoxHandler mRedBoxHandler;
|
||||
|
||||
private ListView mStackView;
|
||||
private Button mReloadJs;
|
||||
private Button mDismiss;
|
||||
private Button mCopyToClipboard;
|
||||
private Button mReloadJsButton;
|
||||
private Button mDismissButton;
|
||||
private Button mCopyToClipboardButton;
|
||||
private @Nullable Button mReportButton;
|
||||
private @Nullable TextView mReportTextView;
|
||||
private @Nullable ProgressBar mLoadingIndicator;
|
||||
private @Nullable View mLineSeparator;
|
||||
private boolean isReporting = false;
|
||||
|
||||
private ReportCompletedListener mReportCompletedListener = new ReportCompletedListener() {
|
||||
@Override
|
||||
public void onReportSuccess(final SpannedString spannedString) {
|
||||
isReporting = false;
|
||||
Assertions.assertNotNull(mReportButton).setEnabled(true);
|
||||
Assertions.assertNotNull(mLoadingIndicator).setVisibility(View.GONE);
|
||||
Assertions.assertNotNull(mReportTextView).setText(spannedString);
|
||||
}
|
||||
@Override
|
||||
public void onReportError(final SpannedString spannedString) {
|
||||
isReporting = false;
|
||||
Assertions.assertNotNull(mReportButton).setEnabled(true);
|
||||
Assertions.assertNotNull(mLoadingIndicator).setVisibility(View.GONE);
|
||||
Assertions.assertNotNull(mReportTextView).setText(spannedString);
|
||||
}
|
||||
};
|
||||
|
||||
private View.OnClickListener mReportButtonOnClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mRedBoxHandler == null || !mRedBoxHandler.isReportEnabled() || isReporting) {
|
||||
return;
|
||||
}
|
||||
isReporting = true;
|
||||
Assertions.assertNotNull(mReportTextView).setText("Reporting...");
|
||||
Assertions.assertNotNull(mReportTextView).setVisibility(View.VISIBLE);
|
||||
Assertions.assertNotNull(mLoadingIndicator).setVisibility(View.VISIBLE);
|
||||
Assertions.assertNotNull(mLineSeparator).setVisibility(View.VISIBLE);
|
||||
Assertions.assertNotNull(mReportButton).setEnabled(false);
|
||||
|
||||
String title = Assertions.assertNotNull(mDevSupportManager.getLastErrorTitle());
|
||||
StackFrame[] stack = Assertions.assertNotNull(mDevSupportManager.getLastErrorStack());
|
||||
String sourceUrl = mDevSupportManager.getSourceUrl();
|
||||
|
||||
mRedBoxHandler.reportRedbox(
|
||||
title,
|
||||
stack,
|
||||
sourceUrl,
|
||||
Assertions.assertNotNull(mReportCompletedListener));
|
||||
}
|
||||
};
|
||||
|
||||
private static class StackAdapter extends BaseAdapter {
|
||||
private static final int VIEW_TYPE_COUNT = 2;
|
||||
@ -203,7 +258,10 @@ import org.json.JSONObject;
|
||||
}
|
||||
}
|
||||
|
||||
protected RedBoxDialog(Context context, DevSupportManager devSupportManager) {
|
||||
protected RedBoxDialog(
|
||||
Context context,
|
||||
DevSupportManager devSupportManager,
|
||||
@Nullable RedBoxHandler redBoxHandler) {
|
||||
super(context, R.style.Theme_Catalyst_RedBox);
|
||||
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
@ -212,25 +270,27 @@ import org.json.JSONObject;
|
||||
|
||||
mDevSupportManager = devSupportManager;
|
||||
mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer();
|
||||
mRedBoxHandler = redBoxHandler;
|
||||
|
||||
mStackView = (ListView) findViewById(R.id.rn_redbox_stack);
|
||||
mStackView.setOnItemClickListener(this);
|
||||
mReloadJs = (Button) findViewById(R.id.rn_redbox_reload_button);
|
||||
mReloadJs.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
mReloadJsButton = (Button) findViewById(R.id.rn_redbox_reload_button);
|
||||
mReloadJsButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mDevSupportManager.handleReloadJS();
|
||||
}
|
||||
});
|
||||
mDismiss = (Button) findViewById(R.id.rn_redbox_dismiss_button);
|
||||
mDismiss.setOnClickListener(new View.OnClickListener() {
|
||||
mDismissButton = (Button) findViewById(R.id.rn_redbox_dismiss_button);
|
||||
mDismissButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
mCopyToClipboard = (Button) findViewById(R.id.rn_redbox_copy_button);
|
||||
mCopyToClipboard.setOnClickListener(new View.OnClickListener() {
|
||||
mCopyToClipboardButton = (Button) findViewById(R.id.rn_redbox_copy_button);
|
||||
mCopyToClipboardButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String title = mDevSupportManager.getLastErrorTitle();
|
||||
@ -242,12 +302,38 @@ import org.json.JSONObject;
|
||||
StackTraceHelper.formatStackTrace(title, stack));
|
||||
}
|
||||
});
|
||||
|
||||
if (mRedBoxHandler != null && mRedBoxHandler.isReportEnabled()) {
|
||||
mLoadingIndicator = (ProgressBar) findViewById(R.id.rn_redbox_loading_indicator);
|
||||
mLineSeparator = (View) findViewById(R.id.rn_redbox_line_separator);
|
||||
mReportTextView = (TextView) findViewById(R.id.rn_redbox_report_label);
|
||||
mReportTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
mReportTextView.setHighlightColor(Color.TRANSPARENT);
|
||||
mReportButton = (Button) findViewById(R.id.rn_redbox_report_button);
|
||||
mReportButton.setOnClickListener(mReportButtonOnClickListener);
|
||||
}
|
||||
}
|
||||
|
||||
public void setExceptionDetails(String title, StackFrame[] stack) {
|
||||
mStackView.setAdapter(new StackAdapter(title, stack));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the report button, hide the report textview and the loading indicator.
|
||||
*/
|
||||
public void resetReporting(boolean enabled) {
|
||||
if (mRedBoxHandler == null || !mRedBoxHandler.isReportEnabled()) {
|
||||
return;
|
||||
}
|
||||
isReporting = false;
|
||||
Assertions.assertNotNull(mReportTextView).setVisibility(View.GONE);
|
||||
Assertions.assertNotNull(mLoadingIndicator).setVisibility(View.GONE);
|
||||
Assertions.assertNotNull(mLineSeparator).setVisibility(View.GONE);
|
||||
Assertions.assertNotNull(mReportButton).setVisibility(
|
||||
enabled ? View.VISIBLE : View.GONE);
|
||||
Assertions.assertNotNull(mReportButton).setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
new OpenStackFrameTask(mDevSupportManager).executeOnExecutor(
|
||||
|
@ -9,12 +9,14 @@
|
||||
|
||||
package com.facebook.react.devsupport;
|
||||
|
||||
import android.text.SpannedString;
|
||||
|
||||
import com.facebook.react.devsupport.StackTraceHelper.StackFrame;
|
||||
|
||||
/**
|
||||
* Interface used by {@link DevSupportManagerImpl} to allow interception on any redboxes
|
||||
* during development and handling the information from the redbox.
|
||||
* The implementation should be passed by {@link #setRedBoxHandler} in {@link ReactInstanceManager}.
|
||||
* The implementation should be passed by setRedBoxHandler in ReactInstanceManager.
|
||||
*/
|
||||
public interface RedBoxHandler {
|
||||
enum ErrorType {
|
||||
@ -29,5 +31,31 @@ public interface RedBoxHandler {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for {@link #reportRedbox}.
|
||||
*/
|
||||
interface ReportCompletedListener {
|
||||
void onReportSuccess(SpannedString spannedString);
|
||||
void onReportError(SpannedString spannedString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the information from the redbox.
|
||||
*/
|
||||
void handleRedbox(String title, StackFrame[] stack, ErrorType errorType);
|
||||
|
||||
/**
|
||||
* Whether the report feature is enabled.
|
||||
*/
|
||||
boolean isReportEnabled();
|
||||
|
||||
/**
|
||||
* Report the information from the redbox and set up a callback listener.
|
||||
*/
|
||||
void reportRedbox(
|
||||
String title,
|
||||
StackFrame[] stack,
|
||||
String sourceUrl,
|
||||
ReportCompletedListener reportCompletedListener);
|
||||
}
|
||||
|
@ -11,6 +11,42 @@
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<View
|
||||
android:id="@+id/rn_redbox_line_separator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@android:color/darker_gray"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<ProgressBar
|
||||
android:id="@+id/rn_redbox_loading_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
style="@android:style/Widget.ProgressBar.Small"
|
||||
android:indeterminateOnly="true"
|
||||
android:visibility="gone"
|
||||
android:paddingLeft="16dp"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/rn_redbox_report_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="monospace"
|
||||
android:visibility="gone"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:lineSpacingExtra="4dp"
|
||||
/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -27,6 +63,7 @@
|
||||
android:textSize="14sp"
|
||||
android:alpha="0.5"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:gravity="center_horizontal|top"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/rn_redbox_reload_button"
|
||||
@ -39,6 +76,7 @@
|
||||
android:textSize="14sp"
|
||||
android:alpha="0.5"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:gravity="center_horizontal|top"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/rn_redbox_copy_button"
|
||||
@ -51,6 +89,21 @@
|
||||
android:textSize="14sp"
|
||||
android:alpha="0.5"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:gravity="center_horizontal|top"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/rn_redbox_report_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_margin="4dp"
|
||||
android:text="@string/catalyst_report_button"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp"
|
||||
android:alpha="0.5"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:visibility="gone"
|
||||
android:gravity="center_horizontal|top"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -18,7 +18,8 @@
|
||||
<string name="catalyst_remotedbg_error" project="catalyst" translatable="false">Unable to connect with remote debugger</string>
|
||||
<string name="catalyst_element_inspector" project="catalyst" translatable="false">Toggle Inspector</string>
|
||||
<string name="catalyst_heap_capture" project="catalyst" translatable="false">Capture Heap</string>
|
||||
<string name="catalyst_dismiss_button" project="catalyst" translatable="false">Dismiss (ESC)</string>
|
||||
<string name="catalyst_reload_button" project="catalyst" translatable="false">Reload (R,\u00A0R)</string>
|
||||
<string name="catalyst_dismiss_button" project="catalyst" translatable="false">Dismiss\n(ESC)</string>
|
||||
<string name="catalyst_reload_button" project="catalyst" translatable="false">Reload\n(R,\u00A0R)</string>
|
||||
<string name="catalyst_copy_button" project="catalyst" translatable="false">Copy</string>
|
||||
<string name="catalyst_report_button" project="catalyst" translatable="false">Report</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user