Permalink
Browse files

Add Report Button for Android Redbox, enabled in Ads Manager, Groups …

…and FB4A

Reviewed By: foghina

Differential Revision: D3542780

fbshipit-source-id: a0dfb8b8af7a5ae0ca696e84ec4b8795a293c26f
  • Loading branch information...
1 parent 42fc2e8 commit 75e404bdde585484b85ce6c02617a6ff7369e007 @lebronJ lebronJ committed with Facebook Github Bot 6 Aug 1, 2016
@@ -252,6 +252,7 @@ public void run() {
// 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 @@ private void showNewError(
@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 void run() {
// 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.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.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 @@
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 @@ protected Void doInBackground(String... clipBoardString) {
}
}
- 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 @@ protected RedBoxDialog(Context context, DevSupportManager devSupportManager) {
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 @@ public void onClick(View v) {
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 String getName() {
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>

0 comments on commit 75e404b

Please sign in to comment.