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
c5ea4098
Commit
c5ea4098
authored
Sep 16, 2015
by
Ian Fischer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Most of the infrastructure needed to install an APK on Android.
parent
d8d87f18
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
104 additions
and
32 deletions
+104
-32
device.dart
packages/flutter_tools/lib/src/device.dart
+86
-26
install.dart
packages/flutter_tools/lib/src/install.dart
+6
-3
install_test.dart
packages/flutter_tools/test/install_test.dart
+6
-2
common.dart
packages/flutter_tools/test/src/common.dart
+6
-1
No files found.
packages/flutter_tools/lib/src/device.dart
View file @
c5ea4098
...
...
@@ -40,13 +40,13 @@ abstract class _Device {
_Device
.
_
(
this
.
id
);
/// Install an app package on the current device
bool
installApp
(
String
path
);
/// Check if the current device needs an installation
bool
needsInstall
();
bool
installApp
(
String
appPath
,
String
appPackageID
,
String
appFileName
);
/// Check if the device is currently connected
bool
isConnected
();
/// Check if the current version of the given app is already installed
bool
isAppInstalled
(
String
appPath
,
String
appPackageID
,
String
appFileName
);
}
class
AndroidDevice
extends
_Device
{
...
...
@@ -57,54 +57,44 @@ class AndroidDevice extends _Device {
String
_adbPath
;
String
get
adbPath
=>
_adbPath
;
bool
_hasAdb
=
false
;
bool
_hasValidAndroid
=
false
;
factory
AndroidDevice
([
String
id
=
null
])
{
return
new
_Device
(
className
,
id
);
}
AndroidDevice
.
_
(
id
)
:
super
.
_
(
id
)
{
_updatePaths
();
_adbPath
=
_getAdbPath
();
_hasAdb
=
_checkForAdb
();
// Checking for lollipop 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.
if
(!
_checkForAdb
()
||
!
_checkForLollipopOrLater
())
{
_logging
.
severe
(
'Unable to run on Android.'
);
}
}
_hasValidAndroid
=
_checkForLollipopOrLater
();
@override
bool
installApp
(
String
path
)
{
return
true
;
}
@override
bool
needsInstall
()
{
return
true
;
if
(!
_hasAdb
||
!
_hasValidAndroid
)
{
_logging
.
severe
(
'Unable to run on Android.'
);
}
@override
bool
isConnected
()
{
return
true
;
}
void
_updatePaths
()
{
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
))
{
_adbPath
=
adbPath1
;
return
adbPath1
;
}
else
if
(
FileSystemEntity
.
isFileSync
(
adbPath2
))
{
_adbPath
=
adbPath2
;
return
adbPath2
;
}
else
{
_logging
.
info
(
'"adb" not found at
\n
"
$adbPath1
" or
\n
"
$adbPath2
"
\n
'
+
'using default path "
$_ADB_PATH
"'
);
_adbPath
=
_ADB_PATH
;
return
_ADB_PATH
;
}
}
else
{
_adbPath
=
_ADB_PATH
;
return
_ADB_PATH
;
}
}
...
...
@@ -184,4 +174,74 @@ class AndroidDevice extends _Device {
}
return
false
;
}
String
_getDeviceSha1Path
(
String
appPackageID
,
String
appFileName
)
{
return
'/sdcard/
$appPackageID
/
$appFileName
.sha1'
;
}
String
_getDeviceApkSha1
(
String
appPackageID
,
String
appFileName
)
{
return
runCheckedSync
([
adbPath
,
'shell'
,
'cat'
,
_getDeviceSha1Path
(
appPackageID
,
appFileName
)
]);
}
String
_getSourceSha1
(
String
apkPath
)
{
String
sha1
=
runCheckedSync
([
'shasum'
,
'-a'
,
'1'
,
'-p'
,
apkPath
]).
split
(
' '
)[
0
];
return
sha1
;
}
@override
bool
isAppInstalled
(
String
appPath
,
String
appPackageID
,
String
appFileName
)
{
if
(!
isConnected
())
{
return
false
;
}
if
(
runCheckedSync
([
adbPath
,
'shell'
,
'pm'
,
'path'
,
appPackageID
])
==
''
)
{
_logging
.
info
(
'TODO(iansf): move this log to the caller.
$appFileName
is not on the device. Installing now...'
);
return
false
;
}
if
(
_getDeviceApkSha1
(
appPackageID
,
appFileName
)
!=
_getSourceSha1
(
appPath
))
{
_logging
.
info
(
'TODO(iansf): move this log to the caller.
$appFileName
is out of date. Installing now...'
);
return
false
;
}
return
true
;
}
@override
bool
installApp
(
String
appPath
,
String
appPackageID
,
String
appFileName
)
{
if
(!
isConnected
())
{
_logging
.
info
(
'Android device not connected. Not installing.'
);
return
false
;
}
if
(!
FileSystemEntity
.
isFileSync
(
appPath
))
{
_logging
.
severe
(
'"
$appPath
" does not exist.'
);
return
false
;
}
runCheckedSync
([
adbPath
,
'install'
,
'-r'
,
appPath
]);
Directory
tempDir
=
Directory
.
systemTemp
;
String
sha1Path
=
path
.
join
(
tempDir
.
path
,
appPath
.
replaceAll
(
path
.
separator
,
'_'
),
'.sha1'
);
File
sha1TempFile
=
new
File
(
sha1Path
);
sha1TempFile
.
writeAsStringSync
(
_getSourceSha1
(
appPath
),
flush:
true
);
runCheckedSync
([
adbPath
,
'push'
,
sha1Path
,
_getDeviceSha1Path
(
appPackageID
,
appFileName
)
]);
sha1TempFile
.
deleteSync
();
return
true
;
}
@override
bool
isConnected
()
=>
_hasValidAndroid
;
}
}
packages/flutter_tools/lib/src/install.dart
View file @
c5ea4098
...
...
@@ -12,7 +12,8 @@ import 'common.dart';
import
'device.dart'
;
class
InstallCommandHandler
extends
CommandHandler
{
InstallCommandHandler
()
AndroidDevice
android
=
null
;
InstallCommandHandler
([
this
.
android
])
:
super
(
'install'
,
'Install your Sky app on attached devices.'
);
@override
...
...
@@ -32,9 +33,11 @@ class InstallCommandHandler extends CommandHandler {
bool
installedSomewhere
=
false
;
AndroidDevice
android
=
new
AndroidDevice
();
if
(
android
==
null
)
{
android
=
new
AndroidDevice
();
}
if
(
android
.
isConnected
())
{
installedSomewhere
=
installedSomewhere
||
android
.
installApp
(
''
);
installedSomewhere
=
installedSomewhere
||
android
.
installApp
(
''
,
''
,
''
);
}
if
(
installedSomewhere
)
{
...
...
packages/flutter_tools/test/install_test.dart
View file @
c5ea4098
...
...
@@ -14,10 +14,14 @@ main() => defineTests();
defineTests
()
{
group
(
'install'
,
()
{
test
(
'install returns 0'
,
()
{
test
(
'returns 0 when Android is connected and ready for an install'
,
()
{
MockAndroidDevice
android
=
new
MockAndroidDevice
();
when
(
android
.
isConnected
()).
thenReturn
(
true
);
when
(
android
.
installApp
(
any
,
any
,
any
)).
thenReturn
(
true
);
InstallCommandHandler
handler
=
new
InstallCommandHandler
(
android
);
MockArgResults
results
=
new
MockArgResults
();
when
(
results
[
'help'
]).
thenReturn
(
false
);
InstallCommandHandler
handler
=
new
InstallCommandHandler
();
handler
.
processArgResults
(
results
)
.
then
((
int
code
)
=>
expect
(
code
,
equals
(
0
)));
...
...
packages/flutter_tools/test/src/common.dart
View file @
c5ea4098
...
...
@@ -4,9 +4,14 @@
import
'package:args/args.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:sky_tools/src/device.dart'
;
@proxy
class
MockArgResults
extends
Mock
implements
ArgResults
{
@override
dynamic
noSuchMethod
(
Invocation
invocation
)
=>
super
.
noSuchMethod
(
invocation
);
}
class
MockAndroidDevice
extends
Mock
implements
AndroidDevice
{
@override
dynamic
noSuchMethod
(
Invocation
invocation
)
=>
super
.
noSuchMethod
(
invocation
);
}
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