From 776b06580f2a240dbd593d69c7cb090c4ff352c5 Mon Sep 17 00:00:00 2001 From: Vitali Zaidman Date: Fri, 9 May 2025 14:50:58 +0100 Subject: [PATCH 1/3] add launch id to termination screen --- front_end/panels/rn_welcome/RNWelcome.ts | 12 ++++++++++ front_end/panels/rn_welcome/rnWelcome.css | 7 ++++++ .../legacy/RemoteDebuggingTerminatedScreen.ts | 22 ++++++++++++++++++- .../remoteDebuggingTerminatedScreen.css | 13 ++++++----- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/front_end/panels/rn_welcome/RNWelcome.ts b/front_end/panels/rn_welcome/RNWelcome.ts index 2d6d772d780..17d63994316 100644 --- a/front_end/panels/rn_welcome/RNWelcome.ts +++ b/front_end/panels/rn_welcome/RNWelcome.ts @@ -7,6 +7,7 @@ import type * as Common from '../../core/common/common.js'; import * as UI from '../../ui/legacy/legacy.js'; import * as Host from '../../core/host/host.js'; import * as i18n from '../../core/i18n/i18n.js'; +import * as Root from '../../core/root/root.js'; import * as SDK from '../../core/sdk/sdk.js'; import rnWelcomeStyles from './rnWelcome.css.js'; @@ -25,6 +26,8 @@ const UIStrings = { docsLabel: 'Debugging docs', /** @description "What's new" link */ whatsNewLabel: "What's new", + /** @description Description for sharing the session ID of the current session with the user */ + sessionIdMessage: "[FB-only] The session ID for this React Native DevTools lauch is: ", /** @description "Debugging Basics" title (docs item 1) */ docsDebuggingBasics: 'Debugging Basics', /** @description "Debugging Basics" item detail */ @@ -132,6 +135,8 @@ export class RNWelcomeImpl extends UI.Widget.VBox implements import.meta.url, ).toString(); + const launchId = Root.Runtime.Runtime.queryParam('launchId'); + render(html`
@@ -162,6 +167,13 @@ export class RNWelcomeImpl extends UI.Widget.VBox implements ${i18nString(UIStrings.whatsNewLabel)}
+ ${launchId ? html` +
+ ${i18nString(UIStrings.sessionIdMessage)} +
+ ${launchId} +
+ ` : ''} ${this.#reactNativeVersion !== null && this.#reactNativeVersion !== undefined ? html`

React Native: ${this.#reactNativeVersion}

` : null} diff --git a/front_end/panels/rn_welcome/rnWelcome.css b/front_end/panels/rn_welcome/rnWelcome.css index 3ff5f3d0be1..d6eef0adda0 100644 --- a/front_end/panels/rn_welcome/rnWelcome.css +++ b/front_end/panels/rn_welcome/rnWelcome.css @@ -101,6 +101,13 @@ border-right: 1px solid var(--color-details-hairline); } +.rn-session-id { + display: flex; + align-items: center; + margin-top: 24px; + user-select: all; +} + .rn-welcome-version { position: fixed; top: 8px; diff --git a/front_end/ui/legacy/RemoteDebuggingTerminatedScreen.ts b/front_end/ui/legacy/RemoteDebuggingTerminatedScreen.ts index d9f8b74792a..731b2497675 100644 --- a/front_end/ui/legacy/RemoteDebuggingTerminatedScreen.ts +++ b/front_end/ui/legacy/RemoteDebuggingTerminatedScreen.ts @@ -4,6 +4,7 @@ import * as Host from '../../core/host/host.js'; import * as i18n from '../../core/i18n/i18n.js'; +import * as Root from '../../core/root/root.js'; import type * as Platform from '../../core/platform/platform.js'; import * as LitHtml from '../../ui/lit-html/lit-html.js'; @@ -50,6 +51,11 @@ const UIStrings = { * @description Text in a dialog box to prompt for feedback if the disconnection is unexpected. */ sendFeedbackMessage: '[FB-only] Please send feedback if this disconnection is unexpected.', + /** + * @description Text in a dialog box to prompt for feedback if the disconnection is unexpected, + * telling the user what's their session ID for easier debugging + */ + sendFeedbackLaunchIdMessage: 'Please include the following session ID:', /** * @description Label of the FB-only 'send feedback' button. */ @@ -76,8 +82,10 @@ export class RemoteDebuggingTerminatedScreen extends VBox {

${i18nString(UIStrings.title)}

${i18nString(UIStrings.debuggingConnectionWasClosed)} +
${reason}
+ ${feedbackLink !== null && feedbackLink !== undefined ? this.#createFeedbackSection(feedbackLink) : null}
${i18nString(UIStrings.reconnectWhenReadyByReopening)} @@ -95,7 +103,6 @@ export class RemoteDebuggingTerminatedScreen extends VBox { jslogContext: 'dismiss', })}
- ${feedbackLink !== null && feedbackLink !== undefined ? this.#createFeedbackSection(feedbackLink) : null} `, this.contentElement, {host: this}, @@ -121,9 +128,22 @@ export class RemoteDebuggingTerminatedScreen extends VBox { ); }; + const launchId = Root.Runtime.Runtime.queryParam('launchId'); + return html`
${i18nString(UIStrings.sendFeedbackMessage)}
+ ${launchId ? + html` +
+ ${i18nString(UIStrings.sendFeedbackLaunchIdMessage)} +
+
+ ${launchId} +
+ ` : '' + } +
${ createTextButton( i18nString(UIStrings.sendFeedback), diff --git a/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css b/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css index 02a5ef703a9..cfe83c3a788 100644 --- a/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css +++ b/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css @@ -6,6 +6,7 @@ .widget { padding: 20px; + user-select: all; } .remote-debugging-terminated-title { @@ -17,7 +18,7 @@ .remote-debugging-terminated-message { font-size: 14px; margin: 5px 0; - margin-bottom: 24px; + margin-bottom: 16px; } .remote-debugging-terminated-options { @@ -26,7 +27,6 @@ grid-gap: 8px; align-items: center; padding-top: 12px; - border-top: 1px solid var(--color-details-hairline-light); } .remote-debugging-terminated-label { @@ -45,7 +45,6 @@ display: flex; flex-direction: column; align-items: center; - margin-top: 16px; padding: 12px 16px; background-color: var(--color-background-elevation-1); border-radius: 6px; @@ -56,9 +55,13 @@ margin-bottom: 8px; } -.remote-debugging-terminated-reason { - --override-reason-color: #8b0000; +.remote-debugging-terminated-feedback-launch-id { + color: red; +} +.remote-debugging-terminated-reason { + --override-reason-color: red; + line-height: 32px; color: var(--override-reason-color); } From c3a792f96fc9c7911b35dd67eea5afcea2bf4be2 Mon Sep 17 00:00:00 2001 From: Vitali Zaidman Date: Fri, 9 May 2025 17:03:44 +0100 Subject: [PATCH 2/3] add devtools disconnected reasons --- front_end/global_typings/react_native.d.ts | 1 + .../legacy/RemoteDebuggingTerminatedScreen.ts | 39 +++++++++++++------ .../remoteDebuggingTerminatedScreen.css | 5 ++- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/front_end/global_typings/react_native.d.ts b/front_end/global_typings/react_native.d.ts index bfbc9b23fd3..c4251df3c96 100644 --- a/front_end/global_typings/react_native.d.ts +++ b/front_end/global_typings/react_native.d.ts @@ -10,6 +10,7 @@ declare global { var enableReactNativePerfMetrics: boolean|undefined; var enableReactNativePerfMetricsGlobalPostMessage: boolean|undefined; var enableReactNativeOpenInExternalEditor: boolean|undefined; + var enableDisplayingFullDisconnectedReason: boolean|undefined; var reactNativeOpenInEditorButtonImage: string|undefined; var FB_ONLY__reactNativeFeedbackLink: string|undefined; var FB_ONLY__enablePerformance: any; diff --git a/front_end/ui/legacy/RemoteDebuggingTerminatedScreen.ts b/front_end/ui/legacy/RemoteDebuggingTerminatedScreen.ts index 731b2497675..469333e0c38 100644 --- a/front_end/ui/legacy/RemoteDebuggingTerminatedScreen.ts +++ b/front_end/ui/legacy/RemoteDebuggingTerminatedScreen.ts @@ -25,6 +25,12 @@ const UIStrings = { * (see https://developer.chrome.com/docs/devtools/remote-debugging/). */ debuggingConnectionWasClosed: 'Debugging connection was closed. Reason: ', + /** + * @description Text in a dialog box in DevTools providing extra details on why remote debugging has been terminated. + * "Remote debugging" here means that DevTools on a PC is inspecting a website running on an actual mobile device + * (see https://developer.chrome.com/docs/devtools/remote-debugging/). + */ + debuggingConnectionWasClosedDetails: 'Details: ', /** * @description Text in a dialog box showing how to reconnect to DevTools when remote debugging has been terminated. * "Remote debugging" here means that DevTools on a PC is inspecting a website running on an actual mobile device @@ -68,7 +74,11 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); const {render, html} = LitHtml; export class RemoteDebuggingTerminatedScreen extends VBox { - constructor(reason: string, onClose?: () => void) { + constructor( + reason: string, + connectionLostDetails?: {reason?: string, code?: string, errorType?: string}, + onClose?: () => void + ) { super(true); this.registerCSSFiles([remoteDebuggingTerminatedScreenStyles]); @@ -81,21 +91,28 @@ export class RemoteDebuggingTerminatedScreen extends VBox { html`

${i18nString(UIStrings.title)}

- ${i18nString(UIStrings.debuggingConnectionWasClosed)} -
- ${reason} +
${i18nString(UIStrings.debuggingConnectionWasClosed)}
+
${reason}
+ ${globalThis.enableDisplayingFullDisconnectedReason ? + html` +
+ ${i18nString(UIStrings.debuggingConnectionWasClosedDetails)} +
+
+ +
+ ` : ''}
${feedbackLink !== null && feedbackLink !== undefined ? this.#createFeedbackSection(feedbackLink) : null}
${i18nString(UIStrings.reconnectWhenReadyByReopening)}
- ${ - createTextButton( - i18nString(UIStrings.reconnectDevtools), - handleReconnect, - {className: 'primary-button', jslogContext: 'reconnect'}, - )} + ${createTextButton( + i18nString(UIStrings.reconnectDevtools), + handleReconnect, + {className: 'primary-button', jslogContext: 'reconnect'}, + )}
${i18nString(UIStrings.closeDialogDetail)}
@@ -116,7 +133,7 @@ export class RemoteDebuggingTerminatedScreen extends VBox { const dialog = new Dialog('remote-debnugging-terminated'); dialog.setSizeBehavior(SizeBehavior.MeasureContent); dialog.setDimmed(true); - new RemoteDebuggingTerminatedScreen(uiMessage, () => dialog.hide()).show(dialog.contentElement); + new RemoteDebuggingTerminatedScreen(uiMessage, connectionLostDetails, () => dialog.hide()).show(dialog.contentElement); dialog.show(); Host.rnPerfMetrics.remoteDebuggingTerminated(connectionLostDetails); } diff --git a/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css b/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css index cfe83c3a788..bb47c3c7924 100644 --- a/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css +++ b/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css @@ -61,8 +61,11 @@ .remote-debugging-terminated-reason { --override-reason-color: red; - line-height: 32px; color: var(--override-reason-color); + margin: 8px; + textarea { + width: 100%; + } } .theme-with-dark-background .reason, From 6aa6cc2575a64c7fec770d93a632a3ba7c67af1b Mon Sep 17 00:00:00 2001 From: Vitali Zaidman Date: Fri, 9 May 2025 17:04:46 +0100 Subject: [PATCH 3/3] allow displaying custom errors to the user for when devtools is disconnected --- .../components/utils/TargetDetachedDialog.ts | 34 +++++++++++++++++-- .../remoteDebuggingTerminatedScreen.css | 4 +-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/front_end/ui/legacy/components/utils/TargetDetachedDialog.ts b/front_end/ui/legacy/components/utils/TargetDetachedDialog.ts index da499434aff..ab66d6949b7 100644 --- a/front_end/ui/legacy/components/utils/TargetDetachedDialog.ts +++ b/front_end/ui/legacy/components/utils/TargetDetachedDialog.ts @@ -13,7 +13,21 @@ const UIStrings = { *@description Text on the remote debugging window to indicate the connection is lost */ websocketDisconnected: 'WebSocket disconnected', + /** + *@description Text on the remote debugging window to indicate the connection cannot be made because the device is not connected + */ + websocketDisconnectedUnregisteredDevice: 'The corresponding app for this DevTools session cannot be found. Please relaunch DevTools from the terminal.', + /** + *@description Text on the remote debugging window to indicate the connection to corresponding device was lost + */ + websocketDisconnectedConnectionLost: 'Connection lost to corresponding device' }; + +const DisconnectedReasonsUIStrings = { + UREGISTERED_DEVICE: UIStrings.websocketDisconnectedUnregisteredDevice, + CONNECTION_LOST: UIStrings.websocketDisconnectedConnectionLost +} + const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/utils/TargetDetachedDialog.ts', UIStrings); const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); export class TargetDetachedDialog extends SDK.SDKModel.SDKModel implements ProtocolProxyApi.InspectorDispatcher { @@ -33,9 +47,25 @@ export class TargetDetachedDialog extends SDK.SDKModel.SDKModel implements UI.RemoteDebuggingTerminatedScreen.RemoteDebuggingTerminatedScreen.show(reason); } + static getCustomUiReason(connectionLostDetails?: {reason?: string, code?: string, errorType?: string}): string | null { + if (!connectionLostDetails) { + return null; + } + + if (connectionLostDetails.code === "1011" && connectionLostDetails.reason?.includes('[UREGISTERED_DEVICE]')) { + return i18nString(DisconnectedReasonsUIStrings.UREGISTERED_DEVICE); + } + + if (connectionLostDetails.code === "1000" && connectionLostDetails.reason?.includes('[CONNECTION_LOST]')) { + return i18nString(DisconnectedReasonsUIStrings.CONNECTION_LOST); + } + + return null; + } + static webSocketConnectionLost(connectionLostDetails?: {reason?: string, code?: string, errorType?: string}): void { - UI.RemoteDebuggingTerminatedScreen.RemoteDebuggingTerminatedScreen.show( - i18nString(UIStrings.websocketDisconnected), connectionLostDetails); + const uiReason = TargetDetachedDialog.getCustomUiReason(connectionLostDetails) || i18nString(UIStrings.websocketDisconnected); + UI.RemoteDebuggingTerminatedScreen.RemoteDebuggingTerminatedScreen.show(uiReason, connectionLostDetails); } targetCrashed(): void { diff --git a/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css b/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css index bb47c3c7924..aa5d976704c 100644 --- a/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css +++ b/front_end/ui/legacy/remoteDebuggingTerminatedScreen.css @@ -6,7 +6,7 @@ .widget { padding: 20px; - user-select: all; + user-select: text; } .remote-debugging-terminated-title { @@ -26,7 +26,6 @@ grid-template-columns: 1fr auto; grid-gap: 8px; align-items: center; - padding-top: 12px; } .remote-debugging-terminated-label { @@ -48,6 +47,7 @@ padding: 12px 16px; background-color: var(--color-background-elevation-1); border-radius: 6px; + margin-bottom: 12px; } .remote-debugging-terminated-feedback-label {