Enable flipper android to use different ports based on prop

Summary:
Part 1 of enabling flipper to run on custom ports: android SDK.
Still to go: iOS SDK and desktop

This should allow you to run mobile apps that use flipper on different ports than the default (8089,8088).

`adb shell`
`su`
`setprop flipper.ports 1111,2222`

From what I can tell, this only works on rooted devices.

Reviewed By: passy

Differential Revision: D13753238

fbshipit-source-id: c5f370c9d8c7382e8c17fb81d4010c642ef7c114
This commit is contained in:
John Knox
2019-01-24 03:08:42 -08:00
committed by Facebook Github Bot
parent c68e74c6a0
commit 324a7ae873
9 changed files with 171 additions and 92 deletions

View File

@@ -1,9 +1,8 @@
/*
* Copyright (c) Facebook, Inc.
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
#include <memory>
@@ -465,6 +464,8 @@ class JFlipperClient : public jni::HybridClass<JFlipperClient> {
jni::alias_ref<jclass>,
JEventBase* callbackWorker,
JEventBase* connectionWorker,
int insecurePort,
int securePort,
const std::string host,
const std::string os,
const std::string device,
@@ -472,20 +473,17 @@ class JFlipperClient : public jni::HybridClass<JFlipperClient> {
const std::string app,
const std::string appId,
const std::string privateAppDirectory) {
FlipperClient::init({
{
std::move(host),
FlipperClient::init({{std::move(host),
std::move(os),
std::move(device),
std::move(deviceId),
std::move(app),
std::move(appId),
std::move(privateAppDirectory)
},
std::move(privateAppDirectory)},
callbackWorker->eventBase(),
connectionWorker->eventBase()
});
connectionWorker->eventBase(),
insecurePort,
securePort});
}
private:

View File

@@ -1,9 +1,8 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.flipper.android;
@@ -36,6 +35,8 @@ public final class AndroidFlipperClient {
FlipperClientImpl.init(
sFlipperThread.getEventBase(),
sConnectionThread.getEventBase(),
FlipperProps.getInsecurePort(),
FlipperProps.getSecurePort(),
getServerHost(app),
"Android",
getFriendlyDeviceName(),

View File

@@ -1,9 +1,8 @@
/*
* Copyright (c) Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package com.facebook.flipper.android;
@@ -36,6 +35,8 @@ class FlipperClientImpl implements FlipperClient {
public static native void init(
EventBase callbackWorker,
EventBase connectionWorker,
int insecurePort,
int securePort,
String host,
String os,
String device,

View File

@@ -0,0 +1,84 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*/
package com.facebook.flipper.android;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
class FlipperProps {
private static final String FLIPPER_PORTS_PROP_NAME = "flipper.ports";
private static final int DEFAULT_INSECURE_PORT = 8089;
private static final int DEFAULT_SECURE_PORT = 8088;
private static final String TAG = "Flipper";
static int getInsecurePort() {
String propValue = getFlipperPortsPropValue();
return extractIntFromPropValue(propValue, 0, DEFAULT_INSECURE_PORT);
}
static int getSecurePort() {
String propValue = getFlipperPortsPropValue();
return extractIntFromPropValue(propValue, 1, DEFAULT_SECURE_PORT);
}
static int extractIntFromPropValue(String propValue, int index, int fallback) {
if (propValue != null && !propValue.isEmpty()) {
try {
String[] values = propValue.split(",");
if (values.length > index) {
return Integer.parseInt(values[index]);
}
} catch (NumberFormatException e) {
Log.e(TAG, "Failed to parse flipper.ports value: " + propValue);
}
}
return fallback;
}
private static String flipperPortsPropValue = null;
private static synchronized String getFlipperPortsPropValue() {
if (flipperPortsPropValue != null) {
return flipperPortsPropValue;
}
Process process = null;
BufferedReader reader = null;
try {
process =
Runtime.getRuntime().exec(new String[] {"/system/bin/getprop", FLIPPER_PORTS_PROP_NAME});
reader =
new BufferedReader(
new InputStreamReader(process.getInputStream(), Charset.forName("UTF-8")));
String lastLine = "";
String line;
while ((line = reader.readLine()) != null) {
lastLine = line;
}
flipperPortsPropValue = lastLine;
} catch (IOException e) {
Log.e(TAG, "Failed to query for flipper.ports prop", e);
flipperPortsPropValue = "";
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
Log.e(TAG, "Failed to close BufferedReader when reading flipper.ports prop", e);
}
if (process != null) {
process.destroy();
}
}
return flipperPortsPropValue;
}
}

View File

@@ -0,0 +1,43 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package com.facebook.flipper.android;
import static org.junit.Assert.assertEquals;
import com.facebook.testing.robolectric.v3.WithTestDefaultsRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(WithTestDefaultsRunner.class)
public class FlipperPropsTest {
@Test
public void shouldParseExpectedInput() throws Exception {
int value1 = FlipperProps.extractIntFromPropValue("1111,2222", 0, 1234);
assertEquals(value1, 1111);
int value2 = FlipperProps.extractIntFromPropValue("1111,2222", 1, 1234);
assertEquals(value2, 2222);
}
@Test
public void shouldFallbackForTruncatedInput() throws Exception {
int value = FlipperProps.extractIntFromPropValue("1111", 1, 1234);
assertEquals(value, 1234);
}
@Test
public void shouldFallbackForMistypedInput() throws Exception {
int value = FlipperProps.extractIntFromPropValue("111ds1", 0, 1234);
assertEquals(value, 1234);
}
@Test
public void shouldFallbackForEmptyInput() throws Exception {
int value = FlipperProps.extractIntFromPropValue("", 0, 1234);
assertEquals(value, 1234);
}
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.flipper.plugins.console;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.MatcherAssert.assertThat;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.testing.FlipperConnectionMock;
import com.facebook.flipper.testing.FlipperResponderMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class ConsoleFlipperPluginTest {
FlipperConnectionMock connection;
FlipperResponderMock responder;
@Before
public void setup() throws Exception {
JavascriptEnvironment jsEnvironment = new JavascriptEnvironment();
final ConsoleFlipperPlugin plugin = new ConsoleFlipperPlugin(jsEnvironment);
connection = new FlipperConnectionMock();
responder = new FlipperResponderMock();
plugin.onConnect(connection);
}
@Test
public void simpleExpressionShouldEvaluateCorrectly() throws Exception {
receiveScript("2 + 2");
assertThat(
responder.successes,
hasItem(new FlipperObject.Builder().put("value", 4).put("type", "json").build()));
}
private void receiveScript(String a) throws Exception {
FlipperObject getValue = new FlipperObject.Builder().put("command", a).build();
connection.receivers.get("executeCommand").onReceive(getValue, responder);
}
}

View File

@@ -24,8 +24,6 @@
static constexpr int reconnectIntervalSeconds = 2;
static constexpr int connectionKeepaliveSeconds = 10;
static constexpr int securePort = 8088;
static constexpr int insecurePort = 8089;
static constexpr int maxPayloadSize = 0xFFFFFF;
@@ -84,6 +82,8 @@ FlipperConnectionManagerImpl::FlipperConnectionManagerImpl(
std::shared_ptr<ConnectionContextStore> contextStore)
: deviceData_(config.deviceData),
flipperState_(state),
insecurePort(config.insecurePort),
securePort(config.securePort),
flipperEventBase_(config.callbackWorker),
connectionEventBase_(config.connectionWorker),
contextStore_(contextStore) {

View File

@@ -1,11 +1,9 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
#pragma once
#include "FlipperInitConfig.h"
@@ -49,6 +47,8 @@ class FlipperConnectionManagerImpl : public FlipperConnectionManager {
Callbacks* callbacks_;
DeviceData deviceData_;
std::shared_ptr<FlipperState> flipperState_;
int insecurePort;
int securePort;
folly::EventBase* flipperEventBase_;
folly::EventBase* connectionEventBase_;

View File

@@ -1,11 +1,9 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
#pragma once
#include <folly/io/async/EventBase.h>
@@ -39,6 +37,9 @@ struct FlipperInitConfig {
EventBase to be used to maintain the network connection.
*/
folly::EventBase* connectionWorker;
int insecurePort = 8089;
int securePort = 8088;
};
} // namespace flipper