Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions common/settings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ std::string Settings::ToString() const {
stream << "enable_dart_profiling: " << enable_dart_profiling << std::endl;
stream << "disable_dart_asserts: " << disable_dart_asserts << std::endl;
stream << "enable_observatory: " << enable_observatory << std::endl;
stream << "enable_observatory_publication: " << enable_observatory_publication
<< std::endl;
stream << "observatory_host: " << observatory_host << std::endl;
stream << "observatory_port: " << observatory_port << std::endl;
stream << "use_test_fonts: " << use_test_fonts << std::endl;
Expand Down
5 changes: 0 additions & 5 deletions common/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,6 @@ struct Settings {
// Whether the Dart VM service should be enabled.
bool enable_observatory = false;

// Whether to publish the observatory URL over mDNS.
// On iOS 14 this prompts a local network permission dialog,
// which cannot be accepted or dismissed in a CI environment.
bool enable_observatory_publication = true;

// The IP address to which the Dart VM service is bound.
std::string observatory_host;

Expand Down
4 changes: 0 additions & 4 deletions shell/common/switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,6 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) {
settings.enable_observatory =
!command_line.HasOption(FlagForSwitch(Switch::DisableObservatory));

// Enable mDNS Observatory Publication
settings.enable_observatory_publication = !command_line.HasOption(
FlagForSwitch(Switch::DisableObservatoryPublication));

// Set Observatory Host
if (command_line.HasOption(FlagForSwitch(Switch::DeviceObservatoryHost))) {
command_line.GetOptionValue(FlagForSwitch(Switch::DeviceObservatoryHost),
Expand Down
3 changes: 0 additions & 3 deletions shell/common/switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ DEF_SWITCH(DisableObservatory,
"disable-observatory",
"Disable the Dart Observatory. The observatory is never available "
"in release mode.")
DEF_SWITCH(DisableObservatoryPublication,
"disable-observatory-publication",
"Disable mDNS Dart Observatory publication.")
DEF_SWITCH(IPv6,
"ipv6",
"Bind to the IPv6 localhost address for the Dart Observatory. "
Expand Down
3 changes: 1 addition & 2 deletions shell/platform/darwin/ios/framework/Source/FlutterEngine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,7 @@ - (BOOL)createShell:(NSString*)entrypoint
if (!_platformViewsController) {
_platformViewsController.reset(new flutter::FlutterPlatformViewsController());
}
_publisher.reset([[FlutterObservatoryPublisher alloc]
initWithEnableObservatoryPublication:settings.enable_observatory_publication]);
_publisher.reset([[FlutterObservatoryPublisher alloc] init]);
[self maybeSetupPlatformViewChannels];
_shell->GetIsGpuDisabledSyncSwitch()->SetSwitch(_isGpuDisabled ? true : false);
if (profilerEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@

@interface FlutterObservatoryPublisher : NSObject

- (instancetype)initWithEnableObservatoryPublication:(BOOL)enableObservatoryPublication
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

@property(nonatomic, readonly) NSURL* url;

@end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,26 @@ @implementation FlutterObservatoryPublisher
#include <net/if.h>

#include "flutter/fml/logging.h"
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/fml/message_loop.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/fml/task_runner.h"
#include "flutter/runtime/dart_service_isolate.h"

@protocol FlutterObservatoryPublisherDelegate
- (void)publishServiceProtocolPort:(NSURL*)uri;
- (instancetype)initWithOwner:(FlutterObservatoryPublisher*)owner;
- (void)publishServiceProtocolPort:(NSString*)uri;
- (void)stopService;

@property(readonly) fml::scoped_nsobject<NSURL> url;
@end

@interface FlutterObservatoryPublisher ()
+ (NSData*)createTxtData:(NSURL*)url;
- (NSData*)createTxtData:(NSURL*)url;

@property(readonly, class) NSString* serviceName;
@property(readonly) NSString* serviceName;
@property(readonly) fml::scoped_nsobject<NSObject<FlutterObservatoryPublisherDelegate>> delegate;
@property(nonatomic, readwrite) NSURL* url;
@property(readonly) BOOL enableObservatoryPublication;

@end

Expand All @@ -65,17 +68,31 @@ @interface ObservatoryDNSServiceDelegate : NSObject <FlutterObservatoryPublisher
@end

@implementation ObservatoryDNSServiceDelegate {
fml::scoped_nsobject<FlutterObservatoryPublisher> _owner;
DNSServiceRef _dnsServiceRef;
}

@synthesize url;

- (instancetype)initWithOwner:(FlutterObservatoryPublisher*)owner {
self = [super init];
NSAssert(self, @"Super must not return null on init.");
_owner.reset([owner retain]);
return self;
}

- (void)stopService {
if (_dnsServiceRef) {
DNSServiceRefDeallocate(_dnsServiceRef);
_dnsServiceRef = NULL;
}
}

- (void)publishServiceProtocolPort:(NSURL*)url {
- (void)publishServiceProtocolPort:(NSString*)uri {
// uri comes in as something like 'http://127.0.0.1:XXXXX/' where XXXXX is the port
// number.
url.reset([[NSURL alloc] initWithString:uri]);

DNSServiceFlags flags = kDNSServiceFlagsDefault;
#if TARGET_IPHONE_SIMULATOR
// Simulator needs to use local loopback explicitly to work.
Expand All @@ -88,11 +105,11 @@ - (void)publishServiceProtocolPort:(NSURL*)url {
const char* domain = "local."; // default domain
uint16_t port = [[url port] unsignedShortValue];

NSData* txtData = [FlutterObservatoryPublisher createTxtData:url];
int err = DNSServiceRegister(&_dnsServiceRef, flags, interfaceIndex,
FlutterObservatoryPublisher.serviceName.UTF8String, registrationType,
domain, NULL, htons(port), txtData.length, txtData.bytes,
registrationCallback, NULL);
NSData* txtData = [_owner createTxtData:url.get()];
int err =
DNSServiceRegister(&_dnsServiceRef, flags, interfaceIndex,
[_owner.get().serviceName UTF8String], registrationType, domain, NULL,
htons(port), txtData.length, txtData.bytes, registrationCallback, NULL);

if (err != 0) {
FML_LOG(ERROR) << "Failed to register observatory port with mDNS with error " << err << ".";
Expand All @@ -105,8 +122,8 @@ - (void)publishServiceProtocolPort:(NSURL*)url {
<< "to the 'NSBonjourServices' key in your Info.plist for the Debug/"
<< "Profile configurations. "
<< "For more information, see "
<< "https://flutter.dev/docs/development/add-to-app/ios/"
"project-setup#local-network-privacy-permissions";
// Update link to a specific header as needed.
<< "https://flutter.dev/docs/development/add-to-app/ios/project-setup";
}
} else {
DNSServiceSetDispatchQueue(_dnsServiceRef, dispatch_get_main_queue());
Expand Down Expand Up @@ -145,21 +162,34 @@ static void DNSSD_API registrationCallback(DNSServiceRef sdRef,
@end

@implementation ObservatoryNSNetServiceDelegate {
fml::scoped_nsobject<FlutterObservatoryPublisher> _owner;
fml::scoped_nsobject<NSNetService> _netService;
}

@synthesize url;

- (instancetype)initWithOwner:(FlutterObservatoryPublisher*)owner {
self = [super init];
NSAssert(self, @"Super must not return null on init.");
_owner.reset([owner retain]);
return self;
}

- (void)stopService {
[_netService.get() stop];
[_netService.get() setDelegate:nil];
}

- (void)publishServiceProtocolPort:(NSURL*)url {
NSNetService* netServiceTmp =
[[NSNetService alloc] initWithDomain:@"local."
type:@"_dartobservatory._tcp."
name:FlutterObservatoryPublisher.serviceName
port:[[url port] intValue]];
[netServiceTmp setTXTRecordData:[FlutterObservatoryPublisher createTxtData:url]];
- (void)publishServiceProtocolPort:(NSString*)uri {
// uri comes in as something like 'http://127.0.0.1:XXXXX/' where XXXXX is the port
// number.
url.reset([[NSURL alloc] initWithString:uri]);

NSNetService* netServiceTmp = [[NSNetService alloc] initWithDomain:@"local."
type:@"_dartobservatory._tcp."
name:_owner.get().serviceName
port:[[url port] intValue]];
[netServiceTmp setTXTRecordData:[_owner createTxtData:url.get()]];
_netService.reset(netServiceTmp);
[_netService.get() setDelegate:self];
[_netService.get() publish];
Expand All @@ -181,16 +211,19 @@ @implementation FlutterObservatoryPublisher {
std::unique_ptr<fml::WeakPtrFactory<FlutterObservatoryPublisher>> _weakFactory;
}

- (instancetype)initWithEnableObservatoryPublication:(BOOL)enableObservatoryPublication {
- (NSURL*)url {
return [_delegate.get().url autorelease];
}

- (instancetype)init {
self = [super init];
NSAssert(self, @"Super must not return null on init.");

if (@available(iOS 9.3, *)) {
_delegate.reset([[ObservatoryDNSServiceDelegate alloc] init]);
_delegate.reset([[ObservatoryDNSServiceDelegate alloc] initWithOwner:self]);
} else {
_delegate.reset([[ObservatoryNSNetServiceDelegate alloc] init]);
_delegate.reset([[ObservatoryNSNetServiceDelegate alloc] initWithOwner:self]);
}
_enableObservatoryPublication = enableObservatoryPublication;
_weakFactory = std::make_unique<fml::WeakPtrFactory<FlutterObservatoryPublisher>>(self);

fml::MessageLoop::EnsureInitializedForCurrentThread();
Expand All @@ -200,15 +233,9 @@ - (instancetype)initWithEnableObservatoryPublication:(BOOL)enableObservatoryPubl
runner = fml::MessageLoop::GetCurrent().GetTaskRunner()](const std::string& uri) {
if (!uri.empty()) {
runner->PostTask([weak, uri]() {
// uri comes in as something like 'http://127.0.0.1:XXXXX/' where XXXXX is the port
// number.
if (weak) {
NSURL* url =
[[NSURL alloc] initWithString:[NSString stringWithUTF8String:uri.c_str()]];
weak.get().url = url;
if (weak.get().enableObservatoryPublication) {
[[weak.get() delegate] publishServiceProtocolPort:url];
}
[[weak.get() delegate]
publishServiceProtocolPort:[NSString stringWithUTF8String:uri.c_str()]];
}
});
}
Expand All @@ -217,11 +244,11 @@ - (instancetype)initWithEnableObservatoryPublication:(BOOL)enableObservatoryPubl
return self;
}

+ (NSString*)serviceName {
- (NSString*)serviceName {
return NSBundle.mainBundle.bundleIdentifier;
}

+ (NSData*)createTxtData:(NSURL*)url {
- (NSData*)createTxtData:(NSURL*)url {
// Check to see if there's an authentication code. If there is, we'll provide
// it as a txt record so flutter tools can establish a connection.
NSString* path = [[url path] substringFromIndex:MIN(1, [[url path] length])];
Expand All @@ -234,7 +261,6 @@ + (NSData*)createTxtData:(NSURL*)url {

- (void)dealloc {
[_delegate stopService];
[_url release];

flutter::DartServiceIsolate::RemoveServerStatusCallback(std::move(_callbackHandle));
[super dealloc];
Expand Down