Allow launching inspector from dev menu
Reviewed By: davidaurelio Differential Revision: D4095356 fbshipit-source-id: 46e43578cdcd663316efb82dffde27b77294c5c0
This commit is contained in:
parent
18184a83f1
commit
f571d28e68
|
@ -19,6 +19,16 @@ public class Inspector {
|
|||
|
||||
private final HybridData mHybridData;
|
||||
|
||||
public static boolean isSupported() {
|
||||
try {
|
||||
// This isn't a very nice way to do this but it works :|
|
||||
instance().getPagesNative();
|
||||
return true;
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Page> getPages() {
|
||||
try {
|
||||
return Arrays.asList(instance().getPagesNative());
|
||||
|
|
|
@ -162,6 +162,12 @@ public class DevServerHelper {
|
|||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
public void openInspector(String id) {
|
||||
if (mInspectorPackagerConnection != null) {
|
||||
mInspectorPackagerConnection.sendOpenEvent(id);
|
||||
}
|
||||
}
|
||||
|
||||
public void closeInspectorConnection() {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
|
|
|
@ -42,6 +42,7 @@ import com.facebook.infer.annotation.Assertions;
|
|||
import com.facebook.react.R;
|
||||
import com.facebook.react.bridge.CatalystInstance;
|
||||
import com.facebook.react.bridge.DefaultNativeModuleCallExceptionHandler;
|
||||
import com.facebook.react.bridge.Inspector;
|
||||
import com.facebook.react.bridge.JavaJSExecutor;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
|
@ -358,6 +359,19 @@ public class DevSupportManagerImpl implements DevSupportManager, PackagerCommand
|
|||
handleReloadJS();
|
||||
}
|
||||
});
|
||||
if (Inspector.isSupported()) {
|
||||
options.put(
|
||||
"Debug JS on-device (experimental)", new DevOptionHandler() {
|
||||
@Override
|
||||
public void onOptionSelected() {
|
||||
List<Inspector.Page> pages = Inspector.getPages();
|
||||
if (pages.size() > 0) {
|
||||
// TODO: We should get the actual page id instead of the first one.
|
||||
mDevServerHelper.openInspector(String.valueOf(pages.get(0).getId()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
options.put(
|
||||
mDevSettings.isReloadOnJSChangeEnabled()
|
||||
? mApplicationContext.getString(R.string.catalyst_live_reload_off)
|
||||
|
|
|
@ -48,6 +48,15 @@ public class InspectorPackagerConnection {
|
|||
mConnection.close();
|
||||
}
|
||||
|
||||
public void sendOpenEvent(String pageId) {
|
||||
try {
|
||||
JSONObject payload = makePageIdPayload(pageId);
|
||||
sendEvent("open", payload);
|
||||
} catch (JSONException | IOException e) {
|
||||
FLog.e(TAG, "Failed to open page", e);
|
||||
}
|
||||
}
|
||||
|
||||
void handleProxyMessage(JSONObject message)
|
||||
throws JSONException, IOException {
|
||||
String event = message.getString("event");
|
||||
|
|
|
@ -8,31 +8,16 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
var child_process = require('child_process');
|
||||
var execFile = require('child_process').execFile;
|
||||
var fs = require('fs');
|
||||
var opn = require('opn');
|
||||
var path = require('path');
|
||||
|
||||
function getChromeAppName() {
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
return 'google chrome';
|
||||
case 'win32':
|
||||
return 'chrome';
|
||||
default:
|
||||
return 'google-chrome';
|
||||
}
|
||||
}
|
||||
const child_process = require('child_process');
|
||||
const execFile = require('child_process').execFile;
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const launchChrome = require('../util/launchChrome');
|
||||
|
||||
function launchChromeDevTools(port) {
|
||||
var debuggerURL = 'http://localhost:' + port + '/debugger-ui';
|
||||
console.log('Launching Dev Tools...');
|
||||
opn(debuggerURL, {app: [getChromeAppName()]}, function(err) {
|
||||
if (err) {
|
||||
console.error('Google Chrome exited with error:', err);
|
||||
}
|
||||
});
|
||||
launchChrome(debuggerURL);
|
||||
}
|
||||
|
||||
function escapePath(path) {
|
||||
|
@ -77,7 +62,7 @@ module.exports = function(options, isChromeConnected) {
|
|||
// TODO: Remove this case in the future
|
||||
console.log(
|
||||
'The method /launch-chrome-devtools is deprecated. You are ' +
|
||||
' probably using an application created with an older CLI with the ' +
|
||||
' probably using an application created with an older CLI with the ' +
|
||||
' packager of a newer CLI. Please upgrade your application: ' +
|
||||
'https://facebook.github.io/react-native/docs/upgrading.html');
|
||||
launchDevTools(options, isChromeConnected);
|
||||
|
|
|
@ -46,6 +46,7 @@ const parseUrl = require('url').parse;
|
|||
const WebSocket = require('ws');
|
||||
|
||||
const debug = require('debug')('ReactNativePackager:InspectorProxy');
|
||||
const launchChrome = require('./launchChrome');
|
||||
|
||||
type DevicePage = {
|
||||
id: string,
|
||||
|
@ -80,6 +81,10 @@ type DisconnectEvent = Message<'disconnect', {
|
|||
pageId?: string,
|
||||
}>;
|
||||
|
||||
type OpenEvent = Message<'open', {
|
||||
pageId?: string,
|
||||
}>;
|
||||
|
||||
type GetPages = Message<'getPages', ?Array<DevicePage>>;
|
||||
|
||||
type Event = WrappedEvent | ConnectEvent | DisconnectEvent | GetPages;
|
||||
|
@ -178,6 +183,8 @@ class Device {
|
|||
this._handleWrappedEvent(message);
|
||||
} else if (message.event === 'disconnect') {
|
||||
this._handleDisconnect(message);
|
||||
} else if (message.event === 'open') {
|
||||
this._handleOpen(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,6 +204,13 @@ class Device {
|
|||
this._removeConnection(pageId);
|
||||
}
|
||||
|
||||
_handleOpen(event: OpenEvent) {
|
||||
const payload = nullthrows(event.payload);
|
||||
const pageId = nullthrows(payload.pageId);
|
||||
const url = DEVTOOLS_URL_BASE + makeInspectorPageUrl(this._id, pageId);
|
||||
launchChrome(url);
|
||||
}
|
||||
|
||||
_removeConnection(pageId: string) {
|
||||
const socket = this._connections.get(pageId);
|
||||
if (socket) {
|
||||
|
@ -229,10 +243,7 @@ class InspectorProxy {
|
|||
}
|
||||
|
||||
_makePage(server: Address, deviceId: string, deviceName: string, devicePage: DevicePage): Page {
|
||||
// The inspector frontend doesn't handle urlencoded params so we
|
||||
// manually urlencode it and decode it on the other side in _createPageHandler
|
||||
const query = querystring.escape(`device=${deviceId}&page=${devicePage.id}`);
|
||||
const wsUrl = `localhost:${server.port}/inspector/page?${query}`;
|
||||
const wsUrl = makeInspectorPageUrl(deviceId, devicePage.id);
|
||||
return {
|
||||
id: `${deviceId}-${devicePage.id}`,
|
||||
title: devicePage.title,
|
||||
|
@ -393,6 +404,13 @@ function escapeHtmlSpecialChar(char: string): string {
|
|||
);
|
||||
}
|
||||
|
||||
function makeInspectorPageUrl(deviceId: string, pageId: string): string {
|
||||
// The inspector frontend doesn't handle urlencoded params so we
|
||||
// manually urlencode it and decode it on the other side in _createPageHandler
|
||||
const query = querystring.escape(`device=${deviceId}&page=${pageId}`);
|
||||
return `localhost:8081/inspector/page?${query}`;
|
||||
}
|
||||
|
||||
function attachToServer(server: http.Server, pathPrefix: string): InspectorProxy {
|
||||
const proxy = new InspectorProxy();
|
||||
proxy.attachToServer(server, pathPrefix);
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const opn = require('opn');
|
||||
|
||||
function getChromeAppName(): string {
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
return 'google chrome';
|
||||
case 'win32':
|
||||
return 'chrome';
|
||||
default:
|
||||
return 'google-chrome';
|
||||
}
|
||||
}
|
||||
|
||||
function launchChrome(url: string) {
|
||||
opn(url, {app: [getChromeAppName()]}, function(err) {
|
||||
if (err) {
|
||||
console.error('Google Chrome exited with error:', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = launchChrome;
|
Loading…
Reference in New Issue