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(
builder
.
compileClassesDex
(
classesDex
,
components
.
jars
);
File
servicesConfig
=
generateServiceDefinitions
(
tempDir
.
path
,
components
.
services
,
ios:
false
);
generateServiceDefinitions
(
tempDir
.
path
,
components
.
services
);
_AssetBuilder
assetBuilder
=
new
_AssetBuilder
(
tempDir
,
'assets'
);
assetBuilder
.
add
(
components
.
icuData
,
'icudtl.dat'
);
...
...
packages/flutter_tools/lib/src/ios/device_ios.dart
View file @
d38bfee6
...
...
@@ -4,6 +4,7 @@
import
'dart:async'
;
import
'dart:io'
;
import
'dart:convert'
;
import
'package:path/path.dart'
as
path
;
...
...
@@ -173,25 +174,22 @@ class IOSDevice extends Device {
// TODO(devoncarew): Handle startPaused, debugPort.
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
);
if
(!
buildResult
)
{
printError
(
'Could not build the precompiled application for the device'
);
printError
(
'Could not build the precompiled application for the device
.
'
);
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'
));
bool
bundleExists
=
bundle
.
existsSync
();
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
;
}
// Step 2.5: Copy any third-party sevices to the app bundle.
await
_addServicesToBundle
(
bundle
);
// Step 3: Attempt to install the application on the device
// Step 3: Attempt to install the application on the device.
int
installationResult
=
await
runCommandAndStreamOutput
([
'/usr/bin/env'
,
'ios-deploy'
,
...
...
@@ -202,11 +200,11 @@ class IOSDevice extends Device {
]);
if
(
installationResult
!=
0
)
{
printError
(
'Could not install
${bundle.path}
on
$id
'
);
printError
(
'Could not install
${bundle.path}
on
$id
.
'
);
return
false
;
}
printTrace
(
'Installation successful'
);
printTrace
(
'Installation successful
.
'
);
return
true
;
}
...
...
@@ -309,33 +307,30 @@ class IOSSimulator extends Device {
Map
<
String
,
dynamic
>
platformArgs
})
async
{
// TODO(chinmaygarde): Use mainPath, route.
printTrace
(
'Building
${app.name}
for
$id
'
);
printTrace
(
'Building
${app.name}
for
$id
.
'
);
if
(
clearLogs
)
this
.
clearLogs
();
// Step 1: Build the Xcode project
// Step 1: Build the Xcode project
.
bool
buildResult
=
await
_buildIOSXcodeProject
(
app
,
buildForDevice:
false
);
if
(!
buildResult
)
{
printError
(
'Could not build the application for the simulator'
);
printError
(
'Could not build the application for the simulator
.
'
);
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'
));
bool
bundleExists
=
await
bundle
.
exists
();
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
;
}
// Step 2.5: Copy any third-party sevices to the app bundle.
await
_addServicesToBundle
(
bundle
);
// Step 3: Install the updated bundle to the simulator
// Step 3: Install the updated bundle to the simulator.
SimControl
.
install
(
id
,
path
.
absolute
(
bundle
.
path
));
// Step 4: Prepare launch arguments
// Step 4: Prepare launch arguments
.
List
<
String
>
args
=
<
String
>[];
if
(
checked
)
...
...
@@ -347,7 +342,7 @@ class IOSSimulator extends Device {
if
(
debugPort
!=
observatoryDefaultPort
)
args
.
add
(
"--observatory-port=
$debugPort
"
);
// Step 5: Launch the updated application in the simulator
// Step 5: Launch the updated application in the simulator
.
try
{
SimControl
.
launch
(
id
,
app
.
id
,
args
);
}
catch
(
error
)
{
...
...
@@ -355,7 +350,7 @@ class IOSSimulator extends Device {
return
false
;
}
printTrace
(
'Successfully started
${app.name}
on
$id
'
);
printTrace
(
'Successfully started
${app.name}
on
$id
.
'
);
return
true
;
}
...
...
@@ -575,6 +570,11 @@ Future<bool> _buildIOSXcodeProject(ApplicationPackage app, { bool buildForDevice
if
(!
_checkXcodeVersion
())
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
>[
'/usr/bin/env'
,
'xcrun'
,
'xcodebuild'
,
'-target'
,
'Runner'
,
'-configuration'
,
'Release'
];
...
...
@@ -593,54 +593,49 @@ Future<bool> _buildIOSXcodeProject(ApplicationPackage app, { bool buildForDevice
}
}
bool
_servicesEnabled
=
false
;
Future
_addServicesToBundle
(
Directory
bundle
)
async
{
if
(
_servicesEnabled
)
{
List
<
Map
<
String
,
String
>>
services
=
[];
await
parseServiceConfigs
(
services
);
await
_fetchFrameworks
(
services
);
_copyFrameworksToBundle
(
bundle
.
path
,
services
);
generateServiceDefinitions
(
bundle
.
path
,
services
,
ios:
true
);
}
List
<
Map
<
String
,
String
>>
services
=
[];
printTrace
(
"Trying to resolve native pub services."
);
// Step 1: Parse the service configuration yaml files present in the service
// pub packages.
await
parseServiceConfigs
(
services
);
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
)
{
String
frameworkUrl
=
service
[
'framework'
];
service
[
'framework-path'
]
=
await
getServiceFromUrl
(
frameworkUrl
,
service
[
'root'
],
service
[
'name'
],
unzip:
true
);
}
}
void
_copyFrameworksToBundle
(
String
destDir
,
List
<
Map
<
String
,
String
>>
services
)
{
// TODO(mpcomplete): check timestamps.
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
);
String
dylibPath
=
await
getServiceFromUrl
(
service
[
'ios-framework'
],
service
[
'root'
],
service
[
'name'
]);
File
dylib
=
new
File
(
dylibPath
);
printTrace
(
"Copying
${dylib.path}
into bundle."
);
if
(!
dylib
.
existsSync
())
{
printError
(
"The service dylib '
${dylib.path}
' does not exist."
);
continue
;
}
// Shell out so permissions on the dylib are preserved.
runCheckedSync
([
'/bin/cp'
,
dylib
.
path
,
frameworksDirectory
.
path
]);
}
}
void
_copyDirRecursive
(
String
fromPath
,
String
toPath
)
{
Directory
fromDir
=
new
Directory
(
fromPath
);
if
(!
fromDir
.
existsSync
())
throw
new
Exception
(
'Source directory "
${fromDir.path}
" does not exist'
);
Directory
toDir
=
new
Directory
(
toPath
);
if
(!
toDir
.
existsSync
())
toDir
.
createSync
(
recursive:
true
);
for
(
FileSystemEntity
entity
in
fromDir
.
listSync
())
{
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.'
);
}
};
void
_copyServiceDefinitionsManifest
(
List
<
Map
<
String
,
String
>>
services
,
File
manifest
)
{
printTrace
(
"Creating service definitions manifest at '
${manifest.path}
'"
);
List
<
Map
<
String
,
String
>>
jsonServices
=
services
.
map
((
Map
<
String
,
String
>
service
)
=>
{
'name'
:
service
[
'name'
],
// Since we have already moved it to the Frameworks directory. Strip away
// the directory and basenames.
'framework'
:
path
.
basenameWithoutExtension
(
service
[
'ios-framework'
])
}).
toList
();
Map
<
String
,
dynamic
>
json
=
{
'services'
:
jsonServices
};
manifest
.
writeAsStringSync
(
JSON
.
encode
(
json
),
mode:
FileMode
.
WRITE
,
flush:
true
);
}
packages/flutter_tools/lib/src/services.dart
View file @
d38bfee6
...
...
@@ -13,8 +13,10 @@ import 'artifacts.dart';
import
'base/globals.dart'
;
const
String
_kFlutterManifestPath
=
'flutter.yaml'
;
const
String
_kFlutterServicesManifestPath
=
'flutter_services.yaml'
;
dynamic
_loadYamlFile
(
String
path
)
{
printTrace
(
"Looking for YAML at '
$path
'"
);
if
(!
FileSystemEntity
.
isFileSync
(
path
))
return
null
;
String
manifestString
=
new
File
(
path
).
readAsStringSync
();
...
...
@@ -26,18 +28,24 @@ dynamic _loadYamlFile(String path) {
Future
parseServiceConfigs
(
List
<
Map
<
String
,
String
>>
services
,
{
List
<
File
>
jars
}
)
async
{
if
(!
ArtifactStore
.
isPackageRootValid
)
if
(!
ArtifactStore
.
isPackageRootValid
)
{
printTrace
(
"Artifact store invalid while parsing service configs"
);
return
;
}
dynamic
manifest
=
_loadYamlFile
(
_kFlutterManifestPath
);
if
(
manifest
==
null
||
manifest
[
'services'
]
==
null
)
if
(
manifest
==
null
||
manifest
[
'services'
]
==
null
)
{
printTrace
(
"No services specified in the manifest"
);
return
;
}
for
(
String
service
in
manifest
[
'services'
])
{
String
serviceRoot
=
'
${ArtifactStore.packageRoot}
/
$service
'
;
dynamic
serviceConfig
=
_loadYamlFile
(
'
$serviceRoot
/config.yaml'
);
if
(
serviceConfig
==
null
)
dynamic
serviceConfig
=
_loadYamlFile
(
'
$serviceRoot
/
$_kFlutterServicesManifestPath
'
);
if
(
serviceConfig
==
null
)
{
printStatus
(
"No
$_kFlutterServicesManifestPath
found for service '
$serviceRoot
'. Skipping."
);
continue
;
}
for
(
Map
<
String
,
String
>
service
in
serviceConfig
[
'services'
])
{
services
.
add
({
...
...
@@ -78,22 +86,16 @@ Future<String> getServiceFromUrl(
/// ]
/// }
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
=
servicesIn
.
map
((
Map
<
String
,
String
>
service
)
=>
{
'name'
:
service
[
'name'
],
keyOut:
service
[
keyIn
]
'class'
:
service
[
'android-class'
]
}).
toList
();
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
);
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