Run CLANGFORMAT on FlipperKit folder
Summary: This diff runs CLANGFORMAT lint on FlipperKit. I have added CLANGFORMAT as the lint engined for objc files in xplat/sonar. Right now the iOS folder is not formatted according to CLANGFORMAT. Ran `arc lint -a --paths-cmd "find ./iOS/FlipperKit -type f" --verbose` Reviewed By: passy Differential Revision: D19942170 fbshipit-source-id: af677323af4edb761f61f8f7e289cab743aa31f2
This commit is contained in:
committed by
Facebook Github Bot
parent
127eec5fa1
commit
ca513cf370
@@ -13,6 +13,7 @@ FlipperCppBridgingConnection is a simple ObjC wrapper around SonarConnection
|
|||||||
that forwards messages to the underlying C++ connection. This class allows
|
that forwards messages to the underlying C++ connection. This class allows
|
||||||
pure Objective-C plugins to send messages to the underlying connection.
|
pure Objective-C plugins to send messages to the underlying connection.
|
||||||
*/
|
*/
|
||||||
@interface FlipperCppBridgingConnection : NSObject <FlipperConnection>
|
@interface FlipperCppBridgingConnection : NSObject<FlipperConnection>
|
||||||
- (instancetype)initWithCppConnection:(std::shared_ptr<facebook::flipper::FlipperConnection>)conn;
|
- (instancetype)initWithCppConnection:
|
||||||
|
(std::shared_ptr<facebook::flipper::FlipperConnection>)conn;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ SonarCppBridgingResponder is a simple ObjC wrapper around FlipperResponder
|
|||||||
that forwards messages to the underlying C++ responder. This class allows
|
that forwards messages to the underlying C++ responder. This class allows
|
||||||
pure Objective-C plugins to send messages to the underlying responder.
|
pure Objective-C plugins to send messages to the underlying responder.
|
||||||
*/
|
*/
|
||||||
@interface FlipperCppBridgingResponder : NSObject <FlipperResponder>
|
@interface FlipperCppBridgingResponder : NSObject<FlipperResponder>
|
||||||
- (instancetype)initWithCppResponder:(std::shared_ptr<facebook::flipper::FlipperResponder>)responder;
|
- (instancetype)initWithCppResponder:
|
||||||
|
(std::shared_ptr<facebook::flipper::FlipperResponder>)responder;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
std::shared_ptr<facebook::flipper::FlipperResponder> responder_;
|
std::shared_ptr<facebook::flipper::FlipperResponder> responder_;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithCppResponder:(std::shared_ptr<facebook::flipper::FlipperResponder>)responder
|
- (instancetype)initWithCppResponder:
|
||||||
{
|
(std::shared_ptr<facebook::flipper::FlipperResponder>)responder {
|
||||||
if (!responder) {
|
if (!responder) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
@@ -28,8 +28,14 @@
|
|||||||
|
|
||||||
#pragma mark - FlipperResponder
|
#pragma mark - FlipperResponder
|
||||||
|
|
||||||
- (void)success:(NSDictionary *)response { responder_->success(facebook::cxxutils::convertIdToFollyDynamic(response, true)); }
|
- (void)success:(NSDictionary*)response {
|
||||||
|
responder_->success(
|
||||||
|
facebook::cxxutils::convertIdToFollyDynamic(response, true));
|
||||||
|
}
|
||||||
|
|
||||||
- (void)error:(NSDictionary *)response { responder_->error(facebook::cxxutils::convertIdToFollyDynamic(response, true)); }
|
- (void)error:(NSDictionary*)response {
|
||||||
|
responder_->error(
|
||||||
|
facebook::cxxutils::convertIdToFollyDynamic(response, true));
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace flipper {
|
namespace flipper {
|
||||||
|
|
||||||
using ObjCPlugin = NSObject<FlipperPlugin> *;
|
using ObjCPlugin = NSObject<FlipperPlugin>*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
SonarCppWrapperPlugin is a simple C++ wrapper around Objective-C Sonar plugins
|
SonarCppWrapperPlugin is a simple C++ wrapper around Objective-C Sonar plugins
|
||||||
@@ -24,19 +24,24 @@ that can be passed to SonarClient. This class allows developers to write pure
|
|||||||
Objective-C plugins if they want.
|
Objective-C plugins if they want.
|
||||||
*/
|
*/
|
||||||
class FlipperCppWrapperPlugin final : public facebook::flipper::FlipperPlugin {
|
class FlipperCppWrapperPlugin final : public facebook::flipper::FlipperPlugin {
|
||||||
public:
|
public:
|
||||||
// Under ARC copying objCPlugin *does* increment its retain count
|
// Under ARC copying objCPlugin *does* increment its retain count
|
||||||
FlipperCppWrapperPlugin(ObjCPlugin objCPlugin) : _objCPlugin(objCPlugin) {}
|
FlipperCppWrapperPlugin(ObjCPlugin objCPlugin) : _objCPlugin(objCPlugin) {}
|
||||||
|
|
||||||
std::string identifier() const override { return [[_objCPlugin identifier] UTF8String]; }
|
std::string identifier() const override {
|
||||||
|
return [[_objCPlugin identifier] UTF8String];
|
||||||
|
}
|
||||||
|
|
||||||
void didConnect(std::shared_ptr<facebook::flipper::FlipperConnection> conn) override
|
void didConnect(
|
||||||
{
|
std::shared_ptr<facebook::flipper::FlipperConnection> conn) override {
|
||||||
FlipperCppBridgingConnection *const bridgingConn = [[FlipperCppBridgingConnection alloc] initWithCppConnection:conn];
|
FlipperCppBridgingConnection* const bridgingConn =
|
||||||
|
[[FlipperCppBridgingConnection alloc] initWithCppConnection:conn];
|
||||||
[_objCPlugin didConnect:bridgingConn];
|
[_objCPlugin didConnect:bridgingConn];
|
||||||
}
|
}
|
||||||
|
|
||||||
void didDisconnect() override { [_objCPlugin didDisconnect]; }
|
void didDisconnect() override {
|
||||||
|
[_objCPlugin didDisconnect];
|
||||||
|
}
|
||||||
|
|
||||||
bool runInBackground() override {
|
bool runInBackground() override {
|
||||||
if ([_objCPlugin respondsToSelector:@selector(runInBackground)]) {
|
if ([_objCPlugin respondsToSelector:@selector(runInBackground)]) {
|
||||||
@@ -45,9 +50,11 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjCPlugin getObjCPlugin() { return _objCPlugin; }
|
ObjCPlugin getObjCPlugin() {
|
||||||
|
return _objCPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ObjCPlugin _objCPlugin;
|
ObjCPlugin _objCPlugin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace facebook {
|
|||||||
namespace cxxutils {
|
namespace cxxutils {
|
||||||
|
|
||||||
folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf = false);
|
folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf = false);
|
||||||
id convertFollyDynamicToId(const folly::dynamic &dyn);
|
id convertFollyDynamicToId(const folly::dynamic& dyn);
|
||||||
|
|
||||||
} }
|
} // namespace cxxutils
|
||||||
|
} // namespace facebook
|
||||||
|
|||||||
@@ -16,8 +16,7 @@ namespace cxxutils {
|
|||||||
* The implementation is taken from RCTFollyConvert(https://fburl.com/vzw8ql2q)
|
* The implementation is taken from RCTFollyConvert(https://fburl.com/vzw8ql2q)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
id convertFollyDynamicToId(const folly::dynamic &dyn)
|
id convertFollyDynamicToId(const folly::dynamic& dyn) {
|
||||||
{
|
|
||||||
// I could imagine an implementation which avoids copies by wrapping the
|
// I could imagine an implementation which avoids copies by wrapping the
|
||||||
// dynamic in a derived class of NSDictionary. We can do that if profiling
|
// dynamic in a derived class of NSDictionary. We can do that if profiling
|
||||||
// implies it will help.
|
// implies it will help.
|
||||||
@@ -32,10 +31,13 @@ id convertFollyDynamicToId(const folly::dynamic &dyn)
|
|||||||
case folly::dynamic::DOUBLE:
|
case folly::dynamic::DOUBLE:
|
||||||
return @(dyn.getDouble());
|
return @(dyn.getDouble());
|
||||||
case folly::dynamic::STRING:
|
case folly::dynamic::STRING:
|
||||||
return [[NSString alloc] initWithBytes:dyn.c_str() length:dyn.size() encoding:NSUTF8StringEncoding];
|
return [[NSString alloc] initWithBytes:dyn.c_str()
|
||||||
|
length:dyn.size()
|
||||||
|
encoding:NSUTF8StringEncoding];
|
||||||
case folly::dynamic::ARRAY: {
|
case folly::dynamic::ARRAY: {
|
||||||
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dyn.size()];
|
NSMutableArray* array =
|
||||||
for (auto &elem : dyn) {
|
[[NSMutableArray alloc] initWithCapacity:dyn.size()];
|
||||||
|
for (auto& elem : dyn) {
|
||||||
id obj = convertFollyDynamicToId(elem);
|
id obj = convertFollyDynamicToId(elem);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
[array addObject:obj];
|
[array addObject:obj];
|
||||||
@@ -44,8 +46,9 @@ id convertFollyDynamicToId(const folly::dynamic &dyn)
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
case folly::dynamic::OBJECT: {
|
case folly::dynamic::OBJECT: {
|
||||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:dyn.size()];
|
NSMutableDictionary* dict =
|
||||||
for (auto &elem : dyn.items()) {
|
[[NSMutableDictionary alloc] initWithCapacity:dyn.size()];
|
||||||
|
for (auto& elem : dyn.items()) {
|
||||||
id obj = convertFollyDynamicToId(elem.second);
|
id obj = convertFollyDynamicToId(elem.second);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
dict[convertFollyDynamicToId(elem.first)] = obj;
|
dict[convertFollyDynamicToId(elem.first)] = obj;
|
||||||
@@ -56,12 +59,11 @@ id convertFollyDynamicToId(const folly::dynamic &dyn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf)
|
folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf) {
|
||||||
{
|
|
||||||
if (json == nil || json == (id)kCFNull) {
|
if (json == nil || json == (id)kCFNull) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else if ([json isKindOfClass:[NSNumber class]]) {
|
} else if ([json isKindOfClass:[NSNumber class]]) {
|
||||||
const char *objCType = [json objCType];
|
const char* objCType = [json objCType];
|
||||||
switch (objCType[0]) {
|
switch (objCType[0]) {
|
||||||
// This is a c++ bool or C99 _Bool. On some platforms, BOOL is a bool.
|
// This is a c++ bool or C99 _Bool. On some platforms, BOOL is a bool.
|
||||||
case _C_BOOL:
|
case _C_BOOL:
|
||||||
@@ -109,8 +111,8 @@ folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf)
|
|||||||
// fall through
|
// fall through
|
||||||
}
|
}
|
||||||
} else if ([json isKindOfClass:[NSString class]]) {
|
} else if ([json isKindOfClass:[NSString class]]) {
|
||||||
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
|
NSData* data = [json dataUsingEncoding:NSUTF8StringEncoding];
|
||||||
return std::string(reinterpret_cast<const char *>(data.bytes), data.length);
|
return std::string(reinterpret_cast<const char*>(data.bytes), data.length);
|
||||||
} else if ([json isKindOfClass:[NSArray class]]) {
|
} else if ([json isKindOfClass:[NSArray class]]) {
|
||||||
folly::dynamic array = folly::dynamic::array;
|
folly::dynamic array = folly::dynamic::array;
|
||||||
for (id element in json) {
|
for (id element in json) {
|
||||||
@@ -120,8 +122,11 @@ folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf)
|
|||||||
} else if ([json isKindOfClass:[NSDictionary class]]) {
|
} else if ([json isKindOfClass:[NSDictionary class]]) {
|
||||||
__block folly::dynamic object = folly::dynamic::object();
|
__block folly::dynamic object = folly::dynamic::object();
|
||||||
|
|
||||||
[json enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, __unused BOOL *stop) {
|
[json enumerateKeysAndObjectsUsingBlock:^(
|
||||||
object.insert(convertIdToFollyDynamic(key, nullifyNanAndInf), convertIdToFollyDynamic(value, nullifyNanAndInf));
|
NSString* key, NSString* value, __unused BOOL* stop) {
|
||||||
|
object.insert(
|
||||||
|
convertIdToFollyDynamic(key, nullifyNanAndInf),
|
||||||
|
convertIdToFollyDynamic(value, nullifyNanAndInf));
|
||||||
}];
|
}];
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
|
|||||||
@@ -15,22 +15,23 @@
|
|||||||
|
|
||||||
static const NSTimeInterval ReconnectDelay = 1.0;
|
static const NSTimeInterval ReconnectDelay = 1.0;
|
||||||
|
|
||||||
@interface FKPortForwardingClient () <GCDAsyncSocketDelegate, PTChannelDelegate>
|
@interface FKPortForwardingClient ()<
|
||||||
{
|
GCDAsyncSocketDelegate,
|
||||||
|
PTChannelDelegate> {
|
||||||
NSUInteger _destPort;
|
NSUInteger _destPort;
|
||||||
NSUInteger _channelPort;
|
NSUInteger _channelPort;
|
||||||
NSNumber *_connectingToDeviceID;
|
NSNumber* _connectingToDeviceID;
|
||||||
NSNumber *_connectedDeviceID;
|
NSNumber* _connectedDeviceID;
|
||||||
NSDictionary *_connectedDeviceProperties;
|
NSDictionary* _connectedDeviceProperties;
|
||||||
BOOL _notConnectedQueueSuspended;
|
BOOL _notConnectedQueueSuspended;
|
||||||
PTChannel *_connectedChannel;
|
PTChannel* _connectedChannel;
|
||||||
dispatch_queue_t _notConnectedQueue;
|
dispatch_queue_t _notConnectedQueue;
|
||||||
dispatch_queue_t _clientSocketsQueue;
|
dispatch_queue_t _clientSocketsQueue;
|
||||||
NSMutableDictionary *_clientSockets;
|
NSMutableDictionary* _clientSockets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property (atomic, readonly) NSNumber *connectedDeviceID;
|
@property(atomic, readonly) NSNumber* connectedDeviceID;
|
||||||
@property (atomic, assign) PTChannel *connectedChannel;
|
@property(atomic, assign) PTChannel* connectedChannel;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -38,42 +39,40 @@ static const NSTimeInterval ReconnectDelay = 1.0;
|
|||||||
|
|
||||||
@synthesize connectedDeviceID = _connectedDeviceID;
|
@synthesize connectedDeviceID = _connectedDeviceID;
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init {
|
||||||
{
|
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
_notConnectedQueue = dispatch_queue_create("FKPortForwarding.notConnectedQueue", DISPATCH_QUEUE_SERIAL);
|
_notConnectedQueue = dispatch_queue_create(
|
||||||
_clientSocketsQueue = dispatch_queue_create("FKPortForwarding.clients", DISPATCH_QUEUE_SERIAL);
|
"FKPortForwarding.notConnectedQueue", DISPATCH_QUEUE_SERIAL);
|
||||||
|
_clientSocketsQueue = dispatch_queue_create(
|
||||||
|
"FKPortForwarding.clients", DISPATCH_QUEUE_SERIAL);
|
||||||
_clientSockets = [NSMutableDictionary dictionary];
|
_clientSockets = [NSMutableDictionary dictionary];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)forwardConnectionsToPort:(NSUInteger)port
|
- (void)forwardConnectionsToPort:(NSUInteger)port {
|
||||||
{
|
|
||||||
_destPort = port;
|
_destPort = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)connectToMultiplexingChannelOnPort:(NSUInteger)port
|
- (void)connectToMultiplexingChannelOnPort:(NSUInteger)port {
|
||||||
{
|
|
||||||
_channelPort = port;
|
_channelPort = port;
|
||||||
[self startListeningForDevices];
|
[self startListeningForDevices];
|
||||||
[self enqueueConnectToLocalIPv4Port];
|
[self enqueueConnectToLocalIPv4Port];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)close
|
- (void)close {
|
||||||
{
|
|
||||||
[self.connectedChannel close];
|
[self.connectedChannel close];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (PTChannel *)connectedChannel {
|
- (PTChannel*)connectedChannel {
|
||||||
return _connectedChannel;
|
return _connectedChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setConnectedChannel:(PTChannel *)connectedChannel {
|
- (void)setConnectedChannel:(PTChannel*)connectedChannel {
|
||||||
_connectedChannel = connectedChannel;
|
_connectedChannel = connectedChannel;
|
||||||
|
|
||||||
if (!_connectedChannel) {
|
if (!_connectedChannel) {
|
||||||
for (GCDAsyncSocket *sock in [_clientSockets objectEnumerator]) {
|
for (GCDAsyncSocket* sock in [_clientSockets objectEnumerator]) {
|
||||||
[sock setDelegate:nil];
|
[sock setDelegate:nil];
|
||||||
[sock disconnect];
|
[sock disconnect];
|
||||||
}
|
}
|
||||||
@@ -94,40 +93,52 @@ static const NSTimeInterval ReconnectDelay = 1.0;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - PTChannelDelegate
|
#pragma mark - PTChannelDelegate
|
||||||
|
|
||||||
- (void)ioFrameChannel:(PTChannel *)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(PTData *)payload {
|
- (void)ioFrameChannel:(PTChannel*)channel
|
||||||
//NSLog(@"received %@, %u, %u, %@", channel, type, tag, payload);
|
didReceiveFrameOfType:(uint32_t)type
|
||||||
|
tag:(uint32_t)tag
|
||||||
|
payload:(PTData*)payload {
|
||||||
|
// NSLog(@"received %@, %u, %u, %@", channel, type, tag, payload);
|
||||||
|
|
||||||
if (type == FKPortForwardingFrameTypeOpenPipe) {
|
if (type == FKPortForwardingFrameTypeOpenPipe) {
|
||||||
GCDAsyncSocket *sock = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_clientSocketsQueue];
|
GCDAsyncSocket* sock =
|
||||||
|
[[GCDAsyncSocket alloc] initWithDelegate:self
|
||||||
|
delegateQueue:_clientSocketsQueue];
|
||||||
sock.userData = @(tag);
|
sock.userData = @(tag);
|
||||||
_clientSockets[@(tag)] = sock;
|
_clientSockets[@(tag)] = sock;
|
||||||
|
|
||||||
NSError *connectError;
|
NSError* connectError;
|
||||||
if (![sock connectToHost:@"localhost" onPort:_destPort error:&connectError]) {
|
if (![sock connectToHost:@"localhost"
|
||||||
FBPFLog(@"Failed to connect to local %lu - %@", (unsigned long)_destPort, connectError);
|
onPort:_destPort
|
||||||
|
error:&connectError]) {
|
||||||
|
FBPFLog(
|
||||||
|
@"Failed to connect to local %lu - %@",
|
||||||
|
(unsigned long)_destPort,
|
||||||
|
connectError);
|
||||||
}
|
}
|
||||||
|
|
||||||
FBPFTrace(@"open socket (%d)", tag);
|
FBPFTrace(@"open socket (%d)", tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == FKPortForwardingFrameTypeWriteToPipe) {
|
if (type == FKPortForwardingFrameTypeWriteToPipe) {
|
||||||
GCDAsyncSocket *sock = _clientSockets[@(tag)];
|
GCDAsyncSocket* sock = _clientSockets[@(tag)];
|
||||||
[sock writeData:[NSData dataWithBytes:payload.data length:payload.length] withTimeout:-1 tag:0];
|
[sock writeData:[NSData dataWithBytes:payload.data length:payload.length]
|
||||||
|
withTimeout:-1
|
||||||
|
tag:0];
|
||||||
FBPFTrace(@"channel -> socket (%d) %zu bytes", tag, payload.length);
|
FBPFTrace(@"channel -> socket (%d) %zu bytes", tag, payload.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == FKPortForwardingFrameTypeClosePipe) {
|
if (type == FKPortForwardingFrameTypeClosePipe) {
|
||||||
GCDAsyncSocket *sock = _clientSockets[@(tag)];
|
GCDAsyncSocket* sock = _clientSockets[@(tag)];
|
||||||
[sock disconnectAfterWriting];
|
[sock disconnectAfterWriting];
|
||||||
FBPFTrace(@"close socket (%d)", tag);
|
FBPFTrace(@"close socket (%d)", tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)ioFrameChannel:(PTChannel *)channel didEndWithError:(NSError *)error {
|
- (void)ioFrameChannel:(PTChannel*)channel didEndWithError:(NSError*)error {
|
||||||
if (_connectedDeviceID && [_connectedDeviceID isEqualToNumber:channel.userInfo]) {
|
if (_connectedDeviceID &&
|
||||||
|
[_connectedDeviceID isEqualToNumber:channel.userInfo]) {
|
||||||
[self didDisconnectFromDevice:_connectedDeviceID];
|
[self didDisconnectFromDevice:_connectedDeviceID];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,69 +148,85 @@ static const NSTimeInterval ReconnectDelay = 1.0;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - GCDAsyncSocketDelegate
|
#pragma mark - GCDAsyncSocketDelegate
|
||||||
|
|
||||||
|
- (void)socket:(GCDAsyncSocket*)sock
|
||||||
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
|
didConnectToHost:(NSString*)host
|
||||||
{
|
port:(uint16_t)port {
|
||||||
FBPFTrace(@"socket (%ld) connected to %@", (long)[sock.userData integerValue], host);
|
FBPFTrace(
|
||||||
|
@"socket (%ld) connected to %@",
|
||||||
|
(long)[sock.userData integerValue],
|
||||||
|
host);
|
||||||
[sock readDataWithTimeout:-1 tag:0];
|
[sock readDataWithTimeout:-1 tag:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
|
- (void)socketDidDisconnect:(GCDAsyncSocket*)sock withError:(NSError*)err {
|
||||||
{
|
|
||||||
UInt32 tag = [sock.userData unsignedIntValue];
|
UInt32 tag = [sock.userData unsignedIntValue];
|
||||||
[_clientSockets removeObjectForKey:@(tag)];
|
[_clientSockets removeObjectForKey:@(tag)];
|
||||||
FBPFTrace(@"socket (%d) disconnected", (unsigned int)tag);
|
FBPFTrace(@"socket (%d) disconnected", (unsigned int)tag);
|
||||||
|
|
||||||
[_connectedChannel sendFrameOfType:FKPortForwardingFrameTypeClosePipe tag:tag withPayload:nil callback:nil];
|
[_connectedChannel sendFrameOfType:FKPortForwardingFrameTypeClosePipe
|
||||||
|
tag:tag
|
||||||
|
withPayload:nil
|
||||||
|
callback:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)_
|
- (void)socket:(GCDAsyncSocket*)sock didReadData:(NSData*)data withTag:(long)_ {
|
||||||
{
|
|
||||||
UInt32 tag = [sock.userData unsignedIntValue];
|
UInt32 tag = [sock.userData unsignedIntValue];
|
||||||
[_connectedChannel sendFrameOfType:FKPortForwardingFrameTypeWriteToPipe tag:tag withPayload:NSDataToGCDData(data) callback:^(NSError *error) {
|
[_connectedChannel sendFrameOfType:FKPortForwardingFrameTypeWriteToPipe
|
||||||
FBPFTrace(@"channel -> socket (%d), %lu bytes", (unsigned int)tag, (unsigned long)data.length);
|
tag:tag
|
||||||
[sock readDataWithTimeout:-1 tag:0];
|
withPayload:NSDataToGCDData(data)
|
||||||
}];
|
callback:^(NSError* error) {
|
||||||
|
FBPFTrace(
|
||||||
|
@"channel -> socket (%d), %lu bytes",
|
||||||
|
(unsigned int)tag,
|
||||||
|
(unsigned long)data.length);
|
||||||
|
[sock readDataWithTimeout:-1 tag:0];
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Wired device connections
|
#pragma mark - Wired device connections
|
||||||
|
|
||||||
|
|
||||||
- (void)startListeningForDevices {
|
- (void)startListeningForDevices {
|
||||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
|
||||||
|
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
|
|
||||||
[nc addObserverForName:PTUSBDeviceDidAttachNotification object:PTUSBHub.sharedHub queue:nil usingBlock:^(NSNotification *note) {
|
[nc addObserverForName:PTUSBDeviceDidAttachNotification
|
||||||
NSNumber *deviceID = [note.userInfo objectForKey:@"DeviceID"];
|
object:PTUSBHub.sharedHub
|
||||||
//NSLog(@"PTUSBDeviceDidAttachNotification: %@", note.userInfo);
|
queue:nil
|
||||||
FBPFTrace(@"PTUSBDeviceDidAttachNotification: %@", deviceID);
|
usingBlock:^(NSNotification* note) {
|
||||||
|
NSNumber* deviceID = [note.userInfo objectForKey:@"DeviceID"];
|
||||||
|
// NSLog(@"PTUSBDeviceDidAttachNotification: %@",
|
||||||
|
// note.userInfo);
|
||||||
|
FBPFTrace(@"PTUSBDeviceDidAttachNotification: %@", deviceID);
|
||||||
|
|
||||||
typeof(self) strongSelf = weakSelf;
|
typeof(self) strongSelf = weakSelf;
|
||||||
if (!strongSelf) {
|
if (!strongSelf) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch_async(strongSelf->_notConnectedQueue, ^{
|
dispatch_async(strongSelf->_notConnectedQueue, ^{
|
||||||
[strongSelf didAttachToDevice:deviceID note:note];
|
[strongSelf didAttachToDevice:deviceID note:note];
|
||||||
});
|
});
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[nc addObserverForName:PTUSBDeviceDidDetachNotification object:PTUSBHub.sharedHub queue:nil usingBlock:^(NSNotification *note) {
|
[nc addObserverForName:PTUSBDeviceDidDetachNotification
|
||||||
NSNumber *deviceID = [note.userInfo objectForKey:@"DeviceID"];
|
object:PTUSBHub.sharedHub
|
||||||
//NSLog(@"PTUSBDeviceDidDetachNotification: %@", note.userInfo);
|
queue:nil
|
||||||
FBPFTrace(@"PTUSBDeviceDidDetachNotification: %@", deviceID);
|
usingBlock:^(NSNotification* note) {
|
||||||
|
NSNumber* deviceID = [note.userInfo objectForKey:@"DeviceID"];
|
||||||
|
// NSLog(@"PTUSBDeviceDidDetachNotification: %@",
|
||||||
|
// note.userInfo);
|
||||||
|
FBPFTrace(@"PTUSBDeviceDidDetachNotification: %@", deviceID);
|
||||||
|
|
||||||
[weakSelf didDetachFromDevice:deviceID];
|
[weakSelf didDetachFromDevice:deviceID];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didAttachToDevice:(NSNumber *)deviceID note:(NSNotification *)note
|
- (void)didAttachToDevice:(NSNumber*)deviceID note:(NSNotification*)note {
|
||||||
{
|
if (!_connectingToDeviceID ||
|
||||||
if (!_connectingToDeviceID || ![deviceID isEqualToNumber:_connectingToDeviceID]) {
|
![deviceID isEqualToNumber:_connectingToDeviceID]) {
|
||||||
[self disconnectFromCurrentChannel];
|
[self disconnectFromCurrentChannel];
|
||||||
_connectingToDeviceID = deviceID;
|
_connectingToDeviceID = deviceID;
|
||||||
_connectedDeviceProperties = [note.userInfo objectForKey:@"Properties"];
|
_connectedDeviceProperties = [note.userInfo objectForKey:@"Properties"];
|
||||||
@@ -207,8 +234,7 @@ static const NSTimeInterval ReconnectDelay = 1.0;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didDetachFromDevice:(NSNumber *)deviceID
|
- (void)didDetachFromDevice:(NSNumber*)deviceID {
|
||||||
{
|
|
||||||
if ([_connectingToDeviceID isEqualToNumber:deviceID]) {
|
if ([_connectingToDeviceID isEqualToNumber:deviceID]) {
|
||||||
_connectedDeviceProperties = nil;
|
_connectedDeviceProperties = nil;
|
||||||
_connectingToDeviceID = nil;
|
_connectingToDeviceID = nil;
|
||||||
@@ -218,8 +244,7 @@ static const NSTimeInterval ReconnectDelay = 1.0;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)didDisconnectFromDevice:(NSNumber*)deviceID {
|
||||||
- (void)didDisconnectFromDevice:(NSNumber *)deviceID {
|
|
||||||
FBPFLog(@"Disconnected from device #%@", deviceID);
|
FBPFLog(@"Disconnected from device #%@", deviceID);
|
||||||
if ([_connectedDeviceID isEqualToNumber:deviceID]) {
|
if ([_connectedDeviceID isEqualToNumber:deviceID]) {
|
||||||
[self willChangeValueForKey:@"connectedDeviceID"];
|
[self willChangeValueForKey:@"connectedDeviceID"];
|
||||||
@@ -228,7 +253,6 @@ static const NSTimeInterval ReconnectDelay = 1.0;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)disconnectFromCurrentChannel {
|
- (void)disconnectFromCurrentChannel {
|
||||||
if (_connectedDeviceID && _connectedChannel) {
|
if (_connectedDeviceID && _connectedChannel) {
|
||||||
[_connectedChannel close];
|
[_connectedChannel close];
|
||||||
@@ -244,25 +268,34 @@ static const NSTimeInterval ReconnectDelay = 1.0;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)connectToLocalIPv4Port {
|
- (void)connectToLocalIPv4Port {
|
||||||
PTChannel *channel = [PTChannel channelWithDelegate:self];
|
PTChannel* channel = [PTChannel channelWithDelegate:self];
|
||||||
channel.userInfo = [NSString stringWithFormat:@"127.0.0.1:%lu", (unsigned long)_channelPort];
|
channel.userInfo =
|
||||||
[channel connectToPort:_channelPort IPv4Address:INADDR_LOOPBACK callback:^(NSError *error, PTAddress *address) {
|
[NSString stringWithFormat:@"127.0.0.1:%lu", (unsigned long)_channelPort];
|
||||||
if (error) {
|
[channel
|
||||||
if (error.domain == NSPOSIXErrorDomain && (error.code == ECONNREFUSED || error.code == ETIMEDOUT)) {
|
connectToPort:_channelPort
|
||||||
// this is an expected state
|
IPv4Address:INADDR_LOOPBACK
|
||||||
} else {
|
callback:^(NSError* error, PTAddress* address) {
|
||||||
FBPFTrace(@"Failed to connect to 127.0.0.1:%lu: %@", (unsigned long)_channelPort, error);
|
if (error) {
|
||||||
}
|
if (error.domain == NSPOSIXErrorDomain &&
|
||||||
} else {
|
(error.code == ECONNREFUSED || error.code == ETIMEDOUT)) {
|
||||||
[self disconnectFromCurrentChannel];
|
// this is an expected state
|
||||||
self.connectedChannel = channel;
|
} else {
|
||||||
channel.userInfo = address;
|
FBPFTrace(
|
||||||
FBPFLog(@"Connected to %@", address);
|
@"Failed to connect to 127.0.0.1:%lu: %@",
|
||||||
}
|
(unsigned long)_channelPort,
|
||||||
[self performSelector:@selector(enqueueConnectToLocalIPv4Port) withObject:nil afterDelay:ReconnectDelay];
|
error);
|
||||||
}];
|
}
|
||||||
|
} else {
|
||||||
|
[self disconnectFromCurrentChannel];
|
||||||
|
self.connectedChannel = channel;
|
||||||
|
channel.userInfo = address;
|
||||||
|
FBPFLog(@"Connected to %@", address);
|
||||||
|
}
|
||||||
|
[self performSelector:@selector(enqueueConnectToLocalIPv4Port)
|
||||||
|
withObject:nil
|
||||||
|
afterDelay:ReconnectDelay];
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)enqueueConnectToUSBDevice {
|
- (void)enqueueConnectToUSBDevice {
|
||||||
@@ -273,30 +306,35 @@ static const NSTimeInterval ReconnectDelay = 1.0;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)connectToUSBDevice {
|
- (void)connectToUSBDevice {
|
||||||
PTChannel *channel = [PTChannel channelWithDelegate:self];
|
PTChannel* channel = [PTChannel channelWithDelegate:self];
|
||||||
channel.userInfo = _connectingToDeviceID;
|
channel.userInfo = _connectingToDeviceID;
|
||||||
channel.delegate = self;
|
channel.delegate = self;
|
||||||
|
|
||||||
[channel connectToPort:(int)_channelPort overUSBHub:PTUSBHub.sharedHub deviceID:_connectingToDeviceID callback:^(NSError *error) {
|
[channel connectToPort:(int)_channelPort
|
||||||
[self didConnectToChannel:channel withError:error];
|
overUSBHub:PTUSBHub.sharedHub
|
||||||
}];
|
deviceID:_connectingToDeviceID
|
||||||
|
callback:^(NSError* error) {
|
||||||
|
[self didConnectToChannel:channel withError:error];
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didConnectToChannel:(PTChannel *)channel withError:(NSError *)error
|
- (void)didConnectToChannel:(PTChannel*)channel withError:(NSError*)error {
|
||||||
{
|
|
||||||
if (error) {
|
if (error) {
|
||||||
FBPFTrace(@"Failed to connect to device #%@: %@", channel.userInfo, error);
|
FBPFTrace(@"Failed to connect to device #%@: %@", channel.userInfo, error);
|
||||||
if (channel.userInfo == _connectingToDeviceID) {
|
if (channel.userInfo == _connectingToDeviceID) {
|
||||||
[self performSelector:@selector(enqueueConnectToUSBDevice) withObject:nil afterDelay:ReconnectDelay];
|
[self performSelector:@selector(enqueueConnectToUSBDevice)
|
||||||
|
withObject:nil
|
||||||
|
afterDelay:ReconnectDelay];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_connectedDeviceID = _connectingToDeviceID;
|
_connectedDeviceID = _connectingToDeviceID;
|
||||||
self.connectedChannel = channel;
|
self.connectedChannel = channel;
|
||||||
FBPFLog(@"Connected to device #%@\n%@", _connectingToDeviceID, _connectedDeviceProperties);
|
FBPFLog(
|
||||||
|
@"Connected to device #%@\n%@",
|
||||||
|
_connectingToDeviceID,
|
||||||
|
_connectedDeviceProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ enum {
|
|||||||
FKPortForwardingFrameTypeClosePipe = 203,
|
FKPortForwardingFrameTypeClosePipe = 203,
|
||||||
};
|
};
|
||||||
|
|
||||||
static dispatch_data_t NSDataToGCDData(NSData *data) {
|
static dispatch_data_t NSDataToGCDData(NSData* data) {
|
||||||
__block NSData *retainedData = data;
|
__block NSData* retainedData = data;
|
||||||
return dispatch_data_create(data.bytes, data.length, nil, ^{
|
return dispatch_data_create(data.bytes, data.length, nil, ^{
|
||||||
retainedData = nil;
|
retainedData = nil;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,26 +14,27 @@
|
|||||||
|
|
||||||
#import "FKPortForwardingCommon.h"
|
#import "FKPortForwardingCommon.h"
|
||||||
|
|
||||||
@interface FKPortForwardingServer () <PTChannelDelegate, GCDAsyncSocketDelegate>
|
@interface FKPortForwardingServer ()<
|
||||||
{
|
PTChannelDelegate,
|
||||||
__weak PTChannel *_serverChannel;
|
GCDAsyncSocketDelegate> {
|
||||||
__weak PTChannel *_peerChannel;
|
__weak PTChannel* _serverChannel;
|
||||||
|
__weak PTChannel* _peerChannel;
|
||||||
|
|
||||||
GCDAsyncSocket *_serverSocket;
|
GCDAsyncSocket* _serverSocket;
|
||||||
NSMutableDictionary *_clientSockets;
|
NSMutableDictionary* _clientSockets;
|
||||||
UInt32 _lastClientSocketTag;
|
UInt32 _lastClientSocketTag;
|
||||||
dispatch_queue_t _socketQueue;
|
dispatch_queue_t _socketQueue;
|
||||||
PTProtocol *_protocol;
|
PTProtocol* _protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation FKPortForwardingServer
|
@implementation FKPortForwardingServer
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init {
|
||||||
{
|
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
_socketQueue = dispatch_queue_create("FKPortForwardingServer", DISPATCH_QUEUE_SERIAL);
|
_socketQueue =
|
||||||
|
dispatch_queue_create("FKPortForwardingServer", DISPATCH_QUEUE_SERIAL);
|
||||||
_lastClientSocketTag = 0;
|
_lastClientSocketTag = 0;
|
||||||
_clientSockets = [NSMutableDictionary dictionary];
|
_clientSockets = [NSMutableDictionary dictionary];
|
||||||
_protocol = [[PTProtocol alloc] initWithDispatchQueue:_socketQueue];
|
_protocol = [[PTProtocol alloc] initWithDispatchQueue:_socketQueue];
|
||||||
@@ -41,24 +42,27 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc {
|
||||||
{
|
|
||||||
[self close];
|
[self close];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)forwardConnectionsFromPort:(NSUInteger)port
|
- (void)forwardConnectionsFromPort:(NSUInteger)port {
|
||||||
{
|
|
||||||
[self _forwardConnectionsFromPort:port reportError:YES];
|
[self _forwardConnectionsFromPort:port reportError:YES];
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
|
[[NSNotificationCenter defaultCenter]
|
||||||
[self _forwardConnectionsFromPort:port reportError:NO];
|
addObserverForName:UIApplicationDidBecomeActiveNotification
|
||||||
}];
|
object:nil
|
||||||
|
queue:nil
|
||||||
|
usingBlock:^(NSNotification* note) {
|
||||||
|
[self _forwardConnectionsFromPort:port reportError:NO];
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_forwardConnectionsFromPort:(NSUInteger)port reportError:(BOOL)shouldReportError
|
- (void)_forwardConnectionsFromPort:(NSUInteger)port
|
||||||
{
|
reportError:(BOOL)shouldReportError {
|
||||||
GCDAsyncSocket *serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_socketQueue];
|
GCDAsyncSocket* serverSocket =
|
||||||
NSError *listenError;
|
[[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_socketQueue];
|
||||||
|
NSError* listenError;
|
||||||
if ([serverSocket acceptOnPort:port error:&listenError]) {
|
if ([serverSocket acceptOnPort:port error:&listenError]) {
|
||||||
_serverSocket = serverSocket;
|
_serverSocket = serverSocket;
|
||||||
} else {
|
} else {
|
||||||
@@ -68,31 +72,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)listenForMultiplexingChannelOnPort:(NSUInteger)port
|
- (void)listenForMultiplexingChannelOnPort:(NSUInteger)port {
|
||||||
{
|
|
||||||
[self _listenForMultiplexingChannelOnPort:port reportError:YES];
|
[self _listenForMultiplexingChannelOnPort:port reportError:YES];
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
|
[[NSNotificationCenter defaultCenter]
|
||||||
[self _listenForMultiplexingChannelOnPort:port reportError:NO];
|
addObserverForName:UIApplicationDidBecomeActiveNotification
|
||||||
}];
|
object:nil
|
||||||
|
queue:nil
|
||||||
|
usingBlock:^(NSNotification* note) {
|
||||||
|
[self _listenForMultiplexingChannelOnPort:port reportError:NO];
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_listenForMultiplexingChannelOnPort:(NSUInteger)port reportError:(BOOL)shouldReportError
|
- (void)_listenForMultiplexingChannelOnPort:(NSUInteger)port
|
||||||
{
|
reportError:(BOOL)shouldReportError {
|
||||||
PTChannel *channel = [[PTChannel alloc] initWithProtocol:_protocol delegate:self];
|
PTChannel* channel = [[PTChannel alloc] initWithProtocol:_protocol
|
||||||
[channel listenOnPort:port IPv4Address:INADDR_LOOPBACK callback:^(NSError *error) {
|
delegate:self];
|
||||||
if (error) {
|
[channel
|
||||||
if (shouldReportError) {
|
listenOnPort:port
|
||||||
FBPFLog(@"Failed to listen on 127.0.0.1:%lu: %@", (unsigned long)port, error);
|
IPv4Address:INADDR_LOOPBACK
|
||||||
}
|
callback:^(NSError* error) {
|
||||||
} else {
|
if (error) {
|
||||||
FBPFTrace(@"Listening on 127.0.0.1:%lu", (unsigned long)port);
|
if (shouldReportError) {
|
||||||
self->_serverChannel = channel;
|
FBPFLog(
|
||||||
}
|
@"Failed to listen on 127.0.0.1:%lu: %@",
|
||||||
}];
|
(unsigned long)port,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FBPFTrace(@"Listening on 127.0.0.1:%lu", (unsigned long)port);
|
||||||
|
self->_serverChannel = channel;
|
||||||
|
}
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)close
|
- (void)close {
|
||||||
{
|
|
||||||
if (_serverChannel) {
|
if (_serverChannel) {
|
||||||
[_serverChannel close];
|
[_serverChannel close];
|
||||||
_serverChannel = nil;
|
_serverChannel = nil;
|
||||||
@@ -102,7 +115,9 @@
|
|||||||
|
|
||||||
#pragma mark - PTChannelDelegate
|
#pragma mark - PTChannelDelegate
|
||||||
|
|
||||||
- (void)ioFrameChannel:(PTChannel *)channel didAcceptConnection:(PTChannel *)otherChannel fromAddress:(PTAddress *)address {
|
- (void)ioFrameChannel:(PTChannel*)channel
|
||||||
|
didAcceptConnection:(PTChannel*)otherChannel
|
||||||
|
fromAddress:(PTAddress*)address {
|
||||||
// Cancel any other connection. We are FIFO, so the last connection
|
// Cancel any other connection. We are FIFO, so the last connection
|
||||||
// established will cancel any previous connection and "take its place".
|
// established will cancel any previous connection and "take its place".
|
||||||
if (_peerChannel) {
|
if (_peerChannel) {
|
||||||
@@ -116,22 +131,27 @@
|
|||||||
FBPFTrace(@"Connected to %@", address);
|
FBPFTrace(@"Connected to %@", address);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)ioFrameChannel:(PTChannel *)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(PTData *)payload {
|
- (void)ioFrameChannel:(PTChannel*)channel
|
||||||
//NSLog(@"didReceiveFrameOfType: %u, %u, %@", type, tag, payload);
|
didReceiveFrameOfType:(uint32_t)type
|
||||||
|
tag:(uint32_t)tag
|
||||||
|
payload:(PTData*)payload {
|
||||||
|
// NSLog(@"didReceiveFrameOfType: %u, %u, %@", type, tag, payload);
|
||||||
if (type == FKPortForwardingFrameTypeWriteToPipe) {
|
if (type == FKPortForwardingFrameTypeWriteToPipe) {
|
||||||
GCDAsyncSocket *sock = _clientSockets[@(tag)];
|
GCDAsyncSocket* sock = _clientSockets[@(tag)];
|
||||||
[sock writeData:[NSData dataWithBytes:payload.data length:payload.length] withTimeout:-1 tag:0];
|
[sock writeData:[NSData dataWithBytes:payload.data length:payload.length]
|
||||||
|
withTimeout:-1
|
||||||
|
tag:0];
|
||||||
FBPFTrace(@"channel -> socket (%d), %zu bytes", tag, payload.length);
|
FBPFTrace(@"channel -> socket (%d), %zu bytes", tag, payload.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == FKPortForwardingFrameTypeClosePipe) {
|
if (type == FKPortForwardingFrameTypeClosePipe) {
|
||||||
GCDAsyncSocket *sock = _clientSockets[@(tag)];
|
GCDAsyncSocket* sock = _clientSockets[@(tag)];
|
||||||
[sock disconnectAfterWriting];
|
[sock disconnectAfterWriting];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)ioFrameChannel:(PTChannel *)channel didEndWithError:(NSError *)error {
|
- (void)ioFrameChannel:(PTChannel*)channel didEndWithError:(NSError*)error {
|
||||||
for (GCDAsyncSocket *sock in [_clientSockets objectEnumerator]) {
|
for (GCDAsyncSocket* sock in [_clientSockets objectEnumerator]) {
|
||||||
[sock setDelegate:nil];
|
[sock setDelegate:nil];
|
||||||
[sock disconnect];
|
[sock disconnect];
|
||||||
}
|
}
|
||||||
@@ -139,11 +159,10 @@
|
|||||||
FBPFTrace(@"Disconnected from %@, error = %@", channel.userInfo, error);
|
FBPFTrace(@"Disconnected from %@, error = %@", channel.userInfo, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - GCDAsyncSocketDelegate
|
#pragma mark - GCDAsyncSocketDelegate
|
||||||
|
|
||||||
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
|
- (void)socket:(GCDAsyncSocket*)sock
|
||||||
{
|
didAcceptNewSocket:(GCDAsyncSocket*)newSocket {
|
||||||
dispatch_block_t block = ^() {
|
dispatch_block_t block = ^() {
|
||||||
if (!self->_peerChannel) {
|
if (!self->_peerChannel) {
|
||||||
[newSocket setDelegate:nil];
|
[newSocket setDelegate:nil];
|
||||||
@@ -154,37 +173,60 @@
|
|||||||
newSocket.userData = @(tag);
|
newSocket.userData = @(tag);
|
||||||
newSocket.delegate = self;
|
newSocket.delegate = self;
|
||||||
self->_clientSockets[@(tag)] = newSocket;
|
self->_clientSockets[@(tag)] = newSocket;
|
||||||
[self->_peerChannel sendFrameOfType:FKPortForwardingFrameTypeOpenPipe tag:self->_lastClientSocketTag withPayload:nil callback:^(NSError *error) {
|
[self->_peerChannel
|
||||||
FBPFTrace(@"open socket (%d), error = %@", (unsigned int)tag, error);
|
sendFrameOfType:FKPortForwardingFrameTypeOpenPipe
|
||||||
[newSocket readDataWithTimeout:-1 tag:0];
|
tag:self->_lastClientSocketTag
|
||||||
}];
|
withPayload:nil
|
||||||
|
callback:^(NSError* error) {
|
||||||
|
FBPFTrace(
|
||||||
|
@"open socket (%d), error = %@", (unsigned int)tag, error);
|
||||||
|
[newSocket readDataWithTimeout:-1 tag:0];
|
||||||
|
}];
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_peerChannel) {
|
if (_peerChannel) {
|
||||||
block();
|
block();
|
||||||
} else {
|
} else {
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), _socketQueue, block);
|
dispatch_after(
|
||||||
|
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)),
|
||||||
|
_socketQueue,
|
||||||
|
block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)_
|
- (void)socket:(GCDAsyncSocket*)sock didReadData:(NSData*)data withTag:(long)_ {
|
||||||
{
|
|
||||||
UInt32 tag = [[sock userData] unsignedIntValue];
|
UInt32 tag = [[sock userData] unsignedIntValue];
|
||||||
FBPFTrace(@"Incoming data on socket (%d) - %lu bytes", (unsigned int)tag, (unsigned long)data.length);
|
FBPFTrace(
|
||||||
[_peerChannel sendFrameOfType:FKPortForwardingFrameTypeWriteToPipe tag:tag withPayload:NSDataToGCDData(data) callback:^(NSError *error) {
|
@"Incoming data on socket (%d) - %lu bytes",
|
||||||
FBPFTrace(@"socket (%d) -> channel %lu bytes, error = %@", (unsigned int)tag, (unsigned long)data.length, error);
|
(unsigned int)tag,
|
||||||
[sock readDataWithTimeout:-1 tag:_];
|
(unsigned long)data.length);
|
||||||
}];
|
[_peerChannel sendFrameOfType:FKPortForwardingFrameTypeWriteToPipe
|
||||||
|
tag:tag
|
||||||
|
withPayload:NSDataToGCDData(data)
|
||||||
|
callback:^(NSError* error) {
|
||||||
|
FBPFTrace(
|
||||||
|
@"socket (%d) -> channel %lu bytes, error = %@",
|
||||||
|
(unsigned int)tag,
|
||||||
|
(unsigned long)data.length,
|
||||||
|
error);
|
||||||
|
[sock readDataWithTimeout:-1 tag:_];
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
|
- (void)socketDidDisconnect:(GCDAsyncSocket*)sock withError:(NSError*)err {
|
||||||
{
|
|
||||||
UInt32 tag = [sock.userData unsignedIntValue];
|
UInt32 tag = [sock.userData unsignedIntValue];
|
||||||
[_clientSockets removeObjectForKey:@(tag)];
|
[_clientSockets removeObjectForKey:@(tag)];
|
||||||
[_peerChannel sendFrameOfType:FKPortForwardingFrameTypeClosePipe tag:tag withPayload:nil callback:^(NSError *error) {
|
[_peerChannel
|
||||||
FBPFTrace(@"socket (%d) disconnected, err = %@, peer error = %@", (unsigned int)tag, err, error);
|
sendFrameOfType:FKPortForwardingFrameTypeClosePipe
|
||||||
}];
|
tag:tag
|
||||||
|
withPayload:nil
|
||||||
|
callback:^(NSError* error) {
|
||||||
|
FBPFTrace(
|
||||||
|
@"socket (%d) disconnected, err = %@, peer error = %@",
|
||||||
|
(unsigned int)tag,
|
||||||
|
err,
|
||||||
|
error);
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -16,6 +16,6 @@
|
|||||||
|
|
||||||
@interface FlipperClient (Testing)
|
@interface FlipperClient (Testing)
|
||||||
|
|
||||||
- (instancetype)initWithCppClient:(facebook::flipper::FlipperClient *)cppClient;
|
- (instancetype)initWithCppClient:(facebook::flipper::FlipperClient*)cppClient;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -12,30 +12,32 @@
|
|||||||
#import "FlipperStateUpdateListener.h"
|
#import "FlipperStateUpdateListener.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Represents a connection between the Sonar desktop och client side. Manages the lifecycle of attached
|
Represents a connection between the Sonar desktop och client side. Manages the
|
||||||
plugin instances.
|
lifecycle of attached plugin instances.
|
||||||
*/
|
*/
|
||||||
@interface FlipperClient : NSObject
|
@interface FlipperClient : NSObject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The shared singleton FlipperClient instance. It is an error to call this on non-debug builds to avoid leaking data.
|
The shared singleton FlipperClient instance. It is an error to call this on
|
||||||
|
non-debug builds to avoid leaking data.
|
||||||
*/
|
*/
|
||||||
+ (instancetype)sharedClient;
|
+ (instancetype)sharedClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Register a plugin with the client.
|
Register a plugin with the client.
|
||||||
*/
|
*/
|
||||||
- (void)addPlugin:(NSObject<FlipperPlugin> *)plugin;
|
- (void)addPlugin:(NSObject<FlipperPlugin>*)plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Unregister a plugin with the client.
|
Unregister a plugin with the client.
|
||||||
*/
|
*/
|
||||||
- (void)removePlugin:(NSObject<FlipperPlugin> *)plugin;
|
- (void)removePlugin:(NSObject<FlipperPlugin>*)plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Retrieve the plugin with a given identifier which was previously registered with this client.
|
Retrieve the plugin with a given identifier which was previously registered with
|
||||||
|
this client.
|
||||||
*/
|
*/
|
||||||
- (NSObject<FlipperPlugin> *)pluginWithIdentifier:(NSString *)identifier;
|
- (NSObject<FlipperPlugin>*)pluginWithIdentifier:(NSString*)identifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Establish a connection to the Sonar desktop.
|
Establish a connection to the Sonar desktop.
|
||||||
@@ -50,19 +52,20 @@ Stop the connection to the Sonar desktop.
|
|||||||
/**
|
/**
|
||||||
Get the log of state changes from the sonar client
|
Get the log of state changes from the sonar client
|
||||||
*/
|
*/
|
||||||
- (NSString *)getState;
|
- (NSString*)getState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the current summarized state of the sonar client
|
Get the current summarized state of the sonar client
|
||||||
*/
|
*/
|
||||||
- (NSArray<NSDictionary *> *)getStateElements;
|
- (NSArray<NSDictionary*>*)getStateElements;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Subscribe a ViewController to state update change notifications
|
Subscribe a ViewController to state update change notifications
|
||||||
*/
|
*/
|
||||||
- (void)subscribeForUpdates:(id<FlipperStateUpdateListener>)controller;
|
- (void)subscribeForUpdates:(id<FlipperStateUpdateListener>)controller;
|
||||||
|
|
||||||
// initializers are disabled. You must use `+[FlipperClient sharedClient]` instance.
|
// initializers are disabled. You must use `+[FlipperClient sharedClient]`
|
||||||
|
// instance.
|
||||||
- (instancetype)init NS_UNAVAILABLE;
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
+ (instancetype)new NS_UNAVAILABLE;
|
+ (instancetype)new NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,14 @@
|
|||||||
#if FB_SONARKIT_ENABLED
|
#if FB_SONARKIT_ENABLED
|
||||||
|
|
||||||
#import "FlipperClient.h"
|
#import "FlipperClient.h"
|
||||||
#import "FlipperCppWrapperPlugin.h"
|
|
||||||
#import <Flipper/FlipperClient.h>
|
#import <Flipper/FlipperClient.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
#include <folly/io/async/EventBase.h>
|
#include <folly/io/async/EventBase.h>
|
||||||
#include <folly/io/async/ScopedEventBaseThread.h>
|
#include <folly/io/async/ScopedEventBaseThread.h>
|
||||||
#import <UIKit/UIKit.h>
|
|
||||||
#include "SKStateUpdateCPPWrapper.h"
|
|
||||||
#import "FlipperClient+Testing.h"
|
#import "FlipperClient+Testing.h"
|
||||||
|
#import "FlipperCppWrapperPlugin.h"
|
||||||
#import "SKEnvironmentVariables.h"
|
#import "SKEnvironmentVariables.h"
|
||||||
|
#include "SKStateUpdateCPPWrapper.h"
|
||||||
|
|
||||||
#if !TARGET_OS_SIMULATOR
|
#if !TARGET_OS_SIMULATOR
|
||||||
#import <FKPortForwarding/FKPortForwardingServer.h>
|
#import <FKPortForwarding/FKPortForwardingServer.h>
|
||||||
@@ -24,23 +24,22 @@
|
|||||||
using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
|
using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
|
||||||
|
|
||||||
@implementation FlipperClient {
|
@implementation FlipperClient {
|
||||||
facebook::flipper::FlipperClient *_cppClient;
|
facebook::flipper::FlipperClient* _cppClient;
|
||||||
folly::ScopedEventBaseThread sonarThread;
|
folly::ScopedEventBaseThread sonarThread;
|
||||||
folly::ScopedEventBaseThread connectionThread;
|
folly::ScopedEventBaseThread connectionThread;
|
||||||
#if !TARGET_OS_SIMULATOR
|
#if !TARGET_OS_SIMULATOR
|
||||||
FKPortForwardingServer *_secureServer;
|
FKPortForwardingServer* _secureServer;
|
||||||
FKPortForwardingServer *_insecureServer;
|
FKPortForwardingServer* _insecureServer;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (instancetype)sharedClient
|
+ (instancetype)sharedClient {
|
||||||
{
|
static FlipperClient* sharedClient = nil;
|
||||||
static FlipperClient *sharedClient = nil;
|
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
try {
|
try {
|
||||||
sharedClient = [[self alloc] init];
|
sharedClient = [[self alloc] init];
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception& e) {
|
||||||
// fail.
|
// fail.
|
||||||
sharedClient = nil;
|
sharedClient = nil;
|
||||||
}
|
}
|
||||||
@@ -48,46 +47,51 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
|
|||||||
return sharedClient;
|
return sharedClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init {
|
||||||
{
|
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
UIDevice *device = [UIDevice currentDevice];
|
UIDevice* device = [UIDevice currentDevice];
|
||||||
NSString *deviceName = [device name];
|
NSString* deviceName = [device name];
|
||||||
NSBundle *bundle = [NSBundle mainBundle];
|
NSBundle* bundle = [NSBundle mainBundle];
|
||||||
NSString *appName = [bundle objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey];
|
NSString* appName =
|
||||||
NSString *appId = [bundle bundleIdentifier];
|
[bundle objectForInfoDictionaryKey:(NSString*)kCFBundleNameKey];
|
||||||
NSString *privateAppDirectory = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0];
|
NSString* appId = [bundle bundleIdentifier];
|
||||||
|
NSString* privateAppDirectory = NSSearchPathForDirectoriesInDomains(
|
||||||
|
NSApplicationSupportDirectory, NSUserDomainMask, YES)[0];
|
||||||
|
|
||||||
NSFileManager *manager = [NSFileManager defaultManager];
|
NSFileManager* manager = [NSFileManager defaultManager];
|
||||||
|
|
||||||
if ([manager fileExistsAtPath:privateAppDirectory isDirectory:NULL] == NO &&
|
if ([manager fileExistsAtPath:privateAppDirectory isDirectory:NULL] == NO &&
|
||||||
![manager createDirectoryAtPath:privateAppDirectory withIntermediateDirectories:YES attributes:nil error:nil]) {
|
![manager createDirectoryAtPath:privateAppDirectory
|
||||||
|
withIntermediateDirectories:YES
|
||||||
|
attributes:nil
|
||||||
|
error:nil]) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TARGET_OS_SIMULATOR
|
#if TARGET_OS_SIMULATOR
|
||||||
deviceName = [NSString stringWithFormat:@"%@ %@", [[UIDevice currentDevice] model], @"Simulator"];
|
deviceName = [NSString stringWithFormat:@"%@ %@",
|
||||||
|
[[UIDevice currentDevice] model],
|
||||||
|
@"Simulator"];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const std::string UNKNOWN = std::string("unknown");
|
static const std::string UNKNOWN = std::string("unknown");
|
||||||
try {
|
try {
|
||||||
facebook::flipper::FlipperClient::init({
|
facebook::flipper::FlipperClient::init(
|
||||||
{
|
{{
|
||||||
"localhost",
|
"localhost",
|
||||||
"iOS",
|
"iOS",
|
||||||
[deviceName UTF8String],
|
[deviceName UTF8String],
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
[appName UTF8String] ?: UNKNOWN,
|
[appName UTF8String] ?: UNKNOWN,
|
||||||
[appId UTF8String] ?: UNKNOWN,
|
[appId UTF8String] ?: UNKNOWN,
|
||||||
[privateAppDirectory UTF8String],
|
[privateAppDirectory UTF8String],
|
||||||
},
|
},
|
||||||
sonarThread.getEventBase(),
|
sonarThread.getEventBase(),
|
||||||
connectionThread.getEventBase(),
|
connectionThread.getEventBase(),
|
||||||
[SKEnvironmentVariables getInsecurePort],
|
[SKEnvironmentVariables getInsecurePort],
|
||||||
[SKEnvironmentVariables getSecurePort]
|
[SKEnvironmentVariables getSecurePort]});
|
||||||
});
|
|
||||||
_cppClient = facebook::flipper::FlipperClient::instance();
|
_cppClient = facebook::flipper::FlipperClient::instance();
|
||||||
} catch (const std::system_error &e) {
|
} catch (const std::system_error& e) {
|
||||||
// Probably ran out of disk space.
|
// Probably ran out of disk space.
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
@@ -95,32 +99,27 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)refreshPlugins
|
- (void)refreshPlugins {
|
||||||
{
|
|
||||||
_cppClient->refreshPlugins();
|
_cppClient->refreshPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addPlugin:(NSObject<FlipperPlugin> *)plugin
|
- (void)addPlugin:(NSObject<FlipperPlugin>*)plugin {
|
||||||
{
|
|
||||||
_cppClient->addPlugin(std::make_shared<WrapperPlugin>(plugin));
|
_cppClient->addPlugin(std::make_shared<WrapperPlugin>(plugin));
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)removePlugin:(NSObject<FlipperPlugin> *)plugin
|
- (void)removePlugin:(NSObject<FlipperPlugin>*)plugin {
|
||||||
{
|
|
||||||
_cppClient->removePlugin(std::make_shared<WrapperPlugin>(plugin));
|
_cppClient->removePlugin(std::make_shared<WrapperPlugin>(plugin));
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSObject<FlipperPlugin> *)pluginWithIdentifier:(NSString *)identifier
|
- (NSObject<FlipperPlugin>*)pluginWithIdentifier:(NSString*)identifier {
|
||||||
{
|
|
||||||
auto cppPlugin = _cppClient->getPlugin([identifier UTF8String]);
|
auto cppPlugin = _cppClient->getPlugin([identifier UTF8String]);
|
||||||
if (auto wrapper = dynamic_cast<WrapperPlugin *>(cppPlugin.get())) {
|
if (auto wrapper = dynamic_cast<WrapperPlugin*>(cppPlugin.get())) {
|
||||||
return wrapper->getObjCPlugin();
|
return wrapper->getObjCPlugin();
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)start
|
- (void)start {
|
||||||
{
|
|
||||||
#if !TARGET_OS_SIMULATOR
|
#if !TARGET_OS_SIMULATOR
|
||||||
_secureServer = [FKPortForwardingServer new];
|
_secureServer = [FKPortForwardingServer new];
|
||||||
[_secureServer forwardConnectionsFromPort:8088];
|
[_secureServer forwardConnectionsFromPort:8088];
|
||||||
@@ -132,9 +131,7 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
|
|||||||
_cppClient->start();
|
_cppClient->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)stop {
|
||||||
- (void)stop
|
|
||||||
{
|
|
||||||
_cppClient->stop();
|
_cppClient->stop();
|
||||||
#if !TARGET_OS_SIMULATOR
|
#if !TARGET_OS_SIMULATOR
|
||||||
[_secureServer close];
|
[_secureServer close];
|
||||||
@@ -144,16 +141,18 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)getState {
|
- (NSString*)getState {
|
||||||
return @(_cppClient->getState().c_str());
|
return @(_cppClient->getState().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *)getStateElements {
|
- (NSArray*)getStateElements {
|
||||||
NSMutableArray<NSDictionary<NSString *, NSString *>*> *const array = [NSMutableArray array];
|
NSMutableArray<NSDictionary<NSString*, NSString*>*>* const array =
|
||||||
|
[NSMutableArray array];
|
||||||
|
|
||||||
for (facebook::flipper::StateElement element: _cppClient->getStateElements()) {
|
for (facebook::flipper::StateElement element :
|
||||||
|
_cppClient->getStateElements()) {
|
||||||
facebook::flipper::State state = element.state_;
|
facebook::flipper::State state = element.state_;
|
||||||
NSString *stateString;
|
NSString* stateString;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case facebook::flipper::in_progress:
|
case facebook::flipper::in_progress:
|
||||||
stateString = @"⏳ ";
|
stateString = @"⏳ ";
|
||||||
@@ -172,9 +171,9 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
[array addObject:@{
|
[array addObject:@{
|
||||||
@"name": [NSString stringWithUTF8String:element.name_.c_str()],
|
@"name" : [NSString stringWithUTF8String:element.name_.c_str()],
|
||||||
@"state": stateString
|
@"state" : stateString
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
@@ -188,11 +187,11 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
|
|||||||
|
|
||||||
@implementation FlipperClient (Testing)
|
@implementation FlipperClient (Testing)
|
||||||
|
|
||||||
- (instancetype)initWithCppClient:(facebook::flipper::FlipperClient *)cppClient {
|
- (instancetype)initWithCppClient:(facebook::flipper::FlipperClient*)cppClient {
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
_cppClient = cppClient;
|
_cppClient = cppClient;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -7,19 +7,20 @@
|
|||||||
|
|
||||||
#ifdef FB_SONARKIT_ENABLED
|
#ifdef FB_SONARKIT_ENABLED
|
||||||
|
|
||||||
#include "FlipperStateUpdateListener.h"
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
#include "FlipperStateUpdateListener.h"
|
||||||
|
|
||||||
@interface StateTableDataSource : NSObject <UITableViewDataSource>
|
@interface StateTableDataSource : NSObject<UITableViewDataSource>
|
||||||
@property (strong, nonatomic) NSArray<NSDictionary *> *elements;
|
@property(strong, nonatomic) NSArray<NSDictionary*>* elements;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface FlipperDiagnosticsViewController : UIViewController<FlipperStateUpdateListener>
|
@interface FlipperDiagnosticsViewController
|
||||||
@property(strong, nonatomic) StateTableDataSource *tableDataSource;
|
: UIViewController<FlipperStateUpdateListener>
|
||||||
@property(strong, nonatomic) UILabel *stateLabel;
|
@property(strong, nonatomic) StateTableDataSource* tableDataSource;
|
||||||
@property(strong, nonatomic) UITableView *stateTable;
|
@property(strong, nonatomic) UILabel* stateLabel;
|
||||||
@property(strong, nonatomic) UIScrollView *scrollView;
|
@property(strong, nonatomic) UITableView* stateTable;
|
||||||
@property(strong, nonatomic) UILabel *logLabel;
|
@property(strong, nonatomic) UIScrollView* scrollView;
|
||||||
|
@property(strong, nonatomic) UILabel* logLabel;
|
||||||
|
|
||||||
- (void)onUpdate;
|
- (void)onUpdate;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -12,10 +12,11 @@
|
|||||||
|
|
||||||
#define STATE_VIEW_HEIGHT 300
|
#define STATE_VIEW_HEIGHT 300
|
||||||
|
|
||||||
static NSString *const kSKCellIdentifier = @"FlipperDiagnosticStateTableStableCellIdentifier";
|
static NSString* const kSKCellIdentifier =
|
||||||
|
@"FlipperDiagnosticStateTableStableCellIdentifier";
|
||||||
|
|
||||||
@implementation StateTableDataSource
|
@implementation StateTableDataSource
|
||||||
- (instancetype)initWithElements:(NSArray<NSDictionary *> *)elements {
|
- (instancetype)initWithElements:(NSArray<NSDictionary*>*)elements {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self) {
|
||||||
_elements = elements;
|
_elements = elements;
|
||||||
@@ -23,16 +24,21 @@ static NSString *const kSKCellIdentifier = @"FlipperDiagnosticStateTableStableCe
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
|
- (nonnull UITableViewCell*)tableView:(nonnull UITableView*)tableView
|
||||||
|
cellForRowAtIndexPath:(nonnull NSIndexPath*)indexPath {
|
||||||
NSInteger row = indexPath.row;
|
NSInteger row = indexPath.row;
|
||||||
|
|
||||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kSKCellIdentifier forIndexPath:indexPath];
|
UITableViewCell* cell =
|
||||||
|
[tableView dequeueReusableCellWithIdentifier:kSKCellIdentifier
|
||||||
|
forIndexPath:indexPath];
|
||||||
cell.textLabel.font = [UIFont fontWithName:@"Arial" size:10];
|
cell.textLabel.font = [UIFont fontWithName:@"Arial" size:10];
|
||||||
cell.textLabel.text = [self.elements[row][@"state"] stringByAppendingString:self.elements[row][@"name"]];
|
cell.textLabel.text = [self.elements[row][@"state"]
|
||||||
|
stringByAppendingString:self.elements[row][@"name"]];
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
- (NSInteger)tableView:(nonnull UITableView*)tableView
|
||||||
|
numberOfRowsInSection:(NSInteger)section {
|
||||||
return [self.elements count];
|
return [self.elements count];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,16 +49,30 @@ static NSString *const kSKCellIdentifier = @"FlipperDiagnosticStateTableStableCe
|
|||||||
- (void)viewDidLoad {
|
- (void)viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, STATE_VIEW_HEIGHT, self.view.frame.size.width, self.view.frame.size.height - 100 - STATE_VIEW_HEIGHT)];
|
self.scrollView = [[UIScrollView alloc]
|
||||||
self.logLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.scrollView.frame.size.height)];
|
initWithFrame:CGRectMake(
|
||||||
|
0,
|
||||||
|
STATE_VIEW_HEIGHT,
|
||||||
|
self.view.frame.size.width,
|
||||||
|
self.view.frame.size.height - 100 - STATE_VIEW_HEIGHT)];
|
||||||
|
self.logLabel =
|
||||||
|
[[UILabel alloc] initWithFrame:CGRectMake(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
self.view.frame.size.width,
|
||||||
|
self.scrollView.frame.size.height)];
|
||||||
self.logLabel.numberOfLines = 0;
|
self.logLabel.numberOfLines = 0;
|
||||||
self.logLabel.font = [UIFont fontWithName:@"Arial" size:10];
|
self.logLabel.font = [UIFont fontWithName:@"Arial" size:10];
|
||||||
[self.scrollView addSubview:self.logLabel];
|
[self.scrollView addSubview:self.logLabel];
|
||||||
|
|
||||||
self.stateTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, STATE_VIEW_HEIGHT)];
|
self.stateTable = [[UITableView alloc]
|
||||||
[self.stateTable registerClass:[UITableViewCell class] forCellReuseIdentifier:kSKCellIdentifier];
|
initWithFrame:CGRectMake(
|
||||||
|
0, 0, self.view.bounds.size.width, STATE_VIEW_HEIGHT)];
|
||||||
|
[self.stateTable registerClass:[UITableViewCell class]
|
||||||
|
forCellReuseIdentifier:kSKCellIdentifier];
|
||||||
self.stateTable.rowHeight = 14;
|
self.stateTable.rowHeight = 14;
|
||||||
self.tableDataSource = [[StateTableDataSource alloc] initWithElements:[[FlipperClient sharedClient] getStateElements]];
|
self.tableDataSource = [[StateTableDataSource alloc]
|
||||||
|
initWithElements:[[FlipperClient sharedClient] getStateElements]];
|
||||||
self.stateTable.dataSource = self.tableDataSource;
|
self.stateTable.dataSource = self.tableDataSource;
|
||||||
|
|
||||||
[self updateLogView];
|
[self updateLogView];
|
||||||
@@ -63,7 +83,7 @@ static NSString *const kSKCellIdentifier = @"FlipperDiagnosticStateTableStableCe
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)onUpdate {
|
- (void)onUpdate {
|
||||||
FlipperDiagnosticsViewController __weak *weakSelf = self;
|
FlipperDiagnosticsViewController __weak* weakSelf = self;
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[weakSelf updateStateTable];
|
[weakSelf updateStateTable];
|
||||||
[weakSelf updateLogView];
|
[weakSelf updateLogView];
|
||||||
@@ -71,18 +91,21 @@ static NSString *const kSKCellIdentifier = @"FlipperDiagnosticStateTableStableCe
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateStateTable {
|
- (void)updateStateTable {
|
||||||
self.tableDataSource.elements = [[FlipperClient sharedClient] getStateElements];
|
self.tableDataSource.elements =
|
||||||
|
[[FlipperClient sharedClient] getStateElements];
|
||||||
[self.stateTable reloadData];
|
[self.stateTable reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateLogView {
|
- (void)updateLogView {
|
||||||
NSString *state = [[FlipperClient sharedClient] getState];
|
NSString* state = [[FlipperClient sharedClient] getState];
|
||||||
self.logLabel.text = state;
|
self.logLabel.text = state;
|
||||||
[self.logLabel sizeToFit];
|
[self.logLabel sizeToFit];
|
||||||
self.scrollView.contentSize = self.logLabel.frame.size;
|
self.scrollView.contentSize = self.logLabel.frame.size;
|
||||||
|
|
||||||
// Scroll to bottom
|
// Scroll to bottom
|
||||||
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height);
|
CGPoint bottomOffset = CGPointMake(
|
||||||
|
0,
|
||||||
|
self.scrollView.contentSize.height - self.scrollView.bounds.size.height);
|
||||||
[self.scrollView setContentOffset:bottomOffset animated:YES];
|
[self.scrollView setContentOffset:bottomOffset animated:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "SKMacros.h"
|
|
||||||
#import "FlipperResponder.h"
|
#import "FlipperResponder.h"
|
||||||
|
#import "SKMacros.h"
|
||||||
|
|
||||||
SK_EXTERN_C_BEGIN
|
SK_EXTERN_C_BEGIN
|
||||||
void FlipperPerformBlockOnMainThread(void(^block)(), id<FlipperResponder> responder);
|
void FlipperPerformBlockOnMainThread(
|
||||||
|
void (^block)(),
|
||||||
|
id<FlipperResponder> responder);
|
||||||
SK_EXTERN_C_END
|
SK_EXTERN_C_END
|
||||||
|
|
||||||
@protocol FlipperConnection;
|
@protocol FlipperConnection;
|
||||||
@@ -19,26 +20,28 @@ SK_EXTERN_C_END
|
|||||||
@protocol FlipperPlugin
|
@protocol FlipperPlugin
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The plugin's identifier. This should map to a javascript plugin with the same identifier to ensure
|
The plugin's identifier. This should map to a javascript plugin with the same
|
||||||
messages are sent correctly.
|
identifier to ensure messages are sent correctly.
|
||||||
*/
|
*/
|
||||||
- (NSString *)identifier;
|
- (NSString*)identifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Called when a connection has been established between this plugin and the corresponding plugin on
|
Called when a connection has been established between this plugin and the
|
||||||
the Sonar desktop app. The provided connection can be used to register method receivers as well
|
corresponding plugin on the Sonar desktop app. The provided connection can be
|
||||||
as send messages back to the desktop app.
|
used to register method receivers as well as send messages back to the desktop
|
||||||
|
app.
|
||||||
*/
|
*/
|
||||||
- (void)didConnect:(id<FlipperConnection>)connection;
|
- (void)didConnect:(id<FlipperConnection>)connection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Called when a plugin has been disconnected and the SonarConnection provided in didConnect is no
|
Called when a plugin has been disconnected and the SonarConnection provided in
|
||||||
longer valid to use.
|
didConnect is no longer valid to use.
|
||||||
*/
|
*/
|
||||||
- (void)didDisconnect;
|
- (void)didDisconnect;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns true if the plugin is meant to be run in background too, otherwise it returns false.
|
Returns true if the plugin is meant to be run in background too, otherwise it
|
||||||
|
returns false.
|
||||||
*/
|
*/
|
||||||
@optional
|
@optional
|
||||||
- (BOOL)runInBackground;
|
- (BOOL)runInBackground;
|
||||||
|
|||||||
@@ -8,18 +8,19 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Acts as a hook for providing return values to remote called from Sonar desktop plugins.
|
Acts as a hook for providing return values to remote called from Sonar desktop
|
||||||
|
plugins.
|
||||||
*/
|
*/
|
||||||
@protocol FlipperResponder
|
@protocol FlipperResponder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Respond with a successful return value.
|
Respond with a successful return value.
|
||||||
*/
|
*/
|
||||||
- (void)success:(NSDictionary *)response;
|
- (void)success:(NSDictionary*)response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Respond with an error.
|
Respond with an error.
|
||||||
*/
|
*/
|
||||||
- (void)error:(NSDictionary *)response;
|
- (void)error:(NSDictionary*)response;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -9,25 +9,34 @@
|
|||||||
#import "FlipperPlugin.h"
|
#import "FlipperPlugin.h"
|
||||||
#import "FlipperResponder.h"
|
#import "FlipperResponder.h"
|
||||||
|
|
||||||
void FlipperPerformBlockOnMainThread(void(^block)(), id<FlipperResponder> responder)
|
void FlipperPerformBlockOnMainThread(
|
||||||
{
|
void (^block)(),
|
||||||
|
id<FlipperResponder> responder) {
|
||||||
if ([NSThread isMainThread]) {
|
if ([NSThread isMainThread]) {
|
||||||
@try {
|
@try {
|
||||||
block();
|
block();
|
||||||
} @catch (NSException *e) {
|
} @catch (NSException* e) {
|
||||||
[responder error:@{@"name": e.name, @"message": e.reason}];
|
[responder error:@{@"name" : e.name, @"message" : e.reason}];
|
||||||
} @catch (...) {
|
} @catch (...) {
|
||||||
[responder error:@{@"name": @"Unknown", @"message": @"Unknown error caught when processing operation on main thread"}];
|
[responder error:@{
|
||||||
}
|
@"name" : @"Unknown",
|
||||||
|
@"message" :
|
||||||
|
@"Unknown error caught when processing operation on main thread"
|
||||||
|
}];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
@try {
|
@try {
|
||||||
block();
|
block();
|
||||||
} @catch (NSException *e) {
|
} @catch (NSException* e) {
|
||||||
[responder error:@{@"name": e.name, @"message": e.reason}];
|
[responder error:@{@"name" : e.name, @"message" : e.reason}];
|
||||||
} @catch (...) {
|
} @catch (...) {
|
||||||
[responder error:@{@"name": @"Unknown", @"message": @"Unknown error caught when processing operation on main thread"}];
|
[responder error:@{
|
||||||
}
|
@"name" : @"Unknown",
|
||||||
});
|
@"message" :
|
||||||
|
@"Unknown error caught when processing operation on main thread"
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,12 @@
|
|||||||
#ifdef FB_SONARKIT_ENABLED
|
#ifdef FB_SONARKIT_ENABLED
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class exists to retreive configuration values stored in environment variables.
|
* This class exists to retreive configuration values stored in environment
|
||||||
|
* variables.
|
||||||
*/
|
*/
|
||||||
@interface SKEnvironmentVariables : NSObject
|
@interface SKEnvironmentVariables : NSObject
|
||||||
+ (int)getInsecurePort;
|
+ (int)getInsecurePort;
|
||||||
+ (int)getSecurePort;
|
+ (int)getSecurePort;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,22 +15,28 @@ static int const DEFAULT_SECURE_PORT = 8088;
|
|||||||
@implementation SKEnvironmentVariables
|
@implementation SKEnvironmentVariables
|
||||||
|
|
||||||
+ (int)getInsecurePort {
|
+ (int)getInsecurePort {
|
||||||
NSString *envVar = [self getFlipperPortsVariable];
|
NSString* envVar = [self getFlipperPortsVariable];
|
||||||
return [self extractIntFromPropValue:envVar atIndex:0 withDefault:DEFAULT_INSECURE_PORT];
|
return [self extractIntFromPropValue:envVar
|
||||||
|
atIndex:0
|
||||||
|
withDefault:DEFAULT_INSECURE_PORT];
|
||||||
}
|
}
|
||||||
+ (int)getSecurePort {
|
+ (int)getSecurePort {
|
||||||
NSString *envVar = [self getFlipperPortsVariable];
|
NSString* envVar = [self getFlipperPortsVariable];
|
||||||
return [self extractIntFromPropValue:envVar atIndex:1 withDefault:DEFAULT_SECURE_PORT];
|
return [self extractIntFromPropValue:envVar
|
||||||
|
atIndex:1
|
||||||
|
withDefault:DEFAULT_SECURE_PORT];
|
||||||
}
|
}
|
||||||
+ (int)extractIntFromPropValue:(NSString *)propValue atIndex:(int)index withDefault:(int)fallback {
|
+ (int)extractIntFromPropValue:(NSString*)propValue
|
||||||
NSArray<NSString *> *components = [propValue componentsSeparatedByString:@","];
|
atIndex:(int)index
|
||||||
NSString *component = [components objectAtIndex:index];
|
withDefault:(int)fallback {
|
||||||
int envInt = [component intValue];
|
NSArray<NSString*>* components = [propValue componentsSeparatedByString:@","];
|
||||||
return envInt > 0 ? envInt : fallback;
|
NSString* component = [components objectAtIndex:index];
|
||||||
|
int envInt = [component intValue];
|
||||||
|
return envInt > 0 ? envInt : fallback;
|
||||||
}
|
}
|
||||||
+ (NSString *)getFlipperPortsVariable {
|
+ (NSString*)getFlipperPortsVariable {
|
||||||
NSString *value = NSProcessInfo.processInfo.environment[@"FLIPPER_PORTS"];
|
NSString* value = NSProcessInfo.processInfo.environment[@"FLIPPER_PORTS"];
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -13,13 +13,15 @@
|
|||||||
/*
|
/*
|
||||||
* This class exists to bridge the gap between Objective C and C++.
|
* This class exists to bridge the gap between Objective C and C++.
|
||||||
* A SKStateUpdateCPPWrapper instance allows for wrapping an Objective-C object
|
* A SKStateUpdateCPPWrapper instance allows for wrapping an Objective-C object
|
||||||
* and passing it to the pure C++ SonarClient, so it can be triggered when updates occur.
|
* and passing it to the pure C++ SonarClient, so it can be triggered when
|
||||||
|
* updates occur.
|
||||||
*/
|
*/
|
||||||
class SKStateUpdateCPPWrapper : public FlipperStateUpdateListener {
|
class SKStateUpdateCPPWrapper : public FlipperStateUpdateListener {
|
||||||
public:
|
public:
|
||||||
SKStateUpdateCPPWrapper(id<FlipperStateUpdateListener> delegate_);
|
SKStateUpdateCPPWrapper(id<FlipperStateUpdateListener> delegate_);
|
||||||
void onUpdate();
|
void onUpdate();
|
||||||
private:
|
|
||||||
|
private:
|
||||||
__weak id<FlipperStateUpdateListener> delegate_;
|
__weak id<FlipperStateUpdateListener> delegate_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
#include "SKStateUpdateCPPWrapper.h"
|
#include "SKStateUpdateCPPWrapper.h"
|
||||||
|
|
||||||
SKStateUpdateCPPWrapper::SKStateUpdateCPPWrapper(id<FlipperStateUpdateListener> controller) {
|
SKStateUpdateCPPWrapper::SKStateUpdateCPPWrapper(
|
||||||
|
id<FlipperStateUpdateListener> controller) {
|
||||||
delegate_ = controller;
|
delegate_ = controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user