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
dcf0b7ba
Commit
dcf0b7ba
authored
Feb 13, 2016
by
Devon Carew
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
allow any android sdk version
parent
5a167615
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
426 additions
and
220 deletions
+426
-220
android_sdk.dart
packages/flutter_tools/lib/src/android/android_sdk.dart
+214
-0
device_android.dart
packages/flutter_tools/lib/src/android/device_android.dart
+28
-91
context.dart
packages/flutter_tools/lib/src/base/context.dart
+8
-0
globals.dart
packages/flutter_tools/lib/src/base/globals.dart
+2
-0
os.dart
packages/flutter_tools/lib/src/base/os.dart
+18
-0
apk.dart
packages/flutter_tools/lib/src/commands/apk.dart
+31
-47
daemon.dart
packages/flutter_tools/lib/src/commands/daemon.dart
+1
-0
refresh.dart
packages/flutter_tools/lib/src/commands/refresh.dart
+1
-1
trace.dart
packages/flutter_tools/lib/src/commands/trace.dart
+1
-1
device_ios.dart
packages/flutter_tools/lib/src/ios/device_ios.dart
+2
-0
flutter_command_runner.dart
.../flutter_tools/lib/src/runner/flutter_command_runner.dart
+18
-0
services.dart
packages/flutter_tools/lib/src/services.dart
+6
-5
pubspec.yaml
packages/flutter_tools/pubspec.yaml
+1
-0
android_device_test.dart
packages/flutter_tools/test/android_device_test.dart
+1
-1
create_test.dart
packages/flutter_tools/test/create_test.dart
+1
-1
daemon_test.dart
packages/flutter_tools/test/daemon_test.dart
+15
-9
device_test.dart
packages/flutter_tools/test/device_test.dart
+1
-1
install_test.dart
packages/flutter_tools/test/install_test.dart
+10
-10
list_test.dart
packages/flutter_tools/test/list_test.dart
+17
-26
listen_test.dart
packages/flutter_tools/test/listen_test.dart
+5
-5
logs_test.dart
packages/flutter_tools/test/logs_test.dart
+3
-5
common.dart
packages/flutter_tools/test/src/common.dart
+11
-0
context.dart
packages/flutter_tools/test/src/context.dart
+16
-3
stop_test.dart
packages/flutter_tools/test/stop_test.dart
+10
-9
trace_test.dart
packages/flutter_tools/test/trace_test.dart
+5
-5
No files found.
packages/flutter_tools/lib/src/android/android_sdk.dart
0 → 100644
View file @
dcf0b7ba
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:io'
;
import
'package:path/path.dart'
as
path
;
import
'package:pub_semver/pub_semver.dart'
;
import
'../base/globals.dart'
;
import
'../base/os.dart'
;
// Android SDK layout:
//
// $ANDROID_HOME/platform-tools/adb
// $ANDROID_HOME/build-tools/19.1.0/aapt, dx, zipalign
// $ANDROID_HOME/build-tools/22.0.1/aapt
// $ANDROID_HOME/build-tools/23.0.2/aapt
// $ANDROID_HOME/platforms/android-22/android.jar
// $ANDROID_HOME/platforms/android-23/android.jar
// TODO(devoncarew): We need a way to locate the Android SDK w/o using an environment variable.
// Perhaps something like `flutter config --android-home=foo/bar`.
/// Locate ADB. Prefer to use one from an Android SDK, if we can locate that.
String
getAdbPath
(
)
{
AndroidSdk
sdk
=
AndroidSdk
.
locateAndroidSdk
();
if
(
sdk
?.
latestVersion
==
null
)
{
return
os
.
which
(
'adb'
)?.
path
;
}
else
{
return
sdk
.
adbPath
;
}
}
class
AndroidSdk
{
AndroidSdk
(
this
.
directory
)
{
_init
();
}
final
String
directory
;
List
<
AndroidSdkVersion
>
_sdkVersions
;
AndroidSdkVersion
_latestVersion
;
static
AndroidSdk
locateAndroidSdk
()
{
// TODO: Use explicit configuration information from a metadata file?
if
(
Platform
.
environment
.
containsKey
(
'ANDROID_HOME'
))
{
String
homeDir
=
Platform
.
environment
[
'ANDROID_HOME'
];
if
(
validSdkDirectory
(
homeDir
))
return
new
AndroidSdk
(
homeDir
);
if
(
validSdkDirectory
(
path
.
join
(
homeDir
,
'sdk'
)))
return
new
AndroidSdk
(
path
.
join
(
homeDir
,
'sdk'
));
}
File
aaptBin
=
os
.
which
(
'aapt'
);
// in build-tools/$version/aapt
if
(
aaptBin
!=
null
)
{
String
dir
=
aaptBin
.
parent
.
parent
.
parent
.
path
;
if
(
validSdkDirectory
(
dir
))
return
new
AndroidSdk
(
dir
);
}
File
adbBin
=
os
.
which
(
'adb'
);
// in platform-tools/adb
if
(
adbBin
!=
null
)
{
String
dir
=
adbBin
.
parent
.
parent
.
path
;
if
(
validSdkDirectory
(
dir
))
return
new
AndroidSdk
(
dir
);
}
// No dice.
printTrace
(
'Unable to locate an Android SDK.'
);
return
null
;
}
static
bool
validSdkDirectory
(
String
dir
)
{
return
FileSystemEntity
.
isDirectorySync
(
path
.
join
(
dir
,
'platform-tools'
));
}
List
<
AndroidSdkVersion
>
get
sdkVersions
=>
_sdkVersions
;
AndroidSdkVersion
get
latestVersion
=>
_latestVersion
;
String
get
adbPath
=>
getPlatformToolsPath
(
'adb'
);
bool
validateSdkWellFormed
({
bool
complain:
false
})
{
if
(!
FileSystemEntity
.
isFileSync
(
adbPath
))
{
if
(
complain
)
printError
(
'Android SDK file not found:
$adbPath
.'
);
return
false
;
}
if
(
sdkVersions
.
isEmpty
)
{
if
(
complain
)
printError
(
'Android SDK does not have the proper build-tools.'
);
return
false
;
}
return
latestVersion
.
validateSdkWellFormed
(
complain:
complain
);
}
String
getPlatformToolsPath
(
String
binaryName
)
{
return
path
.
join
(
directory
,
'platform-tools'
,
binaryName
);
}
void
_init
()
{
List
<
String
>
platforms
=
<
String
>[];
// android-22, ...
Directory
platformsDir
=
new
Directory
(
path
.
join
(
directory
,
'platforms'
));
if
(
platformsDir
.
existsSync
())
{
platforms
=
platformsDir
.
listSync
()
.
map
((
FileSystemEntity
entity
)
=>
path
.
basename
(
entity
.
path
))
.
where
((
String
name
)
=>
name
.
startsWith
(
'android-'
))
.
toList
();
}
List
<
Version
>
buildToolsVersions
=
<
Version
>[];
// 19.1.0, 22.0.1, ...
Directory
buildToolsDir
=
new
Directory
(
path
.
join
(
directory
,
'build-tools'
));
if
(
buildToolsDir
.
existsSync
())
{
buildToolsVersions
=
buildToolsDir
.
listSync
()
.
map
((
FileSystemEntity
entity
)
{
try
{
return
new
Version
.
parse
(
path
.
basename
(
entity
.
path
));
}
catch
(
error
)
{
return
null
;
}
})
.
where
((
Version
version
)
=>
version
!=
null
)
.
toList
();
}
// Here we match up platforms with cooresponding build-tools. If we don't
// have a match, we don't return anything for that platform version. So if
// the user only have 'android-22' and 'build-tools/19.0.0', we don't find
// an Android sdk.
_sdkVersions
=
platforms
.
map
((
String
platform
)
{
int
sdkVersion
;
try
{
sdkVersion
=
int
.
parse
(
platform
.
substring
(
'android-'
.
length
));
}
catch
(
error
)
{
return
null
;
}
Version
buildToolsVersion
=
Version
.
primary
(
buildToolsVersions
.
where
((
Version
version
)
{
return
version
.
major
==
sdkVersion
;
}).
toList
());
if
(
buildToolsVersion
==
null
)
return
null
;
return
new
AndroidSdkVersion
(
this
,
platform
,
buildToolsVersion
.
toString
());
}).
where
((
AndroidSdkVersion
version
)
=>
version
!=
null
).
toList
();
_sdkVersions
.
sort
();
_latestVersion
=
_sdkVersions
.
isEmpty
?
null
:
_sdkVersions
.
last
;
}
String
toString
()
=>
'AndroidSdk:
$directory
'
;
}
class
AndroidSdkVersion
implements
Comparable
<
AndroidSdkVersion
>
{
AndroidSdkVersion
(
this
.
sdk
,
this
.
androidVersion
,
this
.
buildToolsVersion
);
final
AndroidSdk
sdk
;
final
String
androidVersion
;
final
String
buildToolsVersion
;
int
get
sdkLevel
=>
int
.
parse
(
androidVersion
.
substring
(
'android-'
.
length
));
String
get
androidJarPath
=>
getPlatformsPath
(
'android.jar'
);
String
get
aaptPath
=>
getBuildToolsPath
(
'aapt'
);
String
get
dxPath
=>
getBuildToolsPath
(
'dx'
);
String
get
zipalignPath
=>
getBuildToolsPath
(
'zipalign'
);
bool
validateSdkWellFormed
({
bool
complain:
false
})
{
return
_exists
(
androidJarPath
,
complain:
complain
)
&&
_exists
(
aaptPath
,
complain:
complain
)
&&
_exists
(
dxPath
,
complain:
complain
)
&&
_exists
(
zipalignPath
,
complain:
complain
);
}
String
getPlatformsPath
(
String
itemName
)
{
return
path
.
join
(
sdk
.
directory
,
'platforms'
,
androidVersion
,
itemName
);
}
String
getBuildToolsPath
(
String
binaryName
)
{
return
path
.
join
(
sdk
.
directory
,
'build-tools'
,
buildToolsVersion
,
binaryName
);
}
int
compareTo
(
AndroidSdkVersion
other
)
{
return
sdkLevel
-
other
.
sdkLevel
;
}
String
toString
()
=>
'[
${sdk.directory}
, SDK version
$sdkLevel
, build-tools
$buildToolsVersion
]'
;
bool
_exists
(
String
path
,
{
bool
complain:
false
})
{
if
(!
FileSystemEntity
.
isFileSync
(
path
))
{
if
(
complain
)
printError
(
'Android SDK file not found:
$path
.'
);
return
false
;
}
return
true
;
}
}
packages/flutter_tools/lib/src/android/device_android.dart
View file @
dcf0b7ba
...
...
@@ -50,18 +50,6 @@ class AndroidDevice extends Device {
})
:
super
(
id
)
{
if
(
connected
!=
null
)
_connected
=
connected
;
_adbPath
=
getAdbPath
();
_hasAdb
=
_checkForAdb
();
// Checking for [minApiName] only needs to be done if we are starting an
// app, but it has an important side effect, which is to discard any
// progress messages if the adb server is restarted.
_hasValidAndroid
=
_checkForSupportedAndroidVersion
();
if
(!
_hasAdb
||
!
_hasValidAndroid
)
{
printError
(
'Unable to run on Android.'
);
}
}
final
String
productID
;
...
...
@@ -69,32 +57,9 @@ class AndroidDevice extends Device {
final
String
deviceCodeName
;
bool
_connected
;
String
_adbPath
;
String
get
adbPath
=>
_adbPath
;
bool
_hasAdb
=
false
;
bool
_hasValidAndroid
=
false
;
static
String
getAndroidSdkPath
()
{
if
(
Platform
.
environment
.
containsKey
(
'ANDROID_HOME'
))
{
String
androidHomeDir
=
Platform
.
environment
[
'ANDROID_HOME'
];
if
(
FileSystemEntity
.
isDirectorySync
(
path
.
join
(
androidHomeDir
,
'platform-tools'
)))
{
return
androidHomeDir
;
}
else
if
(
FileSystemEntity
.
isDirectorySync
(
path
.
join
(
androidHomeDir
,
'sdk'
,
'platform-tools'
)))
{
return
path
.
join
(
androidHomeDir
,
'sdk'
);
}
else
{
printError
(
'Android SDK not found at
$androidHomeDir
'
);
return
null
;
}
}
else
{
printError
(
'Android SDK not found. The ANDROID_HOME variable must be set.'
);
return
null
;
}
}
List
<
String
>
adbCommandForDevice
(
List
<
String
>
args
)
{
return
<
String
>[
adbPath
,
'-s'
,
id
]..
addAll
(
args
);
return
<
String
>[
a
ndroidSdk
.
a
dbPath
,
'-s'
,
id
]..
addAll
(
args
);
}
bool
_isValidAdbVersion
(
String
adbVersion
)
{
...
...
@@ -121,24 +86,19 @@ class AndroidDevice extends Device {
return
true
;
}
bool
_checkForAdb
()
{
bool
_checkForSupportedAdbVersion
()
{
if
(
androidSdk
==
null
)
return
false
;
try
{
String
adbVersion
=
runCheckedSync
(<
String
>[
adbPath
,
'version'
]);
if
(
_isValidAdbVersion
(
adbVersion
))
{
String
adbVersion
=
runCheckedSync
(<
String
>[
a
ndroidSdk
.
a
dbPath
,
'version'
]);
if
(
_isValidAdbVersion
(
adbVersion
))
return
true
;
}
String
locatedAdbPath
=
runCheckedSync
(<
String
>[
'which'
,
'adb'
]);
printError
(
'"
$locatedAdbPath
" is too old. '
'Please install version 1.0.32 or later.
\n
'
'Try setting ANDROID_HOME to the path to your Android SDK install. '
'Android builds are unavailable.'
);
}
catch
(
e
)
{
printError
(
'"adb" not found in
\
$PATH
. '
'Please install the Android SDK or set ANDROID_HOME '
'to the path of your Android SDK install.'
);
printTrace
(
'
$e
'
);
printError
(
'The ADB at "
${androidSdk.adbPath}
" is too old; please install version 1.0.32 or later.'
);
}
catch
(
error
,
trace
)
{
printError
(
'Error running ADB:
$error
'
,
trace
);
}
return
false
;
}
...
...
@@ -150,34 +110,29 @@ class AndroidDevice extends Device {
// * daemon started successfully *
runCheckedSync
(
adbCommandForDevice
(<
String
>[
'start-server'
]));
String
ready
=
runSync
(
adbCommandForDevice
(<
String
>[
'shell'
,
'echo'
,
'ready'
]));
if
(
ready
.
trim
()
!=
'ready'
)
{
printTrace
(
'Android device not found.'
);
return
false
;
}
// Sample output: '22'
String
sdkVersion
=
runCheckedSync
(
adbCommandForDevice
(<
String
>[
'shell'
,
'getprop'
,
'ro.build.version.sdk'
])
).
trimRight
();
int
sdkVersionParsed
=
int
.
parse
(
sdkVersion
,
onError:
(
String
source
)
=>
null
);
int
sdkVersionParsed
=
int
.
parse
(
sdkVersion
,
onError:
(
String
source
)
=>
null
);
if
(
sdkVersionParsed
==
null
)
{
printError
(
'Unexpected response from getprop: "
$sdkVersion
"'
);
return
false
;
}
if
(
sdkVersionParsed
<
minApiLevel
)
{
printError
(
'The Android version (
$sdkVersion
) on the target device is too old. Please '
'use a
$minVersionName
(version
$minApiLevel
/
$minVersionText
) device or later.'
);
return
false
;
}
return
true
;
}
catch
(
e
)
{
printError
(
'Unexpected failure from adb:
$e
'
);
return
false
;
}
return
false
;
}
String
_getDeviceSha1Path
(
ApplicationPackage
app
)
{
...
...
@@ -220,11 +175,15 @@ class AndroidDevice extends Device {
printTrace
(
'Android device not connected. Not installing.'
);
return
false
;
}
if
(!
FileSystemEntity
.
isFileSync
(
app
.
localPath
))
{
printError
(
'"
${app.localPath}
" does not exist.'
);
return
false
;
}
if
(!
_checkForSupportedAdbVersion
()
||
!
_checkForSupportedAndroidVersion
())
return
false
;
printStatus
(
'Installing
${app.name}
on device.'
);
runCheckedSync
(
adbCommandForDevice
(<
String
>[
'install'
,
'-r'
,
app
.
localPath
]));
runCheckedSync
(
adbCommandForDevice
(<
String
>[
'shell'
,
'echo'
,
'-n'
,
_getSourceSha1
(
app
),
'>'
,
_getDeviceSha1Path
(
app
)]));
...
...
@@ -306,6 +265,9 @@ class AndroidDevice extends Device {
int
debugPort:
observatoryDefaultPort
,
Map
<
String
,
dynamic
>
platformArgs
})
async
{
if
(!
_checkForSupportedAdbVersion
()
||
!
_checkForSupportedAndroidVersion
())
return
false
;
flx
.
DirectoryResult
buildResult
=
await
flx
.
buildInTempDir
(
toolchain
,
mainPath:
mainPath
...
...
@@ -420,7 +382,7 @@ class AndroidDevice extends Device {
return
null
;
}
bool
isConnected
()
=>
_connected
??
_hasValidAndroid
;
bool
isConnected
()
=>
_connected
??
androidSdk
!=
null
;
void
setConnected
(
bool
value
)
{
_connected
=
value
;
...
...
@@ -447,18 +409,12 @@ class AndroidDevice extends Device {
}
}
/// The [mockAndroid] argument is only to facilitate testing with mocks, so that
/// we don't have to rely on the test setup having adb available to it.
List
<
AndroidDevice
>
getAdbDevices
([
AndroidDevice
mockAndroid
])
{
List
<
AndroidDevice
>
devices
=
[];
String
adbPath
=
(
mockAndroid
!=
null
)
?
mockAndroid
.
adbPath
:
getAdbPath
();
List
<
AndroidDevice
>
getAdbDevices
()
{
if
(
androidSdk
==
null
)
return
<
AndroidDevice
>[];
try
{
runCheckedSync
(<
String
>[
adbPath
,
'version'
]);
}
catch
(
e
)
{
printError
(
'Unable to find adb. Is "adb" in your path?'
);
return
devices
;
}
String
adbPath
=
androidSdk
.
adbPath
;
List
<
AndroidDevice
>
devices
=
[];
List
<
String
>
output
=
runSync
(<
String
>[
adbPath
,
'devices'
,
'-l'
]).
trim
().
split
(
'
\n
'
);
...
...
@@ -525,25 +481,6 @@ List<AndroidDevice> getAdbDevices([AndroidDevice mockAndroid]) {
return
devices
;
}
String
getAdbPath
(
)
{
if
(
Platform
.
environment
.
containsKey
(
'ANDROID_HOME'
))
{
String
androidHomeDir
=
Platform
.
environment
[
'ANDROID_HOME'
];
String
adbPath1
=
path
.
join
(
androidHomeDir
,
'sdk'
,
'platform-tools'
,
'adb'
);
String
adbPath2
=
path
.
join
(
androidHomeDir
,
'platform-tools'
,
'adb'
);
if
(
FileSystemEntity
.
isFileSync
(
adbPath1
))
{
return
adbPath1
;
}
else
if
(
FileSystemEntity
.
isFileSync
(
adbPath2
))
{
return
adbPath2
;
}
else
{
printTrace
(
'"adb" not found at
\n
"
$adbPath1
" or
\n
"
$adbPath2
"
\n
'
+
'using default path "
$_defaultAdbPath
"'
);
return
_defaultAdbPath
;
}
}
else
{
return
_defaultAdbPath
;
}
}
/// A log reader that logs from `adb logcat`. This will have the same output as
/// another copy of [_AdbLogReader], and the two instances will be equivalent.
class
_AdbLogReader
extends
DeviceLogReader
{
...
...
packages/flutter_tools/lib/src/base/context.dart
View file @
dcf0b7ba
...
...
@@ -16,6 +16,14 @@ AppContext get context {
class
AppContext
{
Map
<
Type
,
dynamic
>
_instances
=
<
Type
,
dynamic
>{};
bool
isSet
(
Type
type
)
{
if
(
_instances
.
containsKey
(
type
))
return
true
;
AppContext
parent
=
_calcParent
(
Zone
.
current
);
return
parent
!=
null
?
parent
.
isSet
(
type
)
:
false
;
}
dynamic
getVariable
(
Type
type
)
{
if
(
_instances
.
containsKey
(
type
))
return
_instances
[
type
];
...
...
packages/flutter_tools/lib/src/base/globals.dart
View file @
dcf0b7ba
...
...
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'../android/android_sdk.dart'
;
import
'../device.dart'
;
import
'context.dart'
;
import
'logger.dart'
;
DeviceManager
get
deviceManager
=>
context
[
DeviceManager
];
Logger
get
logger
=>
context
[
Logger
];
AndroidSdk
get
androidSdk
=>
context
[
AndroidSdk
];
/// Display an error level message to the user. Commands should use this if they
/// fail in some way.
...
...
packages/flutter_tools/lib/src/base/os.dart
View file @
dcf0b7ba
...
...
@@ -18,12 +18,26 @@ abstract class OperatingSystemUtils {
/// Make the given file executable. This may be a no-op on some platforms.
ProcessResult
makeExecutable
(
File
file
);
/// Return the path (with symlinks resolved) to the given executable, or `null`
/// if `which` was not able to locate the binary.
File
which
(
String
execName
);
}
class
_PosixUtils
implements
OperatingSystemUtils
{
ProcessResult
makeExecutable
(
File
file
)
{
return
Process
.
runSync
(
'chmod'
,
[
'u+x'
,
file
.
path
]);
}
/// Return the path (with symlinks resolved) to the given executable, or `null`
/// if `which` was not able to locate the binary.
File
which
(
String
execName
)
{
ProcessResult
result
=
Process
.
runSync
(
'which'
,
<
String
>[
execName
]);
if
(
result
.
exitCode
!=
0
)
return
null
;
String
path
=
result
.
stdout
.
trim
().
split
(
'
\n
'
).
first
.
trim
();
return
new
File
(
new
File
(
path
).
resolveSymbolicLinksSync
());
}
}
class
_WindowsUtils
implements
OperatingSystemUtils
{
...
...
@@ -31,6 +45,10 @@ class _WindowsUtils implements OperatingSystemUtils {
ProcessResult
makeExecutable
(
File
file
)
{
return
new
ProcessResult
(
0
,
0
,
null
,
null
);
}
File
which
(
String
execName
)
{
throw
new
UnimplementedError
(
'_WindowsUtils.which'
);
}
}
Future
<
int
>
findAvailablePort
()
async
{
...
...
packages/flutter_tools/lib/src/commands/apk.dart
View file @
dcf0b7ba
...
...
@@ -7,11 +7,12 @@ import 'dart:io';
import
'package:path/path.dart'
as
path
;
import
'../android/
device_android
.dart'
;
import
'../android/
android_sdk
.dart'
;
import
'../application_package.dart'
;
import
'../artifacts.dart'
;
import
'../base/file_system.dart'
;
import
'../base/globals.dart'
;
import
'../base/os.dart'
;
import
'../base/process.dart'
;
import
'../build_configuration.dart'
;
import
'../device.dart'
;
...
...
@@ -34,9 +35,6 @@ const String _kDebugKeystoreKeyAlias = "chromiumdebugkey";
// Password for the Chromium debug keystore
const
String
_kDebugKeystorePassword
=
"chromium"
;
const
String
_kAndroidPlatformVersion
=
'22'
;
const
String
_kBuildToolsVersion
=
'22.0.1'
;
/// Copies files into a new directory structure.
class
_AssetBuilder
{
final
Directory
outDir
;
...
...
@@ -59,30 +57,24 @@ class _AssetBuilder {
/// Builds an APK package using Android SDK tools.
class
_ApkBuilder
{
final
String
androidS
dk
;
final
AndroidSdkVersion
s
dk
;
File
_androidJar
;
File
_aapt
;
File
_dx
;
File
_zipalign
;
String
_jarsigner
;
_ApkBuilder
(
this
.
androidSdk
)
{
_androidJar
=
new
File
(
'
$androidSdk
/platforms/android-
$_kAndroidPlatformVersion
/android.jar'
);
String
buildTools
=
'
$androidSdk
/build-tools/
$_kBuildToolsVersion
'
;
_aapt
=
new
File
(
'
$buildTools
/aapt'
);
_dx
=
new
File
(
'
$buildTools
/dx'
);
_zipalign
=
new
File
(
'
$buildTools
/zipalign'
);
_jarsigner
=
'jarsigner'
;
}
bool
checkSdkPath
()
{
return
(
_androidJar
.
existsSync
()
&&
_aapt
.
existsSync
()
&&
_dx
.
existsSync
()
&&
_zipalign
.
existsSync
());
File
_jarsigner
;
_ApkBuilder
(
this
.
sdk
)
{
_androidJar
=
new
File
(
sdk
.
androidJarPath
);
_aapt
=
new
File
(
sdk
.
aaptPath
);
_dx
=
new
File
(
sdk
.
dxPath
);
_zipalign
=
new
File
(
sdk
.
zipalignPath
);
_jarsigner
=
os
.
which
(
'jarsigner'
);
}
void
compileClassesDex
(
File
classesDex
,
List
<
File
>
jars
)
{
List
<
String
>
packageArgs
=
[
_dx
.
path
,
List
<
String
>
packageArgs
=
<
String
>
[
_dx
.
path
,
'--dex'
,
'--force-jumbo'
,
'--output'
,
classesDex
.
path
...
...
@@ -94,7 +86,7 @@ class _ApkBuilder {
}
void
package
(
File
outputApk
,
File
androidManifest
,
Directory
assets
,
Directory
artifacts
,
Directory
resources
)
{
List
<
String
>
packageArgs
=
[
_aapt
.
path
,
List
<
String
>
packageArgs
=
<
String
>
[
_aapt
.
path
,
'package'
,
'-M'
,
androidManifest
.
path
,
'-A'
,
assets
.
path
,
...
...
@@ -109,7 +101,7 @@ class _ApkBuilder {
}
void
sign
(
File
keystore
,
String
keystorePassword
,
String
keyAlias
,
String
keyPassword
,
File
outputApk
)
{
runCheckedSync
(
[
_jarsigner
,
runCheckedSync
(
<
String
>[
_jarsigner
.
path
,
'-keystore'
,
keystore
.
path
,
'-storepass'
,
keystorePassword
,
'-keypass'
,
keyPassword
,
...
...
@@ -119,12 +111,11 @@ class _ApkBuilder {
}
void
align
(
File
unalignedApk
,
File
outputApk
)
{
runCheckedSync
([
_zipalign
.
path
,
'-f'
,
'4'
,
unalignedApk
.
path
,
outputApk
.
path
]);
runCheckedSync
(
<
String
>
[
_zipalign
.
path
,
'-f'
,
'4'
,
unalignedApk
.
path
,
outputApk
.
path
]);
}
}
class
_ApkComponents
{
Directory
androidSdk
;
File
manifest
;
File
icuData
;
List
<
File
>
jars
;
...
...
@@ -135,11 +126,12 @@ class _ApkComponents {
}
class
ApkKeystoreInfo
{
ApkKeystoreInfo
({
this
.
keystore
,
this
.
password
,
this
.
keyAlias
,
this
.
keyPassword
});
String
keystore
;
String
password
;
String
keyAlias
;
String
keyPassword
;
ApkKeystoreInfo
({
this
.
keystore
,
this
.
password
,
this
.
keyAlias
,
this
.
keyPassword
});
}
class
ApkCommand
extends
FlutterCommand
{
...
...
@@ -183,7 +175,19 @@ class ApkCommand extends FlutterCommand {
@override
Future
<
int
>
runInProject
()
async
{
// Validate that we can find an android sdk.
if
(
androidSdk
==
null
)
{
printError
(
'No Android SDK found.'
);
return
1
;
}
if
(!
androidSdk
.
validateSdkWellFormed
(
complain:
true
))
{
printError
(
'Try re-installing or updating your Android SDK.'
);
return
1
;
}
await
downloadToolchain
();
return
await
buildAndroid
(
toolchain:
toolchain
,
configs:
buildConfigurations
,
...
...
@@ -207,10 +211,8 @@ class ApkCommand extends FlutterCommand {
Future
<
_ApkComponents
>
_findApkComponents
(
BuildConfiguration
config
,
String
enginePath
,
String
manifest
,
String
resources
)
async
{
String
androidSdkPath
;
List
<
String
>
artifactPaths
;
if
(
enginePath
!=
null
)
{
androidSdkPath
=
'
$enginePath
/third_party/android_tools/sdk'
;
artifactPaths
=
[
'
$enginePath
/third_party/icu/android/icudtl.dat'
,
'
${config.buildDir}
/gen/sky/shell/shell/classes.dex.jar'
,
...
...
@@ -218,9 +220,6 @@ Future<_ApkComponents> _findApkComponents(
'
$enginePath
/build/android/ant/chromium-debug.keystore'
,
];
}
else
{
androidSdkPath
=
AndroidDevice
.
getAndroidSdkPath
();
if
(
androidSdkPath
==
null
)
return
null
;
List
<
ArtifactType
>
artifactTypes
=
<
ArtifactType
>[
ArtifactType
.
androidIcuData
,
ArtifactType
.
androidClassesJar
,
...
...
@@ -234,7 +233,6 @@ Future<_ApkComponents> _findApkComponents(
}
_ApkComponents
components
=
new
_ApkComponents
();
components
.
androidSdk
=
new
Directory
(
androidSdkPath
);
components
.
manifest
=
new
File
(
manifest
);
components
.
icuData
=
new
File
(
artifactPaths
[
0
]);
components
.
jars
=
[
new
File
(
artifactPaths
[
1
])];
...
...
@@ -242,11 +240,7 @@ Future<_ApkComponents> _findApkComponents(
components
.
debugKeystore
=
new
File
(
artifactPaths
[
3
]);
components
.
resources
=
new
Directory
(
resources
);
await
parseServiceConfigs
(
components
.
services
,
jars:
components
.
jars
,
androidSdk:
components
.
androidSdk
.
path
);
await
parseServiceConfigs
(
components
.
services
,
jars:
components
.
jars
);
if
(!
components
.
resources
.
existsSync
())
{
// TODO(eseidel): This level should be higher when path is manually set.
...
...
@@ -254,16 +248,6 @@ Future<_ApkComponents> _findApkComponents(
components
.
resources
=
null
;
}
if
(!
components
.
androidSdk
.
existsSync
())
{
printError
(
'Can not locate Android SDK:
$androidSdkPath
'
);
return
null
;
}
if
(!(
new
_ApkBuilder
(
components
.
androidSdk
.
path
).
checkSdkPath
()))
{
printError
(
'Can not locate expected Android SDK tools at
$androidSdkPath
'
);
printError
(
'You must install version
$_kAndroidPlatformVersion
of the SDK platform'
);
printError
(
'and version
$_kBuildToolsVersion
of the build tools.'
);
return
null
;
}
for
(
File
f
in
[
components
.
manifest
,
components
.
icuData
,
components
.
libSkyShell
,
components
.
debugKeystore
]..
addAll
(
components
.
jars
))
{
...
...
@@ -281,7 +265,7 @@ int _buildApk(
)
{
Directory
tempDir
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_tools'
);
try
{
_ApkBuilder
builder
=
new
_ApkBuilder
(
components
.
androidSdk
.
path
);
_ApkBuilder
builder
=
new
_ApkBuilder
(
androidSdk
.
latestVersion
);
File
classesDex
=
new
File
(
'
${tempDir.path}
/classes.dex'
);
builder
.
compileClassesDex
(
classesDex
,
components
.
jars
);
...
...
packages/flutter_tools/lib/src/commands/daemon.dart
View file @
dcf0b7ba
...
...
@@ -7,6 +7,7 @@ import 'dart:convert';
import
'dart:io'
;
import
'../android/adb.dart'
;
import
'../android/android_sdk.dart'
;
import
'../android/device_android.dart'
;
import
'../base/context.dart'
;
import
'../base/globals.dart'
;
...
...
packages/flutter_tools/lib/src/commands/refresh.dart
View file @
dcf0b7ba
...
...
@@ -32,7 +32,7 @@ class RefreshCommand extends FlutterCommand {
downloadApplicationPackagesAndConnectToDevices
(),
],
eagerError:
true
);
if
(!
devices
.
android
.
isConnected
())
{
if
(
devices
.
android
==
null
||
!
devices
.
android
.
isConnected
())
{
printError
(
'No device connected.'
);
return
1
;
}
...
...
packages/flutter_tools/lib/src/commands/trace.dart
View file @
dcf0b7ba
...
...
@@ -29,7 +29,7 @@ class TraceCommand extends FlutterCommand {
Future
<
int
>
runInProject
()
async
{
await
downloadApplicationPackagesAndConnectToDevices
();
if
(!
devices
.
android
.
isConnected
())
{
if
(
devices
.
android
==
null
||
!
devices
.
android
.
isConnected
())
{
printError
(
'No device connected, so no trace was completed.'
);
return
1
;
}
...
...
packages/flutter_tools/lib/src/ios/device_ios.dart
View file @
dcf0b7ba
...
...
@@ -402,6 +402,8 @@ class _IOSDeviceLogReader extends DeviceLogReader {
if
(!
device
.
isConnected
())
return
2
;
// TODO(devoncarew): This regex should use the CFBundleIdentifier value from
// the user's plist (instead of `flutter.runner.Runner`).
return
await
runCommandAndStreamOutput
(
<
String
>[
device
.
loggerPath
],
prefix:
'[
$name
] '
,
...
...
packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
View file @
dcf0b7ba
...
...
@@ -9,7 +9,9 @@ import 'package:args/args.dart';
import
'package:args/command_runner.dart'
;
import
'package:path/path.dart'
as
path
;
import
'../android/android_sdk.dart'
;
import
'../artifacts.dart'
;
import
'../base/context.dart'
;
import
'../base/globals.dart'
;
import
'../base/process.dart'
;
import
'../build_configuration.dart'
;
...
...
@@ -167,6 +169,22 @@ class FlutterCommandRunner extends CommandRunner {
// See if the user specified a specific device.
deviceManager
.
specifiedDeviceId
=
globalResults
[
'device-id'
];
// The Android SDK could already have been set by tests.
if
(!
context
.
isSet
(
AndroidSdk
))
{
if
(
enginePath
!=
null
)
{
context
[
AndroidSdk
]
=
new
AndroidSdk
(
'
$enginePath
/third_party/android_tools/sdk'
);
}
else
{
context
[
AndroidSdk
]
=
AndroidSdk
.
locateAndroidSdk
();
}
}
if
(
androidSdk
!=
null
)
{
printTrace
(
'Using Android SDK at
${androidSdk.directory}
.'
);
if
(
androidSdk
.
latestVersion
!=
null
)
printTrace
(
'
${androidSdk.latestVersion}
'
);
}
ArtifactStore
.
flutterRoot
=
path
.
normalize
(
path
.
absolute
(
globalResults
[
'flutter-root'
]));
if
(
globalResults
.
wasParsed
(
'package-root'
))
ArtifactStore
.
packageRoot
=
path
.
normalize
(
path
.
absolute
(
globalResults
[
'package-root'
]));
...
...
packages/flutter_tools/lib/src/services.dart
View file @
dcf0b7ba
...
...
@@ -10,6 +10,7 @@ import 'package:path/path.dart' as path;
import
'package:yaml/yaml.dart'
;
import
'artifacts.dart'
;
import
'base/globals.dart'
;
const
String
_kFlutterManifestPath
=
'flutter.yaml'
;
...
...
@@ -23,7 +24,7 @@ dynamic _loadYamlFile(String path) {
/// Loads all services specified in `flutter.yaml`. Parses each service config file,
/// storing metadata in [services] and the list of jar files in [jars].
Future
parseServiceConfigs
(
List
<
Map
<
String
,
String
>>
services
,
{
List
<
File
>
jars
,
String
androidSdk
}
List
<
Map
<
String
,
String
>>
services
,
{
List
<
File
>
jars
}
)
async
{
if
(!
ArtifactStore
.
isPackageRootValid
)
return
;
...
...
@@ -49,17 +50,17 @@ Future parseServiceConfigs(
if
(
jars
!=
null
)
{
for
(
String
jar
in
serviceConfig
[
'jars'
])
jars
.
add
(
new
File
(
await
getServiceFromUrl
(
jar
,
serviceRoot
,
service
,
androidSdk:
androidSdk
,
unzip:
false
)));
jars
.
add
(
new
File
(
await
getServiceFromUrl
(
jar
,
serviceRoot
,
service
,
unzip:
false
)));
}
}
}
Future
<
String
>
getServiceFromUrl
(
String
url
,
String
rootDir
,
String
serviceName
,
{
String
androidSdk
,
bool
unzip:
false
}
String
url
,
String
rootDir
,
String
serviceName
,
{
bool
unzip:
false
}
)
async
{
if
(
url
.
startsWith
(
"android-sdk:"
))
{
if
(
url
.
startsWith
(
"android-sdk:"
)
&&
androidSdk
!=
null
)
{
// It's something shipped in the standard android SDK.
return
url
.
replaceAll
(
'android-sdk:'
,
'
$
androidSdk
/'
);
return
url
.
replaceAll
(
'android-sdk:'
,
'
$
{androidSdk.directory}
/'
);
}
else
if
(
url
.
startsWith
(
"http"
))
{
// It's a regular file to download.
return
await
ArtifactStore
.
getThirdPartyFile
(
url
,
serviceName
,
unzip
);
...
...
packages/flutter_tools/pubspec.yaml
View file @
dcf0b7ba
...
...
@@ -15,6 +15,7 @@ dependencies:
den_api
:
^0.1.0
mustache4dart
:
^1.0.0
path
:
^1.3.0
pub_semver
:
^1.0.0
stack_trace
:
^1.4.0
test
:
0.12.6+1
# see note below
yaml
:
^2.1.3
...
...
packages/flutter_tools/test/android_device_test.dart
View file @
dcf0b7ba
...
...
@@ -5,7 +5,7 @@
import
'package:flutter_tools/src/android/device_android.dart'
;
import
'package:test/test.dart'
;
import
'src/
test_
context.dart'
;
import
'src/context.dart'
;
main
()
=>
defineTests
();
...
...
packages/flutter_tools/test/create_test.dart
View file @
dcf0b7ba
...
...
@@ -11,7 +11,7 @@ import 'package:flutter_tools/src/commands/create.dart';
import
'package:path/path.dart'
as
path
;
import
'package:test/test.dart'
;
import
'src/
test_
context.dart'
;
import
'src/context.dart'
;
main
()
=>
defineTests
();
...
...
packages/flutter_tools/test/daemon_test.dart
View file @
dcf0b7ba
...
...
@@ -16,11 +16,17 @@ import 'src/mocks.dart';
main
()
=>
defineTests
();
defineTests
()
{
group
(
'daemon'
,
()
{
Daemon
daemon
;
AppContext
appContext
;
NotifyingLogger
notifyingLogger
;
Daemon
daemon
;
AppContext
appContext
;
NotifyingLogger
notifyingLogger
;
void
_testUsingContext
(
String
description
,
dynamic
testMethod
())
{
test
(
description
,
()
{
return
appContext
.
runInZone
(
testMethod
);
});
}
group
(
'daemon'
,
()
{
setUp
(()
{
appContext
=
new
AppContext
();
notifyingLogger
=
new
NotifyingLogger
();
...
...
@@ -32,7 +38,7 @@ defineTests() {
return
daemon
.
shutdown
();
});
tes
t
(
'daemon.version'
,
()
async
{
_testUsingContex
t
(
'daemon.version'
,
()
async
{
StreamController
<
Map
<
String
,
dynamic
>>
commands
=
new
StreamController
();
StreamController
<
Map
<
String
,
dynamic
>>
responses
=
new
StreamController
();
daemon
=
new
Daemon
(
...
...
@@ -47,7 +53,7 @@ defineTests() {
expect
(
response
[
'result'
]
is
String
,
true
);
});
tes
t
(
'daemon.logMessage'
,
()
{
_testUsingContex
t
(
'daemon.logMessage'
,
()
{
return
appContext
.
runInZone
(()
async
{
StreamController
<
Map
<
String
,
dynamic
>>
commands
=
new
StreamController
();
StreamController
<
Map
<
String
,
dynamic
>>
responses
=
new
StreamController
();
...
...
@@ -68,7 +74,7 @@ defineTests() {
});
});
tes
t
(
'daemon.shutdown'
,
()
async
{
_testUsingContex
t
(
'daemon.shutdown'
,
()
async
{
StreamController
<
Map
<
String
,
dynamic
>>
commands
=
new
StreamController
();
StreamController
<
Map
<
String
,
dynamic
>>
responses
=
new
StreamController
();
daemon
=
new
Daemon
(
...
...
@@ -82,7 +88,7 @@ defineTests() {
});
});
tes
t
(
'daemon.stopAll'
,
()
async
{
_testUsingContex
t
(
'daemon.stopAll'
,
()
async
{
DaemonCommand
command
=
new
DaemonCommand
();
applyMocksToCommand
(
command
);
...
...
@@ -112,7 +118,7 @@ defineTests() {
expect
(
response
[
'result'
],
true
);
});
tes
t
(
'device.getDevices'
,
()
async
{
_testUsingContex
t
(
'device.getDevices'
,
()
async
{
StreamController
<
Map
<
String
,
dynamic
>>
commands
=
new
StreamController
();
StreamController
<
Map
<
String
,
dynamic
>>
responses
=
new
StreamController
();
daemon
=
new
Daemon
(
...
...
packages/flutter_tools/test/device_test.dart
View file @
dcf0b7ba
...
...
@@ -5,7 +5,7 @@
import
'package:flutter_tools/src/device.dart'
;
import
'package:test/test.dart'
;
import
'src/
test_
context.dart'
;
import
'src/context.dart'
;
main
()
=>
defineTests
();
...
...
packages/flutter_tools/test/install_test.dart
View file @
dcf0b7ba
...
...
@@ -2,18 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/commands/install.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:test/test.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
import
'src/mocks.dart'
;
main
()
=>
defineTests
();
defineTests
()
{
group
(
'install'
,
()
{
test
(
'returns 0 when Android is connected and ready for an install'
,
()
{
test
UsingContext
(
'returns 0 when Android is connected and ready for an install'
,
()
{
InstallCommand
command
=
new
InstallCommand
();
applyMocksToCommand
(
command
);
MockDeviceStore
mockDevices
=
command
.
devices
;
...
...
@@ -30,13 +31,12 @@ defineTests() {
when
(
mockDevices
.
iOSSimulator
.
isAppInstalled
(
any
)).
thenReturn
(
false
);
when
(
mockDevices
.
iOSSimulator
.
installApp
(
any
)).
thenReturn
(
false
);
CommandRunner
runner
=
new
CommandRunner
(
'test_flutter'
,
''
)
..
addCommand
(
command
);
return
runner
.
run
([
'install'
]).
then
((
int
code
)
=>
expect
(
code
,
equals
(
0
)));
return
createTestCommandRunner
(
command
).
run
([
'install'
]).
then
((
int
code
)
{
expect
(
code
,
equals
(
0
));
});
});
test
(
'returns 0 when iOS is connected and ready for an install'
,
()
{
test
UsingContext
(
'returns 0 when iOS is connected and ready for an install'
,
()
{
InstallCommand
command
=
new
InstallCommand
();
applyMocksToCommand
(
command
);
MockDeviceStore
mockDevices
=
command
.
devices
;
...
...
@@ -53,9 +53,9 @@ defineTests() {
when
(
mockDevices
.
iOSSimulator
.
isAppInstalled
(
any
)).
thenReturn
(
false
);
when
(
mockDevices
.
iOSSimulator
.
installApp
(
any
)).
thenReturn
(
false
);
CommandRunner
runner
=
new
CommandRunner
(
'test_flutter'
,
''
)
..
addCommand
(
command
);
return
runner
.
run
([
'install'
]).
then
((
int
code
)
=>
expect
(
code
,
equals
(
0
))
);
return
createTestCommandRunner
(
command
).
run
([
'install'
]).
then
((
int
code
)
{
expect
(
code
,
equals
(
0
)
);
}
);
});
});
}
packages/flutter_tools/test/list_test.dart
View file @
dcf0b7ba
...
...
@@ -2,43 +2,34 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:io'
;
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/android/android_sdk.dart'
;
import
'package:flutter_tools/src/commands/list.dart'
;
import
'package:
mockito/mockito
.dart'
;
import
'package:
flutter_tools/src/device
.dart'
;
import
'package:test/test.dart'
;
import
'src/
mocks
.dart'
;
import
'src/
test_
context.dart'
;
import
'src/
common
.dart'
;
import
'src/context.dart'
;
main
()
=>
defineTests
();
defineTests
()
{
group
(
'list'
,
()
{
testUsingContext
(
'returns 0 when called'
,
()
{
final
String
mockCommand
=
Platform
.
isWindows
?
'cmd /c echo'
:
'echo'
;
ListCommand
command
=
new
ListCommand
();
applyMocksToCommand
(
command
);
MockDeviceStore
mockDevices
=
command
.
devices
;
// Avoid relying on adb being installed on the test system.
// Instead, cause the test to run the echo command.
when
(
mockDevices
.
android
.
adbPath
).
thenReturn
(
mockCommand
);
// Avoid relying on idevice* being installed on the test system.
// Instead, cause the test to run the echo command.
when
(
mockDevices
.
iOS
.
informerPath
).
thenReturn
(
mockCommand
);
when
(
mockDevices
.
iOS
.
installerPath
).
thenReturn
(
mockCommand
);
when
(
mockDevices
.
iOS
.
listerPath
).
thenReturn
(
mockCommand
);
// Avoid relying on xcrun being installed on the test system.
// Instead, cause the test to run the echo command.
when
(
mockDevices
.
iOSSimulator
.
xcrunPath
).
thenReturn
(
mockCommand
);
return
createTestCommandRunner
(
command
).
run
([
'list'
]).
then
((
int
code
)
{
expect
(
code
,
equals
(
0
));
});
});
CommandRunner
runner
=
new
CommandRunner
(
'test_flutter'
,
''
)..
addCommand
(
command
);
return
runner
.
run
([
'list'
]).
then
((
int
code
)
=>
expect
(
code
,
equals
(
0
)));
testUsingContext
(
'no error when no connected devices'
,
()
{
ListCommand
command
=
new
ListCommand
();
return
createTestCommandRunner
(
command
).
run
([
'list'
]).
then
((
int
code
)
{
expect
(
code
,
equals
(
0
));
expect
(
testLogger
.
statusText
,
contains
(
'No connected devices'
));
});
},
overrides:
<
Type
,
dynamic
>{
AndroidSdk:
null
,
DeviceManager:
new
DeviceManager
()
});
});
}
packages/flutter_tools/test/listen_test.dart
View file @
dcf0b7ba
...
...
@@ -2,14 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/commands/listen.dart'
;
import
'package:flutter_tools/src/runner/flutter_command_runner.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:test/test.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
import
'src/mocks.dart'
;
import
'src/test_context.dart'
;
main
()
=>
defineTests
();
...
...
@@ -24,8 +23,9 @@ defineTests() {
when
(
mockDevices
.
iOS
.
isConnected
()).
thenReturn
(
false
);
when
(
mockDevices
.
iOSSimulator
.
isConnected
()).
thenReturn
(
false
);
CommandRunner
runner
=
new
FlutterCommandRunner
()..
addCommand
(
command
);
return
runner
.
run
([
'listen'
]).
then
((
int
code
)
=>
expect
(
code
,
equals
(
0
)));
return
createTestCommandRunner
(
command
).
run
([
'listen'
]).
then
((
int
code
)
{
expect
(
code
,
equals
(
0
));
});
});
});
}
packages/flutter_tools/test/logs_test.dart
View file @
dcf0b7ba
...
...
@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/commands/logs.dart'
;
import
'package:flutter_tools/src/runner/flutter_command_runner.dart'
;
import
'package:test/test.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
import
'src/mocks.dart'
;
import
'src/test_context.dart'
;
main
()
=>
defineTests
();
...
...
@@ -17,8 +16,7 @@ defineTests() {
testUsingContext
(
'fail with a bad device id'
,
()
{
LogsCommand
command
=
new
LogsCommand
();
applyMocksToCommand
(
command
);
CommandRunner
runner
=
new
FlutterCommandRunner
()..
addCommand
(
command
);
return
runner
.
run
(<
String
>[
'-d'
,
'abc123'
,
'logs'
]).
then
((
int
code
)
{
return
createTestCommandRunner
(
command
).
run
(<
String
>[
'-d'
,
'abc123'
,
'logs'
]).
then
((
int
code
)
{
expect
(
code
,
equals
(
1
));
});
});
...
...
packages/flutter_tools/test/src/common.dart
0 → 100644
View file @
dcf0b7ba
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/runner/flutter_command.dart'
;
import
'package:flutter_tools/src/runner/flutter_command_runner.dart'
;
CommandRunner
createTestCommandRunner
(
FlutterCommand
command
)
{
return
new
FlutterCommandRunner
()..
addCommand
(
command
);
}
packages/flutter_tools/test/src/
test_
context.dart
→
packages/flutter_tools/test/src/context.dart
View file @
dcf0b7ba
...
...
@@ -9,12 +9,25 @@ import 'package:flutter_tools/src/base/logger.dart';
import
'package:flutter_tools/src/device.dart'
;
import
'package:test/test.dart'
;
void
testUsingContext
(
String
description
,
dynamic
testMethod
(),
{
Timeout
timeout
})
{
/// Return the test logger. This assumes that the current Logger is a BufferLogger.
BufferLogger
get
testLogger
=>
context
[
Logger
];
void
testUsingContext
(
String
description
,
dynamic
testMethod
(),
{
Timeout
timeout
,
Map
<
Type
,
dynamic
>
overrides:
const
<
Type
,
dynamic
>{}
})
{
test
(
description
,
()
{
AppContext
testContext
=
new
AppContext
();
testContext
[
Logger
]
=
new
BufferLogger
();
testContext
[
DeviceManager
]
=
new
MockDeviceManager
();
overrides
.
forEach
((
Type
type
,
dynamic
value
)
{
testContext
[
type
]
=
value
;
});
if
(!
overrides
.
containsKey
(
Logger
))
testContext
[
Logger
]
=
new
BufferLogger
();
if
(!
overrides
.
containsKey
(
DeviceManager
))
testContext
[
DeviceManager
]
=
new
MockDeviceManager
();
return
testContext
.
runInZone
(
testMethod
);
},
timeout:
timeout
);
...
...
packages/flutter_tools/test/stop_test.dart
View file @
dcf0b7ba
...
...
@@ -2,18 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/commands/stop.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:test/test.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
import
'src/mocks.dart'
;
main
()
=>
defineTests
();
defineTests
()
{
group
(
'stop'
,
()
{
test
(
'returns 0 when Android is connected and ready to be stopped'
,
()
{
test
UsingContext
(
'returns 0 when Android is connected and ready to be stopped'
,
()
{
StopCommand
command
=
new
StopCommand
();
applyMocksToCommand
(
command
);
MockDeviceStore
mockDevices
=
command
.
devices
;
...
...
@@ -27,12 +28,12 @@ defineTests() {
when
(
mockDevices
.
iOSSimulator
.
isConnected
()).
thenReturn
(
false
);
when
(
mockDevices
.
iOSSimulator
.
stopApp
(
any
)).
thenReturn
(
false
);
CommandRunner
runner
=
new
CommandRunner
(
'test_flutter'
,
''
)
..
addCommand
(
command
);
return
runner
.
run
([
'stop'
]).
then
((
int
code
)
=>
expect
(
code
,
equals
(
0
))
);
return
createTestCommandRunner
(
command
).
run
([
'stop'
]).
then
((
int
code
)
{
expect
(
code
,
equals
(
0
)
);
}
);
});
test
(
'returns 0 when iOS is connected and ready to be stopped'
,
()
{
test
UsingContext
(
'returns 0 when iOS is connected and ready to be stopped'
,
()
{
StopCommand
command
=
new
StopCommand
();
applyMocksToCommand
(
command
);
MockDeviceStore
mockDevices
=
command
.
devices
;
...
...
@@ -46,9 +47,9 @@ defineTests() {
when
(
mockDevices
.
iOSSimulator
.
isConnected
()).
thenReturn
(
false
);
when
(
mockDevices
.
iOSSimulator
.
stopApp
(
any
)).
thenReturn
(
false
);
CommandRunner
runner
=
new
CommandRunner
(
'test_flutter'
,
''
)
..
addCommand
(
command
);
return
runner
.
run
([
'stop'
]).
then
((
int
code
)
=>
expect
(
code
,
equals
(
0
))
);
return
createTestCommandRunner
(
command
).
run
([
'stop'
]).
then
((
int
code
)
{
expect
(
code
,
equals
(
0
)
);
}
);
});
});
}
packages/flutter_tools/test/trace_test.dart
View file @
dcf0b7ba
...
...
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/commands/trace.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:test/test.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
import
'src/mocks.dart'
;
import
'src/test_context.dart'
;
main
()
=>
defineTests
();
...
...
@@ -21,9 +21,9 @@ defineTests() {
when
(
mockDevices
.
android
.
isConnected
()).
thenReturn
(
false
);
CommandRunner
runner
=
new
CommandRunner
(
'test_flutter'
,
''
)
..
addCommand
(
command
);
return
runner
.
run
([
'trace'
]).
then
((
int
code
)
=>
expect
(
code
,
equals
(
1
))
);
return
createTestCommandRunner
(
command
).
run
([
'trace'
]).
then
((
int
code
)
{
expect
(
code
,
equals
(
1
)
);
}
);
});
});
}
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