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
d38bfee6
Commit
d38bfee6
authored
Feb 12, 2016
by
Chinmay Garde
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tooling updates for dealing with native services distributed in pub packages
parent
c30b3cc6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
76 additions
and
79 deletions
+76
-79
apk.dart
packages/flutter_tools/lib/src/commands/apk.dart
+1
-1
device_ios.dart
packages/flutter_tools/lib/src/ios/device_ios.dart
+60
-65
services.dart
packages/flutter_tools/lib/src/services.dart
+15
-13
No files found.
packages/flutter_tools/lib/src/commands/apk.dart
View file @
d38bfee6
...
@@ -271,7 +271,7 @@ int _buildApk(
...
@@ -271,7 +271,7 @@ int _buildApk(
builder
.
compileClassesDex
(
classesDex
,
components
.
jars
);
builder
.
compileClassesDex
(
classesDex
,
components
.
jars
);
File
servicesConfig
=
File
servicesConfig
=
generateServiceDefinitions
(
tempDir
.
path
,
components
.
services
,
ios:
false
);
generateServiceDefinitions
(
tempDir
.
path
,
components
.
services
);
_AssetBuilder
assetBuilder
=
new
_AssetBuilder
(
tempDir
,
'assets'
);
_AssetBuilder
assetBuilder
=
new
_AssetBuilder
(
tempDir
,
'assets'
);
assetBuilder
.
add
(
components
.
icuData
,
'icudtl.dat'
);
assetBuilder
.
add
(
components
.
icuData
,
'icudtl.dat'
);
...
...
packages/flutter_tools/lib/src/ios/device_ios.dart
View file @
d38bfee6
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
import
'dart:async'
;
import
'dart:async'
;
import
'dart:io'
;
import
'dart:io'
;
import
'dart:convert'
;
import
'package:path/path.dart'
as
path
;
import
'package:path/path.dart'
as
path
;
...
@@ -173,25 +174,22 @@ class IOSDevice extends Device {
...
@@ -173,25 +174,22 @@ class IOSDevice extends Device {
// TODO(devoncarew): Handle startPaused, debugPort.
// TODO(devoncarew): Handle startPaused, debugPort.
printTrace
(
'Building
${app.name}
for
$id
'
);
printTrace
(
'Building
${app.name}
for
$id
'
);
// Step 1: Install the precompiled application if necessary
// Step 1: Install the precompiled application if necessary
.
bool
buildResult
=
await
_buildIOSXcodeProject
(
app
,
buildForDevice:
true
);
bool
buildResult
=
await
_buildIOSXcodeProject
(
app
,
buildForDevice:
true
);
if
(!
buildResult
)
{
if
(!
buildResult
)
{
printError
(
'Could not build the precompiled application for the device'
);
printError
(
'Could not build the precompiled application for the device
.
'
);
return
false
;
return
false
;
}
}
// Step 2: Check that the application exists at the specified path
// Step 2: Check that the application exists at the specified path
.
Directory
bundle
=
new
Directory
(
path
.
join
(
app
.
localPath
,
'build'
,
'Release-iphoneos'
,
'Runner.app'
));
Directory
bundle
=
new
Directory
(
path
.
join
(
app
.
localPath
,
'build'
,
'Release-iphoneos'
,
'Runner.app'
));
bool
bundleExists
=
bundle
.
existsSync
();
bool
bundleExists
=
bundle
.
existsSync
();
if
(!
bundleExists
)
{
if
(!
bundleExists
)
{
printError
(
'Could not find the built application bundle at
${bundle.path}
'
);
printError
(
'Could not find the built application bundle at
${bundle.path}
.
'
);
return
false
;
return
false
;
}
}
// Step 2.5: Copy any third-party sevices to the app bundle.
// Step 3: Attempt to install the application on the device.
await
_addServicesToBundle
(
bundle
);
// Step 3: Attempt to install the application on the device
int
installationResult
=
await
runCommandAndStreamOutput
([
int
installationResult
=
await
runCommandAndStreamOutput
([
'/usr/bin/env'
,
'/usr/bin/env'
,
'ios-deploy'
,
'ios-deploy'
,
...
@@ -202,11 +200,11 @@ class IOSDevice extends Device {
...
@@ -202,11 +200,11 @@ class IOSDevice extends Device {
]);
]);
if
(
installationResult
!=
0
)
{
if
(
installationResult
!=
0
)
{
printError
(
'Could not install
${bundle.path}
on
$id
'
);
printError
(
'Could not install
${bundle.path}
on
$id
.
'
);
return
false
;
return
false
;
}
}
printTrace
(
'Installation successful'
);
printTrace
(
'Installation successful
.
'
);
return
true
;
return
true
;
}
}
...
@@ -309,33 +307,30 @@ class IOSSimulator extends Device {
...
@@ -309,33 +307,30 @@ class IOSSimulator extends Device {
Map
<
String
,
dynamic
>
platformArgs
Map
<
String
,
dynamic
>
platformArgs
})
async
{
})
async
{
// TODO(chinmaygarde): Use mainPath, route.
// TODO(chinmaygarde): Use mainPath, route.
printTrace
(
'Building
${app.name}
for
$id
'
);
printTrace
(
'Building
${app.name}
for
$id
.
'
);
if
(
clearLogs
)
if
(
clearLogs
)
this
.
clearLogs
();
this
.
clearLogs
();
// Step 1: Build the Xcode project
// Step 1: Build the Xcode project
.
bool
buildResult
=
await
_buildIOSXcodeProject
(
app
,
buildForDevice:
false
);
bool
buildResult
=
await
_buildIOSXcodeProject
(
app
,
buildForDevice:
false
);
if
(!
buildResult
)
{
if
(!
buildResult
)
{
printError
(
'Could not build the application for the simulator'
);
printError
(
'Could not build the application for the simulator
.
'
);
return
false
;
return
false
;
}
}
// Step 2: Assert that the Xcode project was successfully built
// Step 2: Assert that the Xcode project was successfully built
.
Directory
bundle
=
new
Directory
(
path
.
join
(
app
.
localPath
,
'build'
,
'Release-iphonesimulator'
,
'Runner.app'
));
Directory
bundle
=
new
Directory
(
path
.
join
(
app
.
localPath
,
'build'
,
'Release-iphonesimulator'
,
'Runner.app'
));
bool
bundleExists
=
await
bundle
.
exists
();
bool
bundleExists
=
await
bundle
.
exists
();
if
(!
bundleExists
)
{
if
(!
bundleExists
)
{
printError
(
'Could not find the built application bundle at
${bundle.path}
'
);
printError
(
'Could not find the built application bundle at
${bundle.path}
.
'
);
return
false
;
return
false
;
}
}
// Step 2.5: Copy any third-party sevices to the app bundle.
// Step 3: Install the updated bundle to the simulator.
await
_addServicesToBundle
(
bundle
);
// Step 3: Install the updated bundle to the simulator
SimControl
.
install
(
id
,
path
.
absolute
(
bundle
.
path
));
SimControl
.
install
(
id
,
path
.
absolute
(
bundle
.
path
));
// Step 4: Prepare launch arguments
// Step 4: Prepare launch arguments
.
List
<
String
>
args
=
<
String
>[];
List
<
String
>
args
=
<
String
>[];
if
(
checked
)
if
(
checked
)
...
@@ -347,7 +342,7 @@ class IOSSimulator extends Device {
...
@@ -347,7 +342,7 @@ class IOSSimulator extends Device {
if
(
debugPort
!=
observatoryDefaultPort
)
if
(
debugPort
!=
observatoryDefaultPort
)
args
.
add
(
"--observatory-port=
$debugPort
"
);
args
.
add
(
"--observatory-port=
$debugPort
"
);
// Step 5: Launch the updated application in the simulator
// Step 5: Launch the updated application in the simulator
.
try
{
try
{
SimControl
.
launch
(
id
,
app
.
id
,
args
);
SimControl
.
launch
(
id
,
app
.
id
,
args
);
}
catch
(
error
)
{
}
catch
(
error
)
{
...
@@ -355,7 +350,7 @@ class IOSSimulator extends Device {
...
@@ -355,7 +350,7 @@ class IOSSimulator extends Device {
return
false
;
return
false
;
}
}
printTrace
(
'Successfully started
${app.name}
on
$id
'
);
printTrace
(
'Successfully started
${app.name}
on
$id
.
'
);
return
true
;
return
true
;
}
}
...
@@ -575,6 +570,11 @@ Future<bool> _buildIOSXcodeProject(ApplicationPackage app, { bool buildForDevice
...
@@ -575,6 +570,11 @@ Future<bool> _buildIOSXcodeProject(ApplicationPackage app, { bool buildForDevice
if
(!
_checkXcodeVersion
())
if
(!
_checkXcodeVersion
())
return
false
;
return
false
;
// Before the build, all service definitions must be updated and the dylibs
// copied over to a location that is suitable for Xcodebuild to find them.
await
_addServicesToBundle
(
new
Directory
(
app
.
localPath
));
List
<
String
>
commands
=
<
String
>[
List
<
String
>
commands
=
<
String
>[
'/usr/bin/env'
,
'xcrun'
,
'xcodebuild'
,
'-target'
,
'Runner'
,
'-configuration'
,
'Release'
'/usr/bin/env'
,
'xcrun'
,
'xcodebuild'
,
'-target'
,
'Runner'
,
'-configuration'
,
'Release'
];
];
...
@@ -593,54 +593,49 @@ Future<bool> _buildIOSXcodeProject(ApplicationPackage app, { bool buildForDevice
...
@@ -593,54 +593,49 @@ Future<bool> _buildIOSXcodeProject(ApplicationPackage app, { bool buildForDevice
}
}
}
}
bool
_servicesEnabled
=
false
;
Future
_addServicesToBundle
(
Directory
bundle
)
async
{
Future
_addServicesToBundle
(
Directory
bundle
)
async
{
if
(
_servicesEnabled
)
{
List
<
Map
<
String
,
String
>>
services
=
[];
List
<
Map
<
String
,
String
>>
services
=
[];
printTrace
(
"Trying to resolve native pub services."
);
await
parseServiceConfigs
(
services
);
await
_fetchFrameworks
(
services
);
// Step 1: Parse the service configuration yaml files present in the service
_copyFrameworksToBundle
(
bundle
.
path
,
services
);
// pub packages.
await
parseServiceConfigs
(
services
);
generateServiceDefinitions
(
bundle
.
path
,
services
,
ios:
true
);
printTrace
(
"Found
${services.length}
service definition(s)."
);
}
// Step 2: Copy framework dylibs to the correct spot for xcodebuild to pick up.
Directory
frameworksDirectory
=
new
Directory
(
path
.
join
(
bundle
.
path
,
"Frameworks"
));
await
_copyServiceFrameworks
(
services
,
frameworksDirectory
);
// Step 3: Copy the service definitions manifest at the correct spot for
// xcodebuild to pick up.
File
manifestFile
=
new
File
(
path
.
join
(
bundle
.
path
,
"ServiceDefinitions.json"
));
_copyServiceDefinitionsManifest
(
services
,
manifestFile
);
}
}
Future
_fetchFrameworks
(
List
<
Map
<
String
,
String
>>
services
)
async
{
Future
_copyServiceFrameworks
(
List
<
Map
<
String
,
String
>>
services
,
Directory
frameworksDirectory
)
async
{
printTrace
(
"Copying service frameworks to '
${path.absolute(frameworksDirectory.path)}
'."
);
frameworksDirectory
.
createSync
(
recursive:
true
);
for
(
Map
<
String
,
String
>
service
in
services
)
{
for
(
Map
<
String
,
String
>
service
in
services
)
{
String
frameworkUrl
=
service
[
'framework'
];
String
dylibPath
=
await
getServiceFromUrl
(
service
[
'ios-framework'
],
service
[
'root'
],
service
[
'name'
]);
service
[
'framework-path'
]
=
await
getServiceFromUrl
(
File
dylib
=
new
File
(
dylibPath
);
frameworkUrl
,
service
[
'root'
],
service
[
'name'
],
unzip:
true
printTrace
(
"Copying
${dylib.path}
into bundle."
);
);
if
(!
dylib
.
existsSync
())
{
}
printError
(
"The service dylib '
${dylib.path}
' does not exist."
);
}
continue
;
}
void
_copyFrameworksToBundle
(
String
destDir
,
List
<
Map
<
String
,
String
>>
services
)
{
// Shell out so permissions on the dylib are preserved.
// TODO(mpcomplete): check timestamps.
runCheckedSync
([
'/bin/cp'
,
dylib
.
path
,
frameworksDirectory
.
path
]);
for
(
Map
<
String
,
String
>
service
in
services
)
{
String
basename
=
path
.
basename
(
service
[
'framework-path'
]);
String
destPath
=
path
.
join
(
destDir
,
basename
);
_copyDirRecursive
(
service
[
'framework-path'
],
destPath
);
}
}
}
}
void
_copyDirRecursive
(
String
fromPath
,
String
toPath
)
{
void
_copyServiceDefinitionsManifest
(
List
<
Map
<
String
,
String
>>
services
,
File
manifest
)
{
Directory
fromDir
=
new
Directory
(
fromPath
);
printTrace
(
"Creating service definitions manifest at '
${manifest.path}
'"
);
if
(!
fromDir
.
existsSync
())
List
<
Map
<
String
,
String
>>
jsonServices
=
services
.
map
((
Map
<
String
,
String
>
service
)
=>
{
throw
new
Exception
(
'Source directory "
${fromDir.path}
" does not exist'
);
'name'
:
service
[
'name'
],
// Since we have already moved it to the Frameworks directory. Strip away
Directory
toDir
=
new
Directory
(
toPath
);
// the directory and basenames.
if
(!
toDir
.
existsSync
())
'framework'
:
path
.
basenameWithoutExtension
(
service
[
'ios-framework'
])
toDir
.
createSync
(
recursive:
true
);
}).
toList
();
Map
<
String
,
dynamic
>
json
=
{
'services'
:
jsonServices
};
for
(
FileSystemEntity
entity
in
fromDir
.
listSync
())
{
manifest
.
writeAsStringSync
(
JSON
.
encode
(
json
),
mode:
FileMode
.
WRITE
,
flush:
true
);
String
newPath
=
'
${toDir.path}
/
${path.basename(entity.path)}
'
;
if
(
entity
is
File
)
{
entity
.
copySync
(
newPath
);
}
else
if
(
entity
is
Directory
)
{
_copyDirRecursive
(
entity
.
path
,
newPath
);
}
else
{
throw
new
Exception
(
'Unsupported file type for recursive copy.'
);
}
};
}
}
packages/flutter_tools/lib/src/services.dart
View file @
d38bfee6
...
@@ -13,8 +13,10 @@ import 'artifacts.dart';
...
@@ -13,8 +13,10 @@ import 'artifacts.dart';
import
'base/globals.dart'
;
import
'base/globals.dart'
;
const
String
_kFlutterManifestPath
=
'flutter.yaml'
;
const
String
_kFlutterManifestPath
=
'flutter.yaml'
;
const
String
_kFlutterServicesManifestPath
=
'flutter_services.yaml'
;
dynamic
_loadYamlFile
(
String
path
)
{
dynamic
_loadYamlFile
(
String
path
)
{
printTrace
(
"Looking for YAML at '
$path
'"
);
if
(!
FileSystemEntity
.
isFileSync
(
path
))
if
(!
FileSystemEntity
.
isFileSync
(
path
))
return
null
;
return
null
;
String
manifestString
=
new
File
(
path
).
readAsStringSync
();
String
manifestString
=
new
File
(
path
).
readAsStringSync
();
...
@@ -26,18 +28,24 @@ dynamic _loadYamlFile(String path) {
...
@@ -26,18 +28,24 @@ dynamic _loadYamlFile(String path) {
Future
parseServiceConfigs
(
Future
parseServiceConfigs
(
List
<
Map
<
String
,
String
>>
services
,
{
List
<
File
>
jars
}
List
<
Map
<
String
,
String
>>
services
,
{
List
<
File
>
jars
}
)
async
{
)
async
{
if
(!
ArtifactStore
.
isPackageRootValid
)
if
(!
ArtifactStore
.
isPackageRootValid
)
{
printTrace
(
"Artifact store invalid while parsing service configs"
);
return
;
return
;
}
dynamic
manifest
=
_loadYamlFile
(
_kFlutterManifestPath
);
dynamic
manifest
=
_loadYamlFile
(
_kFlutterManifestPath
);
if
(
manifest
==
null
||
manifest
[
'services'
]
==
null
)
if
(
manifest
==
null
||
manifest
[
'services'
]
==
null
)
{
printTrace
(
"No services specified in the manifest"
);
return
;
return
;
}
for
(
String
service
in
manifest
[
'services'
])
{
for
(
String
service
in
manifest
[
'services'
])
{
String
serviceRoot
=
'
${ArtifactStore.packageRoot}
/
$service
'
;
String
serviceRoot
=
'
${ArtifactStore.packageRoot}
/
$service
'
;
dynamic
serviceConfig
=
_loadYamlFile
(
'
$serviceRoot
/config.yaml'
);
dynamic
serviceConfig
=
_loadYamlFile
(
'
$serviceRoot
/
$_kFlutterServicesManifestPath
'
);
if
(
serviceConfig
==
null
)
if
(
serviceConfig
==
null
)
{
printStatus
(
"No
$_kFlutterServicesManifestPath
found for service '
$serviceRoot
'. Skipping."
);
continue
;
continue
;
}
for
(
Map
<
String
,
String
>
service
in
serviceConfig
[
'services'
])
{
for
(
Map
<
String
,
String
>
service
in
serviceConfig
[
'services'
])
{
services
.
add
({
services
.
add
({
...
@@ -78,22 +86,16 @@ Future<String> getServiceFromUrl(
...
@@ -78,22 +86,16 @@ Future<String> getServiceFromUrl(
/// ]
/// ]
/// }
/// }
File
generateServiceDefinitions
(
File
generateServiceDefinitions
(
String
dir
,
List
<
Map
<
String
,
String
>>
servicesIn
,
{
bool
ios
}
String
dir
,
List
<
Map
<
String
,
String
>>
servicesIn
)
{
)
{
assert
(
ios
!=
null
);
String
keyOut
=
ios
?
'framework'
:
'class'
;
String
keyIn
=
ios
?
'framework-path'
:
'android-class'
;
// TODO(mpcomplete): we should use the same filename for consistency.
String
filename
=
ios
?
'ServiceDefinitions.json'
:
'services.json'
;
List
<
Map
<
String
,
String
>>
services
=
List
<
Map
<
String
,
String
>>
services
=
servicesIn
.
map
((
Map
<
String
,
String
>
service
)
=>
{
servicesIn
.
map
((
Map
<
String
,
String
>
service
)
=>
{
'name'
:
service
[
'name'
],
'name'
:
service
[
'name'
],
keyOut:
service
[
keyIn
]
'class'
:
service
[
'android-class'
]
}).
toList
();
}).
toList
();
Map
<
String
,
dynamic
>
json
=
{
'services'
:
services
};
Map
<
String
,
dynamic
>
json
=
{
'services'
:
services
};
File
servicesFile
=
new
File
(
path
.
join
(
dir
,
filename
));
File
servicesFile
=
new
File
(
path
.
join
(
dir
,
'services.json'
));
servicesFile
.
writeAsStringSync
(
JSON
.
encode
(
json
),
mode:
FileMode
.
WRITE
,
flush:
true
);
servicesFile
.
writeAsStringSync
(
JSON
.
encode
(
json
),
mode:
FileMode
.
WRITE
,
flush:
true
);
return
servicesFile
;
return
servicesFile
;
}
}
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