Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 4494a83

Browse files
authored
Add flag to not publish the observatory port over mDNS (#21883)
1 parent 40c226e commit 4494a83

File tree

7 files changed

+59
-62
lines changed

7 files changed

+59
-62
lines changed

common/settings.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ std::string Settings::ToString() const {
4646
stream << "enable_dart_profiling: " << enable_dart_profiling << std::endl;
4747
stream << "disable_dart_asserts: " << disable_dart_asserts << std::endl;
4848
stream << "enable_observatory: " << enable_observatory << std::endl;
49+
stream << "enable_observatory_publication: " << enable_observatory_publication
50+
<< std::endl;
4951
stream << "observatory_host: " << observatory_host << std::endl;
5052
stream << "observatory_port: " << observatory_port << std::endl;
5153
stream << "use_test_fonts: " << use_test_fonts << std::endl;

common/settings.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ struct Settings {
126126
// Whether the Dart VM service should be enabled.
127127
bool enable_observatory = false;
128128

129+
// Whether to publish the observatory URL over mDNS.
130+
// On iOS 14 this prompts a local network permission dialog,
131+
// which cannot be accepted or dismissed in a CI environment.
132+
bool enable_observatory_publication = true;
133+
129134
// The IP address to which the Dart VM service is bound.
130135
std::string observatory_host;
131136

shell/common/switches.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) {
221221
settings.enable_observatory =
222222
!command_line.HasOption(FlagForSwitch(Switch::DisableObservatory));
223223

224+
// Enable mDNS Observatory Publication
225+
settings.enable_observatory_publication = !command_line.HasOption(
226+
FlagForSwitch(Switch::DisableObservatoryPublication));
227+
224228
// Set Observatory Host
225229
if (command_line.HasOption(FlagForSwitch(Switch::DeviceObservatoryHost))) {
226230
command_line.GetOptionValue(FlagForSwitch(Switch::DeviceObservatoryHost),

shell/common/switches.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ DEF_SWITCH(DisableObservatory,
7979
"disable-observatory",
8080
"Disable the Dart Observatory. The observatory is never available "
8181
"in release mode.")
82+
DEF_SWITCH(DisableObservatoryPublication,
83+
"disable-observatory-publication",
84+
"Disable mDNS Dart Observatory publication.")
8285
DEF_SWITCH(IPv6,
8386
"ipv6",
8487
"Bind to the IPv6 localhost address for the Dart Observatory. "

shell/platform/darwin/ios/framework/Source/FlutterEngine.mm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,8 @@ - (BOOL)createShell:(NSString*)entrypoint
547547
if (!_platformViewsController) {
548548
_platformViewsController.reset(new flutter::FlutterPlatformViewsController());
549549
}
550-
_publisher.reset([[FlutterObservatoryPublisher alloc] init]);
550+
_publisher.reset([[FlutterObservatoryPublisher alloc]
551+
initWithEnableObservatoryPublication:settings.enable_observatory_publication]);
551552
[self maybeSetupPlatformViewChannels];
552553
_shell->GetIsGpuDisabledSyncSwitch()->SetSwitch(_isGpuDisabled ? true : false);
553554
if (profilerEnabled) {

shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99

1010
@interface FlutterObservatoryPublisher : NSObject
1111

12+
- (instancetype)initWithEnableObservatoryPublication:(BOOL)enableObservatoryPublication
13+
NS_DESIGNATED_INITIALIZER;
14+
- (instancetype)init NS_UNAVAILABLE;
15+
+ (instancetype)new NS_UNAVAILABLE;
16+
1217
@property(nonatomic, readonly) NSURL* url;
1318

1419
@end

shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.mm

Lines changed: 38 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#if FLUTTER_RELEASE
1010

1111
@implementation FlutterObservatoryPublisher
12+
- (instancetype)initWithEnableObservatoryPublication:(BOOL)enableObservatoryPublication {
13+
return [super init];
14+
}
1215
@end
1316

1417
#else // FLUTTER_RELEASE
@@ -37,26 +40,23 @@ @implementation FlutterObservatoryPublisher
3740
#include <net/if.h>
3841

3942
#include "flutter/fml/logging.h"
40-
#include "flutter/fml/make_copyable.h"
4143
#include "flutter/fml/memory/weak_ptr.h"
4244
#include "flutter/fml/message_loop.h"
4345
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
44-
#include "flutter/fml/task_runner.h"
4546
#include "flutter/runtime/dart_service_isolate.h"
4647

4748
@protocol FlutterObservatoryPublisherDelegate
48-
- (instancetype)initWithOwner:(FlutterObservatoryPublisher*)owner;
49-
- (void)publishServiceProtocolPort:(NSString*)uri;
49+
- (void)publishServiceProtocolPort:(NSURL*)uri;
5050
- (void)stopService;
51-
52-
@property(readonly) fml::scoped_nsobject<NSURL> url;
5351
@end
5452

5553
@interface FlutterObservatoryPublisher ()
56-
- (NSData*)createTxtData:(NSURL*)url;
54+
+ (NSData*)createTxtData:(NSURL*)url;
5755

58-
@property(readonly) NSString* serviceName;
56+
@property(readonly, class) NSString* serviceName;
5957
@property(readonly) fml::scoped_nsobject<NSObject<FlutterObservatoryPublisherDelegate>> delegate;
58+
@property(nonatomic, readwrite) NSURL* url;
59+
@property(readonly) BOOL enableObservatoryPublication;
6060

6161
@end
6262

@@ -68,31 +68,17 @@ @interface ObservatoryDNSServiceDelegate : NSObject <FlutterObservatoryPublisher
6868
@end
6969

7070
@implementation ObservatoryDNSServiceDelegate {
71-
fml::scoped_nsobject<FlutterObservatoryPublisher> _owner;
7271
DNSServiceRef _dnsServiceRef;
7372
}
7473

75-
@synthesize url;
76-
77-
- (instancetype)initWithOwner:(FlutterObservatoryPublisher*)owner {
78-
self = [super init];
79-
NSAssert(self, @"Super must not return null on init.");
80-
_owner.reset([owner retain]);
81-
return self;
82-
}
83-
8474
- (void)stopService {
8575
if (_dnsServiceRef) {
8676
DNSServiceRefDeallocate(_dnsServiceRef);
8777
_dnsServiceRef = NULL;
8878
}
8979
}
9080

91-
- (void)publishServiceProtocolPort:(NSString*)uri {
92-
// uri comes in as something like 'http://127.0.0.1:XXXXX/' where XXXXX is the port
93-
// number.
94-
url.reset([[NSURL alloc] initWithString:uri]);
95-
81+
- (void)publishServiceProtocolPort:(NSURL*)url {
9682
DNSServiceFlags flags = kDNSServiceFlagsDefault;
9783
#if TARGET_IPHONE_SIMULATOR
9884
// Simulator needs to use local loopback explicitly to work.
@@ -105,11 +91,11 @@ - (void)publishServiceProtocolPort:(NSString*)uri {
10591
const char* domain = "local."; // default domain
10692
uint16_t port = [[url port] unsignedShortValue];
10793

108-
NSData* txtData = [_owner createTxtData:url.get()];
109-
int err =
110-
DNSServiceRegister(&_dnsServiceRef, flags, interfaceIndex,
111-
[_owner.get().serviceName UTF8String], registrationType, domain, NULL,
112-
htons(port), txtData.length, txtData.bytes, registrationCallback, NULL);
94+
NSData* txtData = [FlutterObservatoryPublisher createTxtData:url];
95+
int err = DNSServiceRegister(&_dnsServiceRef, flags, interfaceIndex,
96+
FlutterObservatoryPublisher.serviceName.UTF8String, registrationType,
97+
domain, NULL, htons(port), txtData.length, txtData.bytes,
98+
registrationCallback, NULL);
11399

114100
if (err != 0) {
115101
FML_LOG(ERROR) << "Failed to register observatory port with mDNS with error " << err << ".";
@@ -122,8 +108,8 @@ - (void)publishServiceProtocolPort:(NSString*)uri {
122108
<< "to the 'NSBonjourServices' key in your Info.plist for the Debug/"
123109
<< "Profile configurations. "
124110
<< "For more information, see "
125-
// Update link to a specific header as needed.
126-
<< "https://flutter.dev/docs/development/add-to-app/ios/project-setup";
111+
<< "https://flutter.dev/docs/development/add-to-app/ios/"
112+
"project-setup#local-network-privacy-permissions";
127113
}
128114
} else {
129115
DNSServiceSetDispatchQueue(_dnsServiceRef, dispatch_get_main_queue());
@@ -162,34 +148,21 @@ static void DNSSD_API registrationCallback(DNSServiceRef sdRef,
162148
@end
163149

164150
@implementation ObservatoryNSNetServiceDelegate {
165-
fml::scoped_nsobject<FlutterObservatoryPublisher> _owner;
166151
fml::scoped_nsobject<NSNetService> _netService;
167152
}
168153

169-
@synthesize url;
170-
171-
- (instancetype)initWithOwner:(FlutterObservatoryPublisher*)owner {
172-
self = [super init];
173-
NSAssert(self, @"Super must not return null on init.");
174-
_owner.reset([owner retain]);
175-
return self;
176-
}
177-
178154
- (void)stopService {
179155
[_netService.get() stop];
180156
[_netService.get() setDelegate:nil];
181157
}
182158

183-
- (void)publishServiceProtocolPort:(NSString*)uri {
184-
// uri comes in as something like 'http://127.0.0.1:XXXXX/' where XXXXX is the port
185-
// number.
186-
url.reset([[NSURL alloc] initWithString:uri]);
187-
188-
NSNetService* netServiceTmp = [[NSNetService alloc] initWithDomain:@"local."
189-
type:@"_dartobservatory._tcp."
190-
name:_owner.get().serviceName
191-
port:[[url port] intValue]];
192-
[netServiceTmp setTXTRecordData:[_owner createTxtData:url.get()]];
159+
- (void)publishServiceProtocolPort:(NSURL*)url {
160+
NSNetService* netServiceTmp =
161+
[[NSNetService alloc] initWithDomain:@"local."
162+
type:@"_dartobservatory._tcp."
163+
name:FlutterObservatoryPublisher.serviceName
164+
port:[[url port] intValue]];
165+
[netServiceTmp setTXTRecordData:[FlutterObservatoryPublisher createTxtData:url]];
193166
_netService.reset(netServiceTmp);
194167
[_netService.get() setDelegate:self];
195168
[_netService.get() publish];
@@ -211,19 +184,16 @@ @implementation FlutterObservatoryPublisher {
211184
std::unique_ptr<fml::WeakPtrFactory<FlutterObservatoryPublisher>> _weakFactory;
212185
}
213186

214-
- (NSURL*)url {
215-
return [_delegate.get().url autorelease];
216-
}
217-
218-
- (instancetype)init {
187+
- (instancetype)initWithEnableObservatoryPublication:(BOOL)enableObservatoryPublication {
219188
self = [super init];
220189
NSAssert(self, @"Super must not return null on init.");
221190

222191
if (@available(iOS 9.3, *)) {
223-
_delegate.reset([[ObservatoryDNSServiceDelegate alloc] initWithOwner:self]);
192+
_delegate.reset([[ObservatoryDNSServiceDelegate alloc] init]);
224193
} else {
225-
_delegate.reset([[ObservatoryNSNetServiceDelegate alloc] initWithOwner:self]);
194+
_delegate.reset([[ObservatoryNSNetServiceDelegate alloc] init]);
226195
}
196+
_enableObservatoryPublication = enableObservatoryPublication;
227197
_weakFactory = std::make_unique<fml::WeakPtrFactory<FlutterObservatoryPublisher>>(self);
228198

229199
fml::MessageLoop::EnsureInitializedForCurrentThread();
@@ -233,9 +203,15 @@ - (instancetype)init {
233203
runner = fml::MessageLoop::GetCurrent().GetTaskRunner()](const std::string& uri) {
234204
if (!uri.empty()) {
235205
runner->PostTask([weak, uri]() {
206+
// uri comes in as something like 'http://127.0.0.1:XXXXX/' where XXXXX is the port
207+
// number.
236208
if (weak) {
237-
[[weak.get() delegate]
238-
publishServiceProtocolPort:[NSString stringWithUTF8String:uri.c_str()]];
209+
NSURL* url =
210+
[[NSURL alloc] initWithString:[NSString stringWithUTF8String:uri.c_str()]];
211+
weak.get().url = url;
212+
if (weak.get().enableObservatoryPublication) {
213+
[[weak.get() delegate] publishServiceProtocolPort:url];
214+
}
239215
}
240216
});
241217
}
@@ -244,11 +220,11 @@ - (instancetype)init {
244220
return self;
245221
}
246222

247-
- (NSString*)serviceName {
223+
+ (NSString*)serviceName {
248224
return NSBundle.mainBundle.bundleIdentifier;
249225
}
250226

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

262238
- (void)dealloc {
263239
[_delegate stopService];
240+
[_url release];
264241

265242
flutter::DartServiceIsolate::RemoveServerStatusCallback(std::move(_callbackHandle));
266243
[super dealloc];

0 commit comments

Comments
 (0)