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
3b6d84b0
Commit
3b6d84b0
authored
Jun 16, 2017
by
Yegor
Committed by
GitHub
Jun 16, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
modernize iOS device lookup in driver (#10780)
parent
b474557e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
25 additions
and
210 deletions
+25
-210
drive.dart
packages/flutter_tools/lib/src/commands/drive.dart
+7
-51
simulators.dart
packages/flutter_tools/lib/src/ios/simulators.dart
+0
-113
drive_test.dart
packages/flutter_tools/test/commands/drive_test.dart
+18
-46
No files found.
packages/flutter_tools/lib/src/commands/drive.dart
View file @
3b6d84b0
...
...
@@ -4,11 +4,9 @@
import
'dart:async'
;
import
'../android/android_device.dart'
show
AndroidDevice
;
import
'../application_package.dart'
;
import
'../base/common.dart'
;
import
'../base/file_system.dart'
;
import
'../base/platform.dart'
;
import
'../base/process.dart'
;
import
'../build_info.dart'
;
import
'../cache.dart'
;
...
...
@@ -16,7 +14,6 @@ import '../dart/package_map.dart';
import
'../dart/sdk.dart'
;
import
'../device.dart'
;
import
'../globals.dart'
;
import
'../ios/simulators.dart'
show
SimControl
,
IOSSimulatorUtils
;
import
'../resident_runner.dart'
;
import
'run.dart'
;
...
...
@@ -198,56 +195,15 @@ Future<Device> findTargetDevice() async {
return
devices
.
first
;
}
if
(
platform
.
isMacOS
)
{
// On Mac we look for the iOS Simulator. If available, we use that. Then
// we look for an Android device. If there's one, we use that. Otherwise,
// we launch a new iOS Simulator.
Device
reusableDevice
;
for
(
Device
device
in
devices
)
{
if
(
await
device
.
isLocalEmulator
)
{
reusableDevice
=
device
;
break
;
}
}
if
(
reusableDevice
==
null
)
{
for
(
Device
device
in
devices
)
{
if
(
device
is
AndroidDevice
)
{
reusableDevice
=
device
;
break
;
}
}
}
if
(
reusableDevice
!=
null
)
{
printStatus
(
'Found connected
${await reusableDevice.isLocalEmulator ? "emulator" : "device"}
"
${reusableDevice.name}
"; will reuse it.'
);
return
reusableDevice
;
}
// No running emulator found. Attempt to start one.
printStatus
(
'Starting iOS Simulator, because did not find existing connected devices.'
);
final
bool
started
=
await
SimControl
.
instance
.
boot
();
if
(
started
)
{
return
IOSSimulatorUtils
.
instance
.
getAttachedDevices
().
first
;
}
else
{
printError
(
'Failed to start iOS Simulator.'
);
return
null
;
}
}
else
if
(
platform
.
isLinux
||
platform
.
isWindows
)
{
// On Linux and Windows, for now, we just grab the first connected device we can find.
if
(
devices
.
isEmpty
)
{
printError
(
'No devices found.'
);
return
null
;
}
else
if
(
devices
.
length
>
1
)
{
printStatus
(
'Found multiple connected devices:'
);
printStatus
(
devices
.
map
((
Device
d
)
=>
' -
${d.name}
\n
'
).
join
(
''
));
}
printStatus
(
'Using device
${devices.first.name}
.'
);
return
devices
.
first
;
}
else
{
printError
(
'The operating system on this computer is not supported.'
);
if
(
devices
.
isEmpty
)
{
printError
(
'No devices found.'
);
return
null
;
}
else
if
(
devices
.
length
>
1
)
{
printStatus
(
'Found multiple connected devices:'
);
printStatus
(
devices
.
map
((
Device
d
)
=>
' -
${d.name}
\n
'
).
join
(
''
));
}
printStatus
(
'Using device
${devices.first.name}
.'
);
return
devices
.
first
;
}
/// Starts the application on the device given command configuration.
...
...
packages/flutter_tools/lib/src/ios/simulators.dart
View file @
3b6d84b0
...
...
@@ -59,117 +59,6 @@ class SimControl {
/// Returns [SimControl] active in the current app context (i.e. zone).
static
SimControl
get
instance
=>
context
[
SimControl
];
Future
<
bool
>
boot
({
String
deviceName
})
async
{
if
(
_isAnyConnected
())
return
true
;
if
(
deviceName
==
null
)
{
final
SimDevice
testDevice
=
_createTestDevice
();
if
(
testDevice
==
null
)
{
return
false
;
}
deviceName
=
testDevice
.
name
;
}
// `xcrun instruments` requires a template (-t). @yjbanov has no idea what
// "template" is but the built-in 'Blank' seems to work. -l causes xcrun to
// quit after a time limit without killing the simulator. We quit after
// 1 second.
final
List
<
String
>
args
=
<
String
>[
_xcrunPath
,
'instruments'
,
'-w'
,
deviceName
,
'-t'
,
'Blank'
,
'-l'
,
'1'
];
printTrace
(
args
.
join
(
' '
));
runDetached
(
args
);
printStatus
(
'Waiting for iOS Simulator to boot...'
);
bool
connected
=
false
;
int
attempted
=
0
;
while
(!
connected
&&
attempted
<
20
)
{
connected
=
_isAnyConnected
();
if
(!
connected
)
{
printStatus
(
'Still waiting for iOS Simulator to boot...'
);
await
new
Future
<
Null
>.
delayed
(
const
Duration
(
seconds:
1
));
}
attempted
++;
}
if
(
connected
)
{
printStatus
(
'Connected to iOS Simulator.'
);
return
true
;
}
else
{
printStatus
(
'Timed out waiting for iOS Simulator to boot.'
);
return
false
;
}
}
SimDevice
_createTestDevice
()
{
final
SimDeviceType
deviceType
=
_findSuitableDeviceType
();
if
(
deviceType
==
null
)
return
null
;
final
String
runtime
=
_findSuitableRuntime
();
if
(
runtime
==
null
)
return
null
;
// Delete any old test devices
getDevices
()
.
where
((
SimDevice
d
)
=>
d
.
name
.
endsWith
(
_kFlutterTestDeviceSuffix
))
.
forEach
(
_deleteDevice
);
// Create new device
final
String
deviceName
=
'
${deviceType.name}
$_kFlutterTestDeviceSuffix
'
;
final
List
<
String
>
args
=
<
String
>[
_xcrunPath
,
'simctl'
,
'create'
,
deviceName
,
deviceType
.
identifier
,
runtime
];
printTrace
(
args
.
join
(
' '
));
runCheckedSync
(
args
);
return
getDevices
().
firstWhere
((
SimDevice
d
)
=>
d
.
name
==
deviceName
);
}
SimDeviceType
_findSuitableDeviceType
()
{
final
List
<
Map
<
String
,
dynamic
>>
allTypes
=
_list
(
SimControlListSection
.
devicetypes
);
final
List
<
Map
<
String
,
dynamic
>>
usableTypes
=
allTypes
.
where
((
Map
<
String
,
dynamic
>
info
)
=>
info
[
'name'
].
startsWith
(
'iPhone'
))
.
toList
()
..
sort
((
Map
<
String
,
dynamic
>
r1
,
Map
<
String
,
dynamic
>
r2
)
=>
-
compareIphoneVersions
(
r1
[
'identifier'
],
r2
[
'identifier'
]));
if
(
usableTypes
.
isEmpty
)
{
printError
(
'No suitable device type found.
\n
'
'You may launch an iOS Simulator manually and Flutter will attempt to use it.'
);
}
return
new
SimDeviceType
(
usableTypes
.
first
[
'name'
],
usableTypes
.
first
[
'identifier'
]
);
}
String
_findSuitableRuntime
()
{
final
List
<
Map
<
String
,
dynamic
>>
allRuntimes
=
_list
(
SimControlListSection
.
runtimes
);
final
List
<
Map
<
String
,
dynamic
>>
usableRuntimes
=
allRuntimes
.
where
((
Map
<
String
,
dynamic
>
info
)
=>
info
[
'name'
].
startsWith
(
'iOS'
))
.
toList
()
..
sort
((
Map
<
String
,
dynamic
>
r1
,
Map
<
String
,
dynamic
>
r2
)
=>
-
compareIosVersions
(
r1
[
'version'
],
r2
[
'version'
]));
if
(
usableRuntimes
.
isEmpty
)
{
printError
(
'No suitable iOS runtime found.
\n
'
'You may launch an iOS Simulator manually and Flutter will attempt to use it.'
);
}
return
usableRuntimes
.
first
[
'identifier'
];
}
void
_deleteDevice
(
SimDevice
device
)
{
try
{
final
List
<
String
>
args
=
<
String
>[
_xcrunPath
,
'simctl'
,
'delete'
,
device
.
name
];
printTrace
(
args
.
join
(
' '
));
runCheckedSync
(
args
);
}
catch
(
e
)
{
printError
(
e
);
}
}
/// Runs `simctl list --json` and returns the JSON of the corresponding
/// [section].
///
...
...
@@ -226,8 +115,6 @@ class SimControl {
return
getDevices
().
where
((
SimDevice
device
)
=>
device
.
isBooted
).
toList
();
}
bool
_isAnyConnected
()
=>
getConnectedDevices
().
isNotEmpty
;
Future
<
bool
>
isInstalled
(
String
deviceId
,
String
appId
)
{
return
exitsHappyAsync
(<
String
>[
_xcrunPath
,
...
...
packages/flutter_tools/test/commands/drive_test.dart
View file @
3b6d84b0
...
...
@@ -13,7 +13,6 @@ import 'package:flutter_tools/src/base/platform.dart';
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/drive.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/ios/simulators.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:test/test.dart'
;
...
...
@@ -238,52 +237,7 @@ void main() {
});
});
group
(
'findTargetDevice on iOS'
,
()
{
Platform
macOsPlatform
()
=>
new
FakePlatform
(
operatingSystem:
'macos'
);
testUsingContext
(
'uses existing emulator'
,
()
async
{
withMockDevice
();
when
(
mockDevice
.
name
).
thenReturn
(
'mock-simulator'
);
when
(
mockDevice
.
isLocalEmulator
).
thenReturn
(
new
Future
<
bool
>.
value
(
true
));
final
Device
device
=
await
findTargetDevice
();
expect
(
device
.
name
,
'mock-simulator'
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
Platform:
macOsPlatform
,
});
testUsingContext
(
'uses existing Android device if and there are no simulators'
,
()
async
{
mockDevice
=
new
MockAndroidDevice
();
when
(
mockDevice
.
name
).
thenReturn
(
'mock-android-device'
);
when
(
mockDevice
.
isLocalEmulator
).
thenReturn
(
new
Future
<
bool
>.
value
(
false
));
withMockDevice
(
mockDevice
);
final
Device
device
=
await
findTargetDevice
();
expect
(
device
.
name
,
'mock-android-device'
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
Platform:
macOsPlatform
,
});
testUsingContext
(
'launches emulator'
,
()
async
{
when
(
SimControl
.
instance
.
boot
()).
thenReturn
(
true
);
final
Device
emulator
=
new
MockDevice
();
when
(
emulator
.
name
).
thenReturn
(
'new-simulator'
);
when
(
IOSSimulatorUtils
.
instance
.
getAttachedDevices
())
.
thenReturn
(<
Device
>[
emulator
]);
final
Device
device
=
await
findTargetDevice
();
expect
(
device
.
name
,
'new-simulator'
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
Platform:
macOsPlatform
,
});
});
void
findTargetDeviceOnOperatingSystem
(
String
operatingSystem
)
{
assert
(
operatingSystem
==
'windows'
||
operatingSystem
==
'linux'
);
Platform
platform
()
=>
new
FakePlatform
(
operatingSystem:
operatingSystem
);
testUsingContext
(
'returns null if no devices found'
,
()
async
{
...
...
@@ -313,6 +267,24 @@ void main() {
group
(
'findTargetDevice on Windows'
,
()
{
findTargetDeviceOnOperatingSystem
(
'windows'
);
});
group
(
'findTargetDevice on macOS'
,
()
{
findTargetDeviceOnOperatingSystem
(
'macos'
);
Platform
macOsPlatform
()
=>
new
FakePlatform
(
operatingSystem:
'macos'
);
testUsingContext
(
'uses existing simulator'
,
()
async
{
withMockDevice
();
when
(
mockDevice
.
name
).
thenReturn
(
'mock-simulator'
);
when
(
mockDevice
.
isLocalEmulator
).
thenReturn
(
new
Future
<
bool
>.
value
(
true
));
final
Device
device
=
await
findTargetDevice
();
expect
(
device
.
name
,
'mock-simulator'
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
Platform:
macOsPlatform
,
});
});
});
}
...
...
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