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:
Pritesh Nandgaonkar
2020-02-17 10:46:43 -08:00
committed by Facebook Github Bot
parent 127eec5fa1
commit ca513cf370
21 changed files with 510 additions and 360 deletions

View File

@@ -13,6 +13,7 @@ FlipperCppBridgingConnection is a simple ObjC wrapper around SonarConnection
that forwards messages to the underlying C++ connection. This class allows
pure Objective-C plugins to send messages to the underlying connection.
*/
@interface FlipperCppBridgingConnection : NSObject <FlipperConnection>
- (instancetype)initWithCppConnection:(std::shared_ptr<facebook::flipper::FlipperConnection>)conn;
@interface FlipperCppBridgingConnection : NSObject<FlipperConnection>
- (instancetype)initWithCppConnection:
(std::shared_ptr<facebook::flipper::FlipperConnection>)conn;
@end

View File

@@ -13,6 +13,7 @@ SonarCppBridgingResponder is a simple ObjC wrapper around FlipperResponder
that forwards messages to the underlying C++ responder. This class allows
pure Objective-C plugins to send messages to the underlying responder.
*/
@interface FlipperCppBridgingResponder : NSObject <FlipperResponder>
- (instancetype)initWithCppResponder:(std::shared_ptr<facebook::flipper::FlipperResponder>)responder;
@interface FlipperCppBridgingResponder : NSObject<FlipperResponder>
- (instancetype)initWithCppResponder:
(std::shared_ptr<facebook::flipper::FlipperResponder>)responder;
@end

View File

@@ -13,8 +13,8 @@
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) {
return nil;
}
@@ -28,8 +28,14 @@
#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

View File

@@ -16,7 +16,7 @@
namespace facebook {
namespace flipper {
using ObjCPlugin = NSObject<FlipperPlugin> *;
using ObjCPlugin = NSObject<FlipperPlugin>*;
/**
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.
*/
class FlipperCppWrapperPlugin final : public facebook::flipper::FlipperPlugin {
public:
public:
// Under ARC copying objCPlugin *does* increment its retain count
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
{
FlipperCppBridgingConnection *const bridgingConn = [[FlipperCppBridgingConnection alloc] initWithCppConnection:conn];
void didConnect(
std::shared_ptr<facebook::flipper::FlipperConnection> conn) override {
FlipperCppBridgingConnection* const bridgingConn =
[[FlipperCppBridgingConnection alloc] initWithCppConnection:conn];
[_objCPlugin didConnect:bridgingConn];
}
void didDisconnect() override { [_objCPlugin didDisconnect]; }
void didDisconnect() override {
[_objCPlugin didDisconnect];
}
bool runInBackground() override {
if ([_objCPlugin respondsToSelector:@selector(runInBackground)]) {
@@ -45,9 +50,11 @@ public:
return false;
}
ObjCPlugin getObjCPlugin() { return _objCPlugin; }
ObjCPlugin getObjCPlugin() {
return _objCPlugin;
}
private:
private:
ObjCPlugin _objCPlugin;
};

View File

@@ -15,6 +15,7 @@ namespace facebook {
namespace cxxutils {
folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf = false);
id convertFollyDynamicToId(const folly::dynamic &dyn);
id convertFollyDynamicToId(const folly::dynamic& dyn);
} }
} // namespace cxxutils
} // namespace facebook

View File

@@ -16,8 +16,7 @@ namespace cxxutils {
* 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
// dynamic in a derived class of NSDictionary. We can do that if profiling
// implies it will help.
@@ -32,10 +31,13 @@ id convertFollyDynamicToId(const folly::dynamic &dyn)
case folly::dynamic::DOUBLE:
return @(dyn.getDouble());
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: {
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dyn.size()];
for (auto &elem : dyn) {
NSMutableArray* array =
[[NSMutableArray alloc] initWithCapacity:dyn.size()];
for (auto& elem : dyn) {
id obj = convertFollyDynamicToId(elem);
if (obj) {
[array addObject:obj];
@@ -44,8 +46,9 @@ id convertFollyDynamicToId(const folly::dynamic &dyn)
return array;
}
case folly::dynamic::OBJECT: {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:dyn.size()];
for (auto &elem : dyn.items()) {
NSMutableDictionary* dict =
[[NSMutableDictionary alloc] initWithCapacity:dyn.size()];
for (auto& elem : dyn.items()) {
id obj = convertFollyDynamicToId(elem.second);
if (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) {
return nullptr;
} else if ([json isKindOfClass:[NSNumber class]]) {
const char *objCType = [json objCType];
const char* objCType = [json objCType];
switch (objCType[0]) {
// This is a c++ bool or C99 _Bool. On some platforms, BOOL is a bool.
case _C_BOOL:
@@ -109,8 +111,8 @@ folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf)
// fall through
}
} else if ([json isKindOfClass:[NSString class]]) {
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
return std::string(reinterpret_cast<const char *>(data.bytes), data.length);
NSData* data = [json dataUsingEncoding:NSUTF8StringEncoding];
return std::string(reinterpret_cast<const char*>(data.bytes), data.length);
} else if ([json isKindOfClass:[NSArray class]]) {
folly::dynamic array = folly::dynamic::array;
for (id element in json) {
@@ -120,8 +122,11 @@ folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf)
} else if ([json isKindOfClass:[NSDictionary class]]) {
__block folly::dynamic object = folly::dynamic::object();
[json enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, __unused BOOL *stop) {
object.insert(convertIdToFollyDynamic(key, nullifyNanAndInf), convertIdToFollyDynamic(value, nullifyNanAndInf));
[json enumerateKeysAndObjectsUsingBlock:^(
NSString* key, NSString* value, __unused BOOL* stop) {
object.insert(
convertIdToFollyDynamic(key, nullifyNanAndInf),
convertIdToFollyDynamic(value, nullifyNanAndInf));
}];
return object;

View File

@@ -15,22 +15,23 @@
static const NSTimeInterval ReconnectDelay = 1.0;
@interface FKPortForwardingClient () <GCDAsyncSocketDelegate, PTChannelDelegate>
{
@interface FKPortForwardingClient ()<
GCDAsyncSocketDelegate,
PTChannelDelegate> {
NSUInteger _destPort;
NSUInteger _channelPort;
NSNumber *_connectingToDeviceID;
NSNumber *_connectedDeviceID;
NSDictionary *_connectedDeviceProperties;
NSNumber* _connectingToDeviceID;
NSNumber* _connectedDeviceID;
NSDictionary* _connectedDeviceProperties;
BOOL _notConnectedQueueSuspended;
PTChannel *_connectedChannel;
PTChannel* _connectedChannel;
dispatch_queue_t _notConnectedQueue;
dispatch_queue_t _clientSocketsQueue;
NSMutableDictionary *_clientSockets;
NSMutableDictionary* _clientSockets;
}
@property (atomic, readonly) NSNumber *connectedDeviceID;
@property (atomic, assign) PTChannel *connectedChannel;
@property(atomic, readonly) NSNumber* connectedDeviceID;
@property(atomic, assign) PTChannel* connectedChannel;
@end
@@ -38,42 +39,40 @@ static const NSTimeInterval ReconnectDelay = 1.0;
@synthesize connectedDeviceID = _connectedDeviceID;
- (instancetype)init
{
- (instancetype)init {
if (self = [super init]) {
_notConnectedQueue = dispatch_queue_create("FKPortForwarding.notConnectedQueue", DISPATCH_QUEUE_SERIAL);
_clientSocketsQueue = dispatch_queue_create("FKPortForwarding.clients", DISPATCH_QUEUE_SERIAL);
_notConnectedQueue = dispatch_queue_create(
"FKPortForwarding.notConnectedQueue", DISPATCH_QUEUE_SERIAL);
_clientSocketsQueue = dispatch_queue_create(
"FKPortForwarding.clients", DISPATCH_QUEUE_SERIAL);
_clientSockets = [NSMutableDictionary dictionary];
}
return self;
}
- (void)forwardConnectionsToPort:(NSUInteger)port
{
- (void)forwardConnectionsToPort:(NSUInteger)port {
_destPort = port;
}
- (void)connectToMultiplexingChannelOnPort:(NSUInteger)port
{
- (void)connectToMultiplexingChannelOnPort:(NSUInteger)port {
_channelPort = port;
[self startListeningForDevices];
[self enqueueConnectToLocalIPv4Port];
}
- (void)close
{
- (void)close {
[self.connectedChannel close];
}
- (PTChannel *)connectedChannel {
- (PTChannel*)connectedChannel {
return _connectedChannel;
}
- (void)setConnectedChannel:(PTChannel *)connectedChannel {
- (void)setConnectedChannel:(PTChannel*)connectedChannel {
_connectedChannel = connectedChannel;
if (!_connectedChannel) {
for (GCDAsyncSocket *sock in [_clientSockets objectEnumerator]) {
for (GCDAsyncSocket* sock in [_clientSockets objectEnumerator]) {
[sock setDelegate:nil];
[sock disconnect];
}
@@ -94,40 +93,52 @@ static const NSTimeInterval ReconnectDelay = 1.0;
}
}
#pragma mark - PTChannelDelegate
- (void)ioFrameChannel:(PTChannel *)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(PTData *)payload {
//NSLog(@"received %@, %u, %u, %@", channel, type, tag, payload);
- (void)ioFrameChannel:(PTChannel*)channel
didReceiveFrameOfType:(uint32_t)type
tag:(uint32_t)tag
payload:(PTData*)payload {
// NSLog(@"received %@, %u, %u, %@", channel, type, tag, payload);
if (type == FKPortForwardingFrameTypeOpenPipe) {
GCDAsyncSocket *sock = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_clientSocketsQueue];
GCDAsyncSocket* sock =
[[GCDAsyncSocket alloc] initWithDelegate:self
delegateQueue:_clientSocketsQueue];
sock.userData = @(tag);
_clientSockets[@(tag)] = sock;
NSError *connectError;
if (![sock connectToHost:@"localhost" onPort:_destPort error:&connectError]) {
FBPFLog(@"Failed to connect to local %lu - %@", (unsigned long)_destPort, connectError);
NSError* connectError;
if (![sock connectToHost:@"localhost"
onPort:_destPort
error:&connectError]) {
FBPFLog(
@"Failed to connect to local %lu - %@",
(unsigned long)_destPort,
connectError);
}
FBPFTrace(@"open socket (%d)", tag);
}
if (type == FKPortForwardingFrameTypeWriteToPipe) {
GCDAsyncSocket *sock = _clientSockets[@(tag)];
[sock writeData:[NSData dataWithBytes:payload.data length:payload.length] withTimeout:-1 tag:0];
GCDAsyncSocket* sock = _clientSockets[@(tag)];
[sock writeData:[NSData dataWithBytes:payload.data length:payload.length]
withTimeout:-1
tag:0];
FBPFTrace(@"channel -> socket (%d) %zu bytes", tag, payload.length);
}
if (type == FKPortForwardingFrameTypeClosePipe) {
GCDAsyncSocket *sock = _clientSockets[@(tag)];
GCDAsyncSocket* sock = _clientSockets[@(tag)];
[sock disconnectAfterWriting];
FBPFTrace(@"close socket (%d)", tag);
}
}
- (void)ioFrameChannel:(PTChannel *)channel didEndWithError:(NSError *)error {
if (_connectedDeviceID && [_connectedDeviceID isEqualToNumber:channel.userInfo]) {
- (void)ioFrameChannel:(PTChannel*)channel didEndWithError:(NSError*)error {
if (_connectedDeviceID &&
[_connectedDeviceID isEqualToNumber:channel.userInfo]) {
[self didDisconnectFromDevice:_connectedDeviceID];
}
@@ -137,45 +148,57 @@ static const NSTimeInterval ReconnectDelay = 1.0;
}
}
#pragma mark - GCDAsyncSocketDelegate
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
FBPFTrace(@"socket (%ld) connected to %@", (long)[sock.userData integerValue], host);
- (void)socket:(GCDAsyncSocket*)sock
didConnectToHost:(NSString*)host
port:(uint16_t)port {
FBPFTrace(
@"socket (%ld) connected to %@",
(long)[sock.userData integerValue],
host);
[sock readDataWithTimeout:-1 tag:0];
}
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
- (void)socketDidDisconnect:(GCDAsyncSocket*)sock withError:(NSError*)err {
UInt32 tag = [sock.userData unsignedIntValue];
[_clientSockets removeObjectForKey:@(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];
[_connectedChannel sendFrameOfType:FKPortForwardingFrameTypeWriteToPipe tag:tag withPayload:NSDataToGCDData(data) callback:^(NSError *error) {
FBPFTrace(@"channel -> socket (%d), %lu bytes", (unsigned int)tag, (unsigned long)data.length);
[_connectedChannel sendFrameOfType:FKPortForwardingFrameTypeWriteToPipe
tag:tag
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
- (void)startListeningForDevices {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
__weak typeof(self) weakSelf = self;
[nc addObserverForName:PTUSBDeviceDidAttachNotification object:PTUSBHub.sharedHub queue:nil usingBlock:^(NSNotification *note) {
NSNumber *deviceID = [note.userInfo objectForKey:@"DeviceID"];
//NSLog(@"PTUSBDeviceDidAttachNotification: %@", note.userInfo);
[nc addObserverForName:PTUSBDeviceDidAttachNotification
object:PTUSBHub.sharedHub
queue:nil
usingBlock:^(NSNotification* note) {
NSNumber* deviceID = [note.userInfo objectForKey:@"DeviceID"];
// NSLog(@"PTUSBDeviceDidAttachNotification: %@",
// note.userInfo);
FBPFTrace(@"PTUSBDeviceDidAttachNotification: %@", deviceID);
typeof(self) strongSelf = weakSelf;
@@ -188,18 +211,22 @@ static const NSTimeInterval ReconnectDelay = 1.0;
});
}];
[nc addObserverForName:PTUSBDeviceDidDetachNotification object:PTUSBHub.sharedHub queue:nil usingBlock:^(NSNotification *note) {
NSNumber *deviceID = [note.userInfo objectForKey:@"DeviceID"];
//NSLog(@"PTUSBDeviceDidDetachNotification: %@", note.userInfo);
[nc addObserverForName:PTUSBDeviceDidDetachNotification
object:PTUSBHub.sharedHub
queue:nil
usingBlock:^(NSNotification* note) {
NSNumber* deviceID = [note.userInfo objectForKey:@"DeviceID"];
// NSLog(@"PTUSBDeviceDidDetachNotification: %@",
// note.userInfo);
FBPFTrace(@"PTUSBDeviceDidDetachNotification: %@", deviceID);
[weakSelf didDetachFromDevice:deviceID];
}];
}
- (void)didAttachToDevice:(NSNumber *)deviceID note:(NSNotification *)note
{
if (!_connectingToDeviceID || ![deviceID isEqualToNumber:_connectingToDeviceID]) {
- (void)didAttachToDevice:(NSNumber*)deviceID note:(NSNotification*)note {
if (!_connectingToDeviceID ||
![deviceID isEqualToNumber:_connectingToDeviceID]) {
[self disconnectFromCurrentChannel];
_connectingToDeviceID = deviceID;
_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]) {
_connectedDeviceProperties = 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);
if ([_connectedDeviceID isEqualToNumber:deviceID]) {
[self willChangeValueForKey:@"connectedDeviceID"];
@@ -228,7 +253,6 @@ static const NSTimeInterval ReconnectDelay = 1.0;
}
}
- (void)disconnectFromCurrentChannel {
if (_connectedDeviceID && _connectedChannel) {
[_connectedChannel close];
@@ -244,16 +268,23 @@ static const NSTimeInterval ReconnectDelay = 1.0;
});
}
- (void)connectToLocalIPv4Port {
PTChannel *channel = [PTChannel channelWithDelegate:self];
channel.userInfo = [NSString stringWithFormat:@"127.0.0.1:%lu", (unsigned long)_channelPort];
[channel connectToPort:_channelPort IPv4Address:INADDR_LOOPBACK callback:^(NSError *error, PTAddress *address) {
PTChannel* channel = [PTChannel channelWithDelegate:self];
channel.userInfo =
[NSString stringWithFormat:@"127.0.0.1:%lu", (unsigned long)_channelPort];
[channel
connectToPort:_channelPort
IPv4Address:INADDR_LOOPBACK
callback:^(NSError* error, PTAddress* address) {
if (error) {
if (error.domain == NSPOSIXErrorDomain && (error.code == ECONNREFUSED || error.code == ETIMEDOUT)) {
if (error.domain == NSPOSIXErrorDomain &&
(error.code == ECONNREFUSED || error.code == ETIMEDOUT)) {
// this is an expected state
} else {
FBPFTrace(@"Failed to connect to 127.0.0.1:%lu: %@", (unsigned long)_channelPort, error);
FBPFTrace(
@"Failed to connect to 127.0.0.1:%lu: %@",
(unsigned long)_channelPort,
error);
}
} else {
[self disconnectFromCurrentChannel];
@@ -261,7 +292,9 @@ static const NSTimeInterval ReconnectDelay = 1.0;
channel.userInfo = address;
FBPFLog(@"Connected to %@", address);
}
[self performSelector:@selector(enqueueConnectToLocalIPv4Port) withObject:nil afterDelay:ReconnectDelay];
[self performSelector:@selector(enqueueConnectToLocalIPv4Port)
withObject:nil
afterDelay:ReconnectDelay];
}];
}
@@ -273,30 +306,35 @@ static const NSTimeInterval ReconnectDelay = 1.0;
});
}
- (void)connectToUSBDevice {
PTChannel *channel = [PTChannel channelWithDelegate:self];
PTChannel* channel = [PTChannel channelWithDelegate:self];
channel.userInfo = _connectingToDeviceID;
channel.delegate = self;
[channel connectToPort:(int)_channelPort overUSBHub:PTUSBHub.sharedHub deviceID:_connectingToDeviceID callback:^(NSError *error) {
[channel connectToPort:(int)_channelPort
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) {
FBPFTrace(@"Failed to connect to device #%@: %@", channel.userInfo, error);
if (channel.userInfo == _connectingToDeviceID) {
[self performSelector:@selector(enqueueConnectToUSBDevice) withObject:nil afterDelay:ReconnectDelay];
[self performSelector:@selector(enqueueConnectToUSBDevice)
withObject:nil
afterDelay:ReconnectDelay];
}
} else {
_connectedDeviceID = _connectingToDeviceID;
self.connectedChannel = channel;
FBPFLog(@"Connected to device #%@\n%@", _connectingToDeviceID, _connectedDeviceProperties);
FBPFLog(
@"Connected to device #%@\n%@",
_connectingToDeviceID,
_connectedDeviceProperties);
}
}
@end

View File

@@ -16,8 +16,8 @@ enum {
FKPortForwardingFrameTypeClosePipe = 203,
};
static dispatch_data_t NSDataToGCDData(NSData *data) {
__block NSData *retainedData = data;
static dispatch_data_t NSDataToGCDData(NSData* data) {
__block NSData* retainedData = data;
return dispatch_data_create(data.bytes, data.length, nil, ^{
retainedData = nil;
});

View File

@@ -14,26 +14,27 @@
#import "FKPortForwardingCommon.h"
@interface FKPortForwardingServer () <PTChannelDelegate, GCDAsyncSocketDelegate>
{
__weak PTChannel *_serverChannel;
__weak PTChannel *_peerChannel;
@interface FKPortForwardingServer ()<
PTChannelDelegate,
GCDAsyncSocketDelegate> {
__weak PTChannel* _serverChannel;
__weak PTChannel* _peerChannel;
GCDAsyncSocket *_serverSocket;
NSMutableDictionary *_clientSockets;
GCDAsyncSocket* _serverSocket;
NSMutableDictionary* _clientSockets;
UInt32 _lastClientSocketTag;
dispatch_queue_t _socketQueue;
PTProtocol *_protocol;
PTProtocol* _protocol;
}
@end
@implementation FKPortForwardingServer
- (instancetype)init
{
- (instancetype)init {
if (self = [super init]) {
_socketQueue = dispatch_queue_create("FKPortForwardingServer", DISPATCH_QUEUE_SERIAL);
_socketQueue =
dispatch_queue_create("FKPortForwardingServer", DISPATCH_QUEUE_SERIAL);
_lastClientSocketTag = 0;
_clientSockets = [NSMutableDictionary dictionary];
_protocol = [[PTProtocol alloc] initWithDispatchQueue:_socketQueue];
@@ -41,24 +42,27 @@
return self;
}
- (void)dealloc
{
- (void)dealloc {
[self close];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)forwardConnectionsFromPort:(NSUInteger)port
{
- (void)forwardConnectionsFromPort:(NSUInteger)port {
[self _forwardConnectionsFromPort:port reportError:YES];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
[[NSNotificationCenter defaultCenter]
addObserverForName:UIApplicationDidBecomeActiveNotification
object:nil
queue:nil
usingBlock:^(NSNotification* note) {
[self _forwardConnectionsFromPort:port reportError:NO];
}];
}
- (void)_forwardConnectionsFromPort:(NSUInteger)port reportError:(BOOL)shouldReportError
{
GCDAsyncSocket *serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_socketQueue];
NSError *listenError;
- (void)_forwardConnectionsFromPort:(NSUInteger)port
reportError:(BOOL)shouldReportError {
GCDAsyncSocket* serverSocket =
[[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_socketQueue];
NSError* listenError;
if ([serverSocket acceptOnPort:port error:&listenError]) {
_serverSocket = serverSocket;
} else {
@@ -68,21 +72,31 @@
}
}
- (void)listenForMultiplexingChannelOnPort:(NSUInteger)port
{
- (void)listenForMultiplexingChannelOnPort:(NSUInteger)port {
[self _listenForMultiplexingChannelOnPort:port reportError:YES];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
[[NSNotificationCenter defaultCenter]
addObserverForName:UIApplicationDidBecomeActiveNotification
object:nil
queue:nil
usingBlock:^(NSNotification* note) {
[self _listenForMultiplexingChannelOnPort:port reportError:NO];
}];
}
- (void)_listenForMultiplexingChannelOnPort:(NSUInteger)port reportError:(BOOL)shouldReportError
{
PTChannel *channel = [[PTChannel alloc] initWithProtocol:_protocol delegate:self];
[channel listenOnPort:port IPv4Address:INADDR_LOOPBACK callback:^(NSError *error) {
- (void)_listenForMultiplexingChannelOnPort:(NSUInteger)port
reportError:(BOOL)shouldReportError {
PTChannel* channel = [[PTChannel alloc] initWithProtocol:_protocol
delegate:self];
[channel
listenOnPort:port
IPv4Address:INADDR_LOOPBACK
callback:^(NSError* error) {
if (error) {
if (shouldReportError) {
FBPFLog(@"Failed to listen on 127.0.0.1:%lu: %@", (unsigned long)port, error);
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);
@@ -91,8 +105,7 @@
}];
}
- (void)close
{
- (void)close {
if (_serverChannel) {
[_serverChannel close];
_serverChannel = nil;
@@ -102,7 +115,9 @@
#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
// established will cancel any previous connection and "take its place".
if (_peerChannel) {
@@ -116,22 +131,27 @@
FBPFTrace(@"Connected to %@", address);
}
- (void)ioFrameChannel:(PTChannel *)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(PTData *)payload {
//NSLog(@"didReceiveFrameOfType: %u, %u, %@", type, tag, payload);
- (void)ioFrameChannel:(PTChannel*)channel
didReceiveFrameOfType:(uint32_t)type
tag:(uint32_t)tag
payload:(PTData*)payload {
// NSLog(@"didReceiveFrameOfType: %u, %u, %@", type, tag, payload);
if (type == FKPortForwardingFrameTypeWriteToPipe) {
GCDAsyncSocket *sock = _clientSockets[@(tag)];
[sock writeData:[NSData dataWithBytes:payload.data length:payload.length] withTimeout:-1 tag:0];
GCDAsyncSocket* sock = _clientSockets[@(tag)];
[sock writeData:[NSData dataWithBytes:payload.data length:payload.length]
withTimeout:-1
tag:0];
FBPFTrace(@"channel -> socket (%d), %zu bytes", tag, payload.length);
}
if (type == FKPortForwardingFrameTypeClosePipe) {
GCDAsyncSocket *sock = _clientSockets[@(tag)];
GCDAsyncSocket* sock = _clientSockets[@(tag)];
[sock disconnectAfterWriting];
}
}
- (void)ioFrameChannel:(PTChannel *)channel didEndWithError:(NSError *)error {
for (GCDAsyncSocket *sock in [_clientSockets objectEnumerator]) {
- (void)ioFrameChannel:(PTChannel*)channel didEndWithError:(NSError*)error {
for (GCDAsyncSocket* sock in [_clientSockets objectEnumerator]) {
[sock setDelegate:nil];
[sock disconnect];
}
@@ -139,11 +159,10 @@
FBPFTrace(@"Disconnected from %@, error = %@", channel.userInfo, error);
}
#pragma mark - GCDAsyncSocketDelegate
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
- (void)socket:(GCDAsyncSocket*)sock
didAcceptNewSocket:(GCDAsyncSocket*)newSocket {
dispatch_block_t block = ^() {
if (!self->_peerChannel) {
[newSocket setDelegate:nil];
@@ -154,8 +173,13 @@
newSocket.userData = @(tag);
newSocket.delegate = self;
self->_clientSockets[@(tag)] = newSocket;
[self->_peerChannel sendFrameOfType:FKPortForwardingFrameTypeOpenPipe tag:self->_lastClientSocketTag withPayload:nil callback:^(NSError *error) {
FBPFTrace(@"open socket (%d), error = %@", (unsigned int)tag, error);
[self->_peerChannel
sendFrameOfType:FKPortForwardingFrameTypeOpenPipe
tag:self->_lastClientSocketTag
withPayload:nil
callback:^(NSError* error) {
FBPFTrace(
@"open socket (%d), error = %@", (unsigned int)tag, error);
[newSocket readDataWithTimeout:-1 tag:0];
}];
};
@@ -163,28 +187,46 @@
if (_peerChannel) {
block();
} 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];
FBPFTrace(@"Incoming data on socket (%d) - %lu bytes", (unsigned int)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);
FBPFTrace(
@"Incoming data on socket (%d) - %lu bytes",
(unsigned int)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];
[_clientSockets removeObjectForKey:@(tag)];
[_peerChannel sendFrameOfType:FKPortForwardingFrameTypeClosePipe tag:tag withPayload:nil callback:^(NSError *error) {
FBPFTrace(@"socket (%d) disconnected, err = %@, peer error = %@", (unsigned int)tag, err, error);
[_peerChannel
sendFrameOfType:FKPortForwardingFrameTypeClosePipe
tag:tag
withPayload:nil
callback:^(NSError* error) {
FBPFTrace(
@"socket (%d) disconnected, err = %@, peer error = %@",
(unsigned int)tag,
err,
error);
}];
}
@end

View File

@@ -16,6 +16,6 @@
@interface FlipperClient (Testing)
- (instancetype)initWithCppClient:(facebook::flipper::FlipperClient *)cppClient;
- (instancetype)initWithCppClient:(facebook::flipper::FlipperClient*)cppClient;
@end

View File

@@ -12,30 +12,32 @@
#import "FlipperStateUpdateListener.h"
/**
Represents a connection between the Sonar desktop och client side. Manages the lifecycle of attached
plugin instances.
Represents a connection between the Sonar desktop och client side. Manages the
lifecycle of attached plugin instances.
*/
@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;
/**
Register a plugin with the client.
*/
- (void)addPlugin:(NSObject<FlipperPlugin> *)plugin;
- (void)addPlugin:(NSObject<FlipperPlugin>*)plugin;
/**
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.
@@ -50,19 +52,20 @@ Stop the connection to the Sonar desktop.
/**
Get the log of state changes from the sonar client
*/
- (NSString *)getState;
- (NSString*)getState;
/**
Get the current summarized state of the sonar client
*/
- (NSArray<NSDictionary *> *)getStateElements;
- (NSArray<NSDictionary*>*)getStateElements;
/**
Subscribe a ViewController to state update change notifications
*/
- (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)new NS_UNAVAILABLE;

View File

@@ -8,14 +8,14 @@
#if FB_SONARKIT_ENABLED
#import "FlipperClient.h"
#import "FlipperCppWrapperPlugin.h"
#import <Flipper/FlipperClient.h>
#import <UIKit/UIKit.h>
#include <folly/io/async/EventBase.h>
#include <folly/io/async/ScopedEventBaseThread.h>
#import <UIKit/UIKit.h>
#include "SKStateUpdateCPPWrapper.h"
#import "FlipperClient+Testing.h"
#import "FlipperCppWrapperPlugin.h"
#import "SKEnvironmentVariables.h"
#include "SKStateUpdateCPPWrapper.h"
#if !TARGET_OS_SIMULATOR
#import <FKPortForwarding/FKPortForwardingServer.h>
@@ -24,23 +24,22 @@
using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
@implementation FlipperClient {
facebook::flipper::FlipperClient *_cppClient;
facebook::flipper::FlipperClient* _cppClient;
folly::ScopedEventBaseThread sonarThread;
folly::ScopedEventBaseThread connectionThread;
#if !TARGET_OS_SIMULATOR
FKPortForwardingServer *_secureServer;
FKPortForwardingServer *_insecureServer;
FKPortForwardingServer* _secureServer;
FKPortForwardingServer* _insecureServer;
#endif
}
+ (instancetype)sharedClient
{
static FlipperClient *sharedClient = nil;
+ (instancetype)sharedClient {
static FlipperClient* sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
try {
sharedClient = [[self alloc] init];
} catch (const std::exception &e) {
} catch (const std::exception& e) {
// fail.
sharedClient = nil;
}
@@ -48,31 +47,37 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
return sharedClient;
}
- (instancetype)init
{
- (instancetype)init {
if (self = [super init]) {
UIDevice *device = [UIDevice currentDevice];
NSString *deviceName = [device name];
NSBundle *bundle = [NSBundle mainBundle];
NSString *appName = [bundle objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey];
NSString *appId = [bundle bundleIdentifier];
NSString *privateAppDirectory = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0];
UIDevice* device = [UIDevice currentDevice];
NSString* deviceName = [device name];
NSBundle* bundle = [NSBundle mainBundle];
NSString* appName =
[bundle objectForInfoDictionaryKey:(NSString*)kCFBundleNameKey];
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 &&
![manager createDirectoryAtPath:privateAppDirectory withIntermediateDirectories:YES attributes:nil error:nil]) {
![manager createDirectoryAtPath:privateAppDirectory
withIntermediateDirectories:YES
attributes:nil
error:nil]) {
return nil;
}
#if TARGET_OS_SIMULATOR
deviceName = [NSString stringWithFormat:@"%@ %@", [[UIDevice currentDevice] model], @"Simulator"];
deviceName = [NSString stringWithFormat:@"%@ %@",
[[UIDevice currentDevice] model],
@"Simulator"];
#endif
static const std::string UNKNOWN = std::string("unknown");
try {
facebook::flipper::FlipperClient::init({
{
facebook::flipper::FlipperClient::init(
{{
"localhost",
"iOS",
[deviceName UTF8String],
@@ -84,10 +89,9 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
sonarThread.getEventBase(),
connectionThread.getEventBase(),
[SKEnvironmentVariables getInsecurePort],
[SKEnvironmentVariables getSecurePort]
});
[SKEnvironmentVariables getSecurePort]});
_cppClient = facebook::flipper::FlipperClient::instance();
} catch (const std::system_error &e) {
} catch (const std::system_error& e) {
// Probably ran out of disk space.
return nil;
}
@@ -95,32 +99,27 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
return self;
}
- (void)refreshPlugins
{
- (void)refreshPlugins {
_cppClient->refreshPlugins();
}
- (void)addPlugin:(NSObject<FlipperPlugin> *)plugin
{
- (void)addPlugin:(NSObject<FlipperPlugin>*)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));
}
- (NSObject<FlipperPlugin> *)pluginWithIdentifier:(NSString *)identifier
{
- (NSObject<FlipperPlugin>*)pluginWithIdentifier:(NSString*)identifier {
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 nil;
}
- (void)start
{
- (void)start {
#if !TARGET_OS_SIMULATOR
_secureServer = [FKPortForwardingServer new];
[_secureServer forwardConnectionsFromPort:8088];
@@ -132,9 +131,7 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
_cppClient->start();
}
- (void)stop
{
- (void)stop {
_cppClient->stop();
#if !TARGET_OS_SIMULATOR
[_secureServer close];
@@ -144,16 +141,18 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
#endif
}
- (NSString *)getState {
- (NSString*)getState {
return @(_cppClient->getState().c_str());
}
- (NSArray *)getStateElements {
NSMutableArray<NSDictionary<NSString *, NSString *>*> *const array = [NSMutableArray array];
- (NSArray*)getStateElements {
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_;
NSString *stateString;
NSString* stateString;
switch (state) {
case facebook::flipper::in_progress:
stateString = @"⏳ ";
@@ -172,8 +171,8 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
break;
}
[array addObject:@{
@"name": [NSString stringWithUTF8String:element.name_.c_str()],
@"state": stateString
@"name" : [NSString stringWithUTF8String:element.name_.c_str()],
@"state" : stateString
}];
}
return array;
@@ -188,7 +187,7 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
@implementation FlipperClient (Testing)
- (instancetype)initWithCppClient:(facebook::flipper::FlipperClient *)cppClient {
- (instancetype)initWithCppClient:(facebook::flipper::FlipperClient*)cppClient {
if (self = [super init]) {
_cppClient = cppClient;
}

View File

@@ -7,19 +7,20 @@
#ifdef FB_SONARKIT_ENABLED
#include "FlipperStateUpdateListener.h"
#import <UIKit/UIKit.h>
#include "FlipperStateUpdateListener.h"
@interface StateTableDataSource : NSObject <UITableViewDataSource>
@property (strong, nonatomic) NSArray<NSDictionary *> *elements;
@interface StateTableDataSource : NSObject<UITableViewDataSource>
@property(strong, nonatomic) NSArray<NSDictionary*>* elements;
@end
@interface FlipperDiagnosticsViewController : UIViewController<FlipperStateUpdateListener>
@property(strong, nonatomic) StateTableDataSource *tableDataSource;
@property(strong, nonatomic) UILabel *stateLabel;
@property(strong, nonatomic) UITableView *stateTable;
@property(strong, nonatomic) UIScrollView *scrollView;
@property(strong, nonatomic) UILabel *logLabel;
@interface FlipperDiagnosticsViewController
: UIViewController<FlipperStateUpdateListener>
@property(strong, nonatomic) StateTableDataSource* tableDataSource;
@property(strong, nonatomic) UILabel* stateLabel;
@property(strong, nonatomic) UITableView* stateTable;
@property(strong, nonatomic) UIScrollView* scrollView;
@property(strong, nonatomic) UILabel* logLabel;
- (void)onUpdate;
@end

View File

@@ -12,10 +12,11 @@
#define STATE_VIEW_HEIGHT 300
static NSString *const kSKCellIdentifier = @"FlipperDiagnosticStateTableStableCellIdentifier";
static NSString* const kSKCellIdentifier =
@"FlipperDiagnosticStateTableStableCellIdentifier";
@implementation StateTableDataSource
- (instancetype)initWithElements:(NSArray<NSDictionary *> *)elements {
- (instancetype)initWithElements:(NSArray<NSDictionary*>*)elements {
self = [super init];
if (self) {
_elements = elements;
@@ -23,16 +24,21 @@ static NSString *const kSKCellIdentifier = @"FlipperDiagnosticStateTableStableCe
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;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kSKCellIdentifier forIndexPath:indexPath];
UITableViewCell* cell =
[tableView dequeueReusableCellWithIdentifier:kSKCellIdentifier
forIndexPath:indexPath];
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;
}
- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- (NSInteger)tableView:(nonnull UITableView*)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.elements count];
}
@@ -43,16 +49,30 @@ static NSString *const kSKCellIdentifier = @"FlipperDiagnosticStateTableStableCe
- (void)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.logLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.scrollView.frame.size.height)];
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.logLabel =
[[UILabel alloc] initWithFrame:CGRectMake(
0,
0,
self.view.frame.size.width,
self.scrollView.frame.size.height)];
self.logLabel.numberOfLines = 0;
self.logLabel.font = [UIFont fontWithName:@"Arial" size:10];
[self.scrollView addSubview:self.logLabel];
self.stateTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, STATE_VIEW_HEIGHT)];
[self.stateTable registerClass:[UITableViewCell class] forCellReuseIdentifier:kSKCellIdentifier];
self.stateTable = [[UITableView alloc]
initWithFrame:CGRectMake(
0, 0, self.view.bounds.size.width, STATE_VIEW_HEIGHT)];
[self.stateTable registerClass:[UITableViewCell class]
forCellReuseIdentifier:kSKCellIdentifier];
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 updateLogView];
@@ -63,7 +83,7 @@ static NSString *const kSKCellIdentifier = @"FlipperDiagnosticStateTableStableCe
}
- (void)onUpdate {
FlipperDiagnosticsViewController __weak *weakSelf = self;
FlipperDiagnosticsViewController __weak* weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf updateStateTable];
[weakSelf updateLogView];
@@ -71,18 +91,21 @@ static NSString *const kSKCellIdentifier = @"FlipperDiagnosticStateTableStableCe
}
- (void)updateStateTable {
self.tableDataSource.elements = [[FlipperClient sharedClient] getStateElements];
self.tableDataSource.elements =
[[FlipperClient sharedClient] getStateElements];
[self.stateTable reloadData];
}
- (void)updateLogView {
NSString *state = [[FlipperClient sharedClient] getState];
NSString* state = [[FlipperClient sharedClient] getState];
self.logLabel.text = state;
[self.logLabel sizeToFit];
self.scrollView.contentSize = self.logLabel.frame.size;
// 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];
}

View File

@@ -6,12 +6,13 @@
*/
#import <Foundation/Foundation.h>
#import "SKMacros.h"
#import "FlipperResponder.h"
#import "SKMacros.h"
SK_EXTERN_C_BEGIN
void FlipperPerformBlockOnMainThread(void(^block)(), id<FlipperResponder> responder);
void FlipperPerformBlockOnMainThread(
void (^block)(),
id<FlipperResponder> responder);
SK_EXTERN_C_END
@protocol FlipperConnection;
@@ -19,26 +20,28 @@ SK_EXTERN_C_END
@protocol FlipperPlugin
/**
The plugin's identifier. This should map to a javascript plugin with the same identifier to ensure
messages are sent correctly.
The plugin's identifier. This should map to a javascript plugin with the same
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
the Sonar desktop app. The provided connection can be used to register method receivers as well
as send messages back to the desktop app.
Called when a connection has been established between this plugin and the
corresponding plugin on the Sonar desktop app. The provided connection can be
used to register method receivers as well as send messages back to the desktop
app.
*/
- (void)didConnect:(id<FlipperConnection>)connection;
/**
Called when a plugin has been disconnected and the SonarConnection provided in didConnect is no
longer valid to use.
Called when a plugin has been disconnected and the SonarConnection provided in
didConnect is no longer valid to use.
*/
- (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
- (BOOL)runInBackground;

View File

@@ -8,18 +8,19 @@
#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
/**
Respond with a successful return value.
*/
- (void)success:(NSDictionary *)response;
- (void)success:(NSDictionary*)response;
/**
Respond with an error.
*/
- (void)error:(NSDictionary *)response;
- (void)error:(NSDictionary*)response;
@end

View File

@@ -9,24 +9,33 @@
#import "FlipperPlugin.h"
#import "FlipperResponder.h"
void FlipperPerformBlockOnMainThread(void(^block)(), id<FlipperResponder> responder)
{
void FlipperPerformBlockOnMainThread(
void (^block)(),
id<FlipperResponder> responder) {
if ([NSThread isMainThread]) {
@try {
block();
} @catch (NSException *e) {
[responder error:@{@"name": e.name, @"message": e.reason}];
} @catch (NSException* e) {
[responder error:@{@"name" : e.name, @"message" : e.reason}];
} @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 {
dispatch_async(dispatch_get_main_queue(), ^{
@try {
block();
} @catch (NSException *e) {
[responder error:@{@"name": e.name, @"message": e.reason}];
} @catch (NSException* e) {
[responder error:@{@"name" : e.name, @"message" : e.reason}];
} @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"
}];
}
});
}

View File

@@ -8,11 +8,12 @@
#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
+ (int)getInsecurePort;
+ (int)getSecurePort;
+ (int)getInsecurePort;
+ (int)getSecurePort;
@end
#endif

View File

@@ -15,21 +15,27 @@ static int const DEFAULT_SECURE_PORT = 8088;
@implementation SKEnvironmentVariables
+ (int)getInsecurePort {
NSString *envVar = [self getFlipperPortsVariable];
return [self extractIntFromPropValue:envVar atIndex:0 withDefault:DEFAULT_INSECURE_PORT];
NSString* envVar = [self getFlipperPortsVariable];
return [self extractIntFromPropValue:envVar
atIndex:0
withDefault:DEFAULT_INSECURE_PORT];
}
+ (int)getSecurePort {
NSString *envVar = [self getFlipperPortsVariable];
return [self extractIntFromPropValue:envVar atIndex:1 withDefault:DEFAULT_SECURE_PORT];
NSString* envVar = [self getFlipperPortsVariable];
return [self extractIntFromPropValue:envVar
atIndex:1
withDefault:DEFAULT_SECURE_PORT];
}
+ (int)extractIntFromPropValue:(NSString *)propValue atIndex:(int)index withDefault:(int)fallback {
NSArray<NSString *> *components = [propValue componentsSeparatedByString:@","];
NSString *component = [components objectAtIndex:index];
+ (int)extractIntFromPropValue:(NSString*)propValue
atIndex:(int)index
withDefault:(int)fallback {
NSArray<NSString*>* components = [propValue componentsSeparatedByString:@","];
NSString* component = [components objectAtIndex:index];
int envInt = [component intValue];
return envInt > 0 ? envInt : fallback;
}
+ (NSString *)getFlipperPortsVariable {
NSString *value = NSProcessInfo.processInfo.environment[@"FLIPPER_PORTS"];
+ (NSString*)getFlipperPortsVariable {
NSString* value = NSProcessInfo.processInfo.environment[@"FLIPPER_PORTS"];
return value;
}
@end

View File

@@ -13,13 +13,15 @@
/*
* This class exists to bridge the gap between Objective C and C++.
* 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 {
public:
public:
SKStateUpdateCPPWrapper(id<FlipperStateUpdateListener> delegate_);
void onUpdate();
private:
private:
__weak id<FlipperStateUpdateListener> delegate_;
};

View File

@@ -9,7 +9,8 @@
#include "SKStateUpdateCPPWrapper.h"
SKStateUpdateCPPWrapper::SKStateUpdateCPPWrapper(id<FlipperStateUpdateListener> controller) {
SKStateUpdateCPPWrapper::SKStateUpdateCPPWrapper(
id<FlipperStateUpdateListener> controller) {
delegate_ = controller;
}