-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Replace ideviceinfo and idevice_id with xcdevice #49854
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
0ee695b to
456e43b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was more like 5 seconds in my tests, but let's be conservative...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sp: "after with" -> "after which"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant with the import of '../build_info.dart' below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dang I thought I fixed that. Android Studio loves automatically importing package:flutter_tools.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a Stream?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
async* / yield requires this to be a stream. I can change it to async and to just return a List, if we prefer that pattern...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could return a Stream if we're actually getting results bit-by-bit from xcdevice, or if this is implementing an interface that requires it to be a Stream, but otherwise we should probably prefer Future<List>, or Future<Iterable>.
(async* Streams also can have some surprising behavior. IIRC they don't interact well with FakeAsync for tests.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a stream?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, async*.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we pass a smaller timeout if we know the user doesn't care about wireless debugging?
Said another way, if wireless device discovery was under a flag, could this number be smaller?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the user doesn't care about networked devices and this is changed to --timeout 1 (faster than the default) , this returns the USB-tethered devices and none of the networked devices.
There's an xcdevice wait [--usb|--wifi|--both] [--timeout=sec] <udid> which will return as soon as the device is found but waits until the timeout if not, which would be fast for USB-tethered devices. That would make sense for flutter run -d <udid> hasSpecifiedDeviceId situations, though it would require PollingDeviceDiscovery to get refactored to take a "hint" identifier or something like that.
Maybe it would be okay for flutter doctor and flutter devices to take the full 5 seconds since we can then surface that it's networked and that they need to pass in -d <udid> to flutter run (attach, logs, screenshot, etc) on the device. And users would only be running those command infrequently, and they probably would prefer an accurate listing than for them to be fast.
Proposal:
- Switch to
xcdevice wait --both --timeout=5for any command using-d <udid>(run,attach,logs,screenshot) to return fast if possible, but wait if needed. - When there's no
-d <udid>or-d allassume USB-only (common case) and use the fastest timeout possible. - Keep the long timeout for
flutter doctorandflutter devicesand for "network" interface show a warning like "This device is available over the network and must be specified with `-d {}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the --timeout value be smaller than 1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the
--timeoutvalue be smaller than 1?
1 seems to be the minimum allowed. 0 reverts to the longer default timeout.
christopherfujino
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few questions, but overall this is great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean it will always take 5 seconds, even if all devices were found?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NVM, just read "cons" above. adding 5 seconds to the doctor seems costly, I wonder if we should make the extended timeout opt-in at first? Not sure how many users would be interested in this feature.
|
Should we warn the user that connecting to the observatory is not supported at this time? |
|
I would actually suggest not listing network devices until we have a way to connect to them |
@christopherfujino This is a good idea, and detectible since we know it's a "network" interface.
@jonahwilliams That's what we do now, we just ignore them. I think it's better to at least let the user at least launch the app, even if they can't connect to the observatory, than to not ever be able to launch it at all. What about @christopherfujino's suggestion to print a message that networked devices don't support hot reload and just exit instead of crashing? |
|
I'm going to repurpose this issue to replace |
sgtm |
|
I guess if we can still launch the app, that is definitely useful |
456e43b to
3b1ffbd
Compare
Done. PTAL! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Best practice is to hoist RegExp construction out of the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the --timeout value be smaller than 1?
|
Diagnostic messages I've seen while testing: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks pretty great -- I had no idea xcdevice existed!
Two quick questions:
- do all versions of XCode we support include this tool? (if we only support 11, then we're set)
- do they all emit compatible output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is pretty long -- could a few smaller methods be factored out to break out? Something like some {sub,super,}set of:
- fetch blob o' json (already done:
_getAllDevices()) isIPhoneOSDevice(deviceProperties)- error message check (already done:
_parseErrorMessage) _isAvailable(...)_isUSBDevice(...)(or alternatively_getConnectionType(...) == _DeviceConnectionType.usb)- get SDK version
- get cpu arch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, done!
I tested on Xcode 10.1 and the output looked the same, though the error message text was sometimes different. I'll try on Xcode 10.2, which is our current minimum required version. Of course there's nothing stopping Xcode from completely changing or even removing this tool in the next release... |
75f10c3 to
3ac412f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider printing a trace message with the exception object so we can get some additional info from a --verbose run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you may also want to pass throwOnError: true to runSync(). That will make runSync() throw a ProcessException if the xcrun exit code is non-zero.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this fail more loudly if the reason we can't find devices is that the tool isn't installed like we expect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen GitHub issues where people are trying to run -d chrome or for a particular Android device, and they are getting crashes because their personal iPhone is plugged in but isn't set up for development. I don't think we should make people have Xcode installed if they aren't doing iOS development, and we can't really tell what their intentions are at the point we're trying to find a particular device identifier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay, yeah that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this is called shortly after an empty return from getAllConnectedDevices(). Would it make sense to cache the result of _getAllDevices() to avoid shelling out to xcdevice again?
3ac412f to
0e229d2
Compare
eaf12b6 to
0aeb10a
Compare
Rebased onto master to resolve. |
Description
Xcode ships with a command line tool called
xcdevicethat produces a json array of all available devices, including iOS devices that can be deployed via Xcode over the network (Connect via network checkbox). This PR filters out these network devices, but it's relevant to someday fixing #15072.I checked to make sure
xcdeviceis available in Xcode 10.2 (minimum Xcode required by Flutter) and later.Example output:
{ "simulator" : false, "operatingSystemVersion" : "13.3 (17C54)", "interface" : "usb", "available" : true, "platform" : "com.apple.platform.iphoneos", "modelCode" : "iPhone8,1", "identifier" : "d83d5bc53967baa0ee18626ba87b6254b2ab5418", "architecture" : "arm64", "modelName" : "iPhone 6s", "name" : "iPhone" }Since this provides the identifier, name, operating system, and architecture, we can get rid of all usages of
idevice_idandideviceinfo(cleanup happening in the next PR since this one was already getting too big).Also, show any connection errors in doctor instead of crashing. Example:
Related Issues
Part of #6118
Precursor to #15072 (will make networked devices discoverable when we stop filtering "network" interfaces).
Fixes #49375
Fixes #36524
Fixes #47727
Fixes #43398
Fixes #48057
Supersedes #49626
Supersedes #45657
Supersedes part of #36902?
Tests
xcode_test, devices_test
Checklist
///).flutter analyze --flutter-repo) does not report any problems on my PR.Breaking Change