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
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -16,6 +16,6 @@
|
||||
|
||||
@interface FlipperClient (Testing)
|
||||
|
||||
- (instancetype)initWithCppClient:(facebook::flipper::FlipperClient *)cppClient;
|
||||
- (instancetype)initWithCppClient:(facebook::flipper::FlipperClient*)cppClient;
|
||||
|
||||
@end
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
#include "SKStateUpdateCPPWrapper.h"
|
||||
|
||||
SKStateUpdateCPPWrapper::SKStateUpdateCPPWrapper(id<FlipperStateUpdateListener> controller) {
|
||||
SKStateUpdateCPPWrapper::SKStateUpdateCPPWrapper(
|
||||
id<FlipperStateUpdateListener> controller) {
|
||||
delegate_ = controller;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user