Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
f9499f44
Unverified
Commit
f9499f44
authored
Jul 24, 2020
by
Jenn Magder
Committed by
GitHub
Jul 24, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Detect exact device ID matches quickly (#62070)
parent
a48446f9
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
146 additions
and
20 deletions
+146
-20
device.dart
packages/flutter_tools/lib/src/device.dart
+41
-13
device_test.dart
packages/flutter_tools/test/general.shard/device_test.dart
+63
-7
mocks.dart
packages/flutter_tools/test/src/mocks.dart
+42
-0
No files found.
packages/flutter_tools/lib/src/device.dart
View file @
f9499f44
...
...
@@ -104,23 +104,51 @@ abstract class DeviceManager {
bool
get
hasSpecifiedAllDevices
=>
_specifiedDeviceId
==
'all'
;
Future
<
List
<
Device
>>
getDevicesById
(
String
deviceId
)
async
{
final
List
<
Device
>
devices
=
await
getAllConnectedDevices
();
deviceId
=
deviceId
.
toLowerCase
();
final
String
lowerDeviceId
=
deviceId
.
toLowerCase
();
bool
exactlyMatchesDeviceId
(
Device
device
)
=>
device
.
id
.
toLowerCase
()
==
d
eviceId
||
device
.
name
.
toLowerCase
()
==
d
eviceId
;
device
.
id
.
toLowerCase
()
==
lowerD
eviceId
||
device
.
name
.
toLowerCase
()
==
lowerD
eviceId
;
bool
startsWithDeviceId
(
Device
device
)
=>
device
.
id
.
toLowerCase
().
startsWith
(
deviceId
)
||
device
.
name
.
toLowerCase
().
startsWith
(
deviceId
);
device
.
id
.
toLowerCase
().
startsWith
(
lowerDeviceId
)
||
device
.
name
.
toLowerCase
().
startsWith
(
lowerDeviceId
);
// Some discoverers have hard-coded device IDs and return quickly, and others
// shell out to other processes and can take longer.
// Process discoverers as they can return results, so if an exact match is
// found quickly, we don't wait for all the discoverers to complete.
final
List
<
Device
>
prefixMatches
=
<
Device
>[];
final
Completer
<
Device
>
exactMatchCompleter
=
Completer
<
Device
>();
final
List
<
Future
<
List
<
Device
>>>
futureDevices
=
<
Future
<
List
<
Device
>>>[
for
(
final
DeviceDiscovery
discoverer
in
_platformDiscoverers
)
discoverer
.
devices
.
then
((
List
<
Device
>
devices
)
{
for
(
final
Device
device
in
devices
)
{
if
(
exactlyMatchesDeviceId
(
device
))
{
exactMatchCompleter
.
complete
(
device
);
return
null
;
}
if
(
startsWithDeviceId
(
device
))
{
prefixMatches
.
add
(
device
);
}
}
return
null
;
},
onError:
(
dynamic
error
,
StackTrace
stackTrace
)
{
// Return matches from other discoverers even if one fails.
globals
.
printTrace
(
'Ignored error discovering
$deviceId
:
$error
'
);
})
];
final
Device
exactMatch
=
devices
.
firstWhere
(
exactlyMatchesDeviceId
,
orElse:
()
=>
null
);
if
(
exactMatch
!=
null
)
{
return
<
Device
>[
exactMatch
];
}
// Wait for an exact match, or for all discoverers to return results.
await
Future
.
any
<
dynamic
>(<
Future
<
dynamic
>>[
exactMatchCompleter
.
future
,
Future
.
wait
<
List
<
Device
>>(
futureDevices
),
]);
// Match on a id or name starting with [deviceId].
return
devices
.
where
(
startsWithDeviceId
).
toList
();
if
(
exactMatchCompleter
.
isCompleted
)
{
return
<
Device
>[
await
exactMatchCompleter
.
future
];
}
return
prefixMatches
;
}
/// Returns the list of connected devices, filtered by any user-specified device id.
...
...
packages/flutter_tools/test/general.shard/device_test.dart
View file @
f9499f44
...
...
@@ -4,6 +4,7 @@
import
'dart:async'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/terminal.dart'
;
import
'package:flutter_tools/src/artifacts.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
...
...
@@ -22,9 +23,11 @@ import '../src/mocks.dart';
void
main
(
)
{
MockCache
cache
;
BufferLogger
logger
;
setUp
(()
{
cache
=
MockCache
();
logger
=
BufferLogger
.
test
();
when
(
cache
.
dyLdLibEntry
).
thenReturn
(
const
MapEntry
<
String
,
String
>(
'foo'
,
'bar'
));
});
...
...
@@ -41,25 +44,67 @@ void main() {
Cache:
()
=>
cache
,
});
testUsingContext
(
'getDeviceById'
,
()
async
{
testUsingContext
(
'getDeviceById
exact matcher
'
,
()
async
{
final
FakeDevice
device1
=
FakeDevice
(
'Nexus 5'
,
'0553790d0a4e726f'
);
final
FakeDevice
device2
=
FakeDevice
(
'Nexus 5X'
,
'01abfc49119c410e'
);
final
FakeDevice
device3
=
FakeDevice
(
'iPod touch'
,
'82564b38861a9a5'
);
final
List
<
Device
>
devices
=
<
Device
>[
device1
,
device2
,
device3
];
final
DeviceManager
deviceManager
=
TestDeviceManager
(
devices
);
// Include different device discoveries:
// 1. One that never completes to prove the first exact match is
// returned quickly.
// 2. One that throws, to prove matches can return when some succeed
// and others fail.
// 3. A device discoverer that succeeds.
final
DeviceManager
deviceManager
=
TestDeviceManager
(
devices
,
testLongPollingDeviceDiscovery:
true
,
testThrowingDeviceDiscovery:
true
,
);
Future
<
void
>
expectDevice
(
String
id
,
List
<
Device
>
expected
)
async
{
expect
(
await
deviceManager
.
getDevicesById
(
id
),
expected
);
}
await
expectDevice
(
'01abfc49119c410e'
,
<
Device
>[
device2
]);
expect
(
logger
.
traceText
,
contains
(
'Ignored error discovering 01abfc49119c410e'
));
await
expectDevice
(
'Nexus 5X'
,
<
Device
>[
device2
]);
expect
(
logger
.
traceText
,
contains
(
'Ignored error discovering Nexus 5X'
));
await
expectDevice
(
'0553790d0a4e726f'
,
<
Device
>[
device1
]);
expect
(
logger
.
traceText
,
contains
(
'Ignored error discovering 0553790d0a4e726f'
));
},
overrides:
<
Type
,
Generator
>{
Artifacts:
()
=>
Artifacts
.
test
(),
Cache:
()
=>
cache
,
Logger:
()
=>
logger
,
});
testUsingContext
(
'getDeviceById prefix matcher'
,
()
async
{
final
FakeDevice
device1
=
FakeDevice
(
'Nexus 5'
,
'0553790d0a4e726f'
);
final
FakeDevice
device2
=
FakeDevice
(
'Nexus 5X'
,
'01abfc49119c410e'
);
final
FakeDevice
device3
=
FakeDevice
(
'iPod touch'
,
'82564b38861a9a5'
);
final
List
<
Device
>
devices
=
<
Device
>[
device1
,
device2
,
device3
];
// Include different device discoveries:
// 1. One that throws, to prove matches can return when some succeed
// and others fail.
// 2. A device discoverer that succeeds.
final
DeviceManager
deviceManager
=
TestDeviceManager
(
devices
,
testThrowingDeviceDiscovery:
true
);
Future
<
void
>
expectDevice
(
String
id
,
List
<
Device
>
expected
)
async
{
expect
(
await
deviceManager
.
getDevicesById
(
id
),
expected
);
}
await
expectDevice
(
'Nexus 5'
,
<
Device
>[
device1
]);
expect
(
logger
.
traceText
,
contains
(
'Ignored error discovering Nexus 5'
));
await
expectDevice
(
'0553790'
,
<
Device
>[
device1
]);
expect
(
logger
.
traceText
,
contains
(
'Ignored error discovering 0553790'
));
await
expectDevice
(
'Nexus'
,
<
Device
>[
device1
,
device2
]);
expect
(
logger
.
traceText
,
contains
(
'Ignored error discovering Nexus'
));
},
overrides:
<
Type
,
Generator
>{
Artifacts:
()
=>
Artifacts
.
test
(),
Cache:
()
=>
cache
,
Logger:
()
=>
logger
,
});
testUsingContext
(
'getAllConnectedDevices caches'
,
()
async
{
...
...
@@ -374,16 +419,27 @@ void main() {
}
class
TestDeviceManager
extends
DeviceManager
{
TestDeviceManager
(
List
<
Device
>
allDevices
)
{
_deviceDiscoverer
=
FakePollingDeviceDiscovery
();
TestDeviceManager
(
List
<
Device
>
allDevices
,
{
bool
testLongPollingDeviceDiscovery
=
false
,
bool
testThrowingDeviceDiscovery
=
false
,
})
{
_fakeDeviceDiscoverer
=
FakePollingDeviceDiscovery
();
_deviceDiscoverers
=
<
DeviceDiscovery
>[
if
(
testLongPollingDeviceDiscovery
)
LongPollingDeviceDiscovery
(),
if
(
testThrowingDeviceDiscovery
)
ThrowingPollingDeviceDiscovery
(),
_fakeDeviceDiscoverer
,
];
resetDevices
(
allDevices
);
}
@override
List
<
DeviceDiscovery
>
get
deviceDiscoverers
=>
<
DeviceDiscovery
>[
_deviceDiscoverer
];
FakePollingDeviceDiscovery
_deviceDiscoverer
;
List
<
DeviceDiscovery
>
get
deviceDiscoverers
=>
_deviceDiscoverers
;
List
<
DeviceDiscovery
>
_deviceDiscoverers
;
FakePollingDeviceDiscovery
_fakeDeviceDiscoverer
;
void
resetDevices
(
List
<
Device
>
allDevices
)
{
_
d
eviceDiscoverer
.
setDevices
(
allDevices
);
_
fakeD
eviceDiscoverer
.
setDevices
(
allDevices
);
}
bool
isAlwaysSupportedOverride
;
...
...
packages/flutter_tools/test/src/mocks.dart
View file @
f9499f44
...
...
@@ -526,6 +526,48 @@ class FakePollingDeviceDiscovery extends PollingDeviceDiscovery {
Stream
<
Device
>
get
onRemoved
=>
_onRemovedController
.
stream
;
}
class
LongPollingDeviceDiscovery
extends
PollingDeviceDiscovery
{
LongPollingDeviceDiscovery
()
:
super
(
'forever'
);
final
Completer
<
List
<
Device
>>
_completer
=
Completer
<
List
<
Device
>>();
@override
Future
<
List
<
Device
>>
pollingGetDevices
({
Duration
timeout
})
async
{
return
_completer
.
future
;
}
@override
Future
<
void
>
stopPolling
()
async
{
_completer
.
complete
();
}
@override
Future
<
void
>
dispose
()
async
{
_completer
.
complete
();
}
@override
bool
get
supportsPlatform
=>
true
;
@override
bool
get
canListAnything
=>
true
;
}
class
ThrowingPollingDeviceDiscovery
extends
PollingDeviceDiscovery
{
ThrowingPollingDeviceDiscovery
()
:
super
(
'throw'
);
@override
Future
<
List
<
Device
>>
pollingGetDevices
({
Duration
timeout
})
async
{
throw
const
ProcessException
(
'fake-discovery'
,
<
String
>[]);
}
@override
bool
get
supportsPlatform
=>
true
;
@override
bool
get
canListAnything
=>
true
;
}
class
MockIosProject
extends
Mock
implements
IosProject
{
static
const
String
bundleId
=
'com.example.test'
;
static
const
String
appBundleName
=
'My Super Awesome App.app'
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment