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
be6234d5
Unverified
Commit
be6234d5
authored
Apr 06, 2020
by
Anisov Aleksey
Committed by
GitHub
Apr 06, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Read custom app project name from gradle.properties (#52791)
parent
f118e99f
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
470 additions
and
3 deletions
+470
-3
test.dart
dev/bots/test.dart
+1
-0
module_custom_host_app_name_test.dart
...devicelab/bin/tasks/module_custom_host_app_name_test.dart
+356
-0
README.md
dev/integration_tests/android_custom_host_app/README.md
+8
-0
build.gradle
...tion_tests/android_custom_host_app/SampleApp/build.gradle
+27
-0
AndroidManifest.xml
...id_custom_host_app/SampleApp/src/main/AndroidManifest.xml
+13
-0
MainActivity.java
...pleApp/src/main/java/io/flutter/add2app/MainActivity.java
+12
-0
build.gradle
dev/integration_tests/android_custom_host_app/build.gradle
+24
-0
gradle.properties
...tegration_tests/android_custom_host_app/gradle.properties
+4
-0
gradle-wrapper.properties
..._custom_host_app/gradle/wrapper/gradle-wrapper.properties
+6
-0
local.properties
...ntegration_tests/android_custom_host_app/local.properties
+8
-0
settings.gradle
...integration_tests/android_custom_host_app/settings.gradle
+7
-0
flutter.gradle
packages/flutter_tools/gradle/flutter.gradle
+4
-3
No files found.
dev/bots/test.dart
View file @
be6234d5
...
...
@@ -923,6 +923,7 @@ Future<void> _runHostOnlyDeviceLabTests() async {
()
=>
_runDevicelabTest
(
'gradle_r8_test'
,
environment:
gradleEnvironment
),
()
=>
_runDevicelabTest
(
'module_host_with_custom_build_test'
,
environment:
gradleEnvironment
,
testEmbeddingV2:
true
),
()
=>
_runDevicelabTest
(
'module_custom_host_app_name_test'
,
environment:
gradleEnvironment
),
()
=>
_runDevicelabTest
(
'module_test'
,
environment:
gradleEnvironment
,
testEmbeddingV2:
true
),
()
=>
_runDevicelabTest
(
'plugin_dependencies_test'
,
environment:
gradleEnvironment
),
...
...
dev/devicelab/bin/tasks/module_custom_host_app_name_test.dart
0 → 100644
View file @
be6234d5
// Copyright 2014 The Flutter 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:async'
;
import
'dart:io'
;
import
'package:flutter_devicelab/framework/apk_utils.dart'
;
import
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/framework/utils.dart'
;
import
'package:path/path.dart'
as
path
;
final
String
gradlew
=
Platform
.
isWindows
?
'gradlew.bat'
:
'gradlew'
;
final
String
gradlewExecutable
=
Platform
.
isWindows
?
'.
\\
$gradlew
'
:
'./
$gradlew
'
;
final
String
fileReadWriteMode
=
Platform
.
isWindows
?
'rw-rw-rw-'
:
'rw-r--r--'
;
/// Tests that the Flutter module project template works and supports
/// adding Flutter to an existing Android app.
Future
<
void
>
main
()
async
{
await
task
(()
async
{
section
(
'Find Java'
);
final
String
javaHome
=
await
findJavaHome
();
if
(
javaHome
==
null
)
return
TaskResult
.
failure
(
'Could not find Java'
);
print
(
'
\n
Using JAVA_HOME=
$javaHome
'
);
section
(
'Create Flutter module project'
);
final
Directory
tempDir
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_module_test.'
);
final
Directory
projectDir
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello'
));
try
{
await
inDirectory
(
tempDir
,
()
async
{
await
flutter
(
'create'
,
options:
<
String
>[
'--org'
,
'io.flutter.devicelab'
,
'--template=module'
,
'hello'
],
);
});
section
(
'Add read-only asset'
);
final
File
readonlyTxtAssetFile
=
await
File
(
path
.
join
(
projectDir
.
path
,
'assets/read-only.txt'
))
.
create
(
recursive:
true
);
if
(!
exists
(
readonlyTxtAssetFile
))
{
return
TaskResult
.
failure
(
'Failed to create read-only asset'
);
}
if
(!
Platform
.
isWindows
)
{
await
exec
(
'chmod'
,
<
String
>[
'444'
,
readonlyTxtAssetFile
.
path
]);
}
final
File
pubspec
=
File
(
path
.
join
(
projectDir
.
path
,
'pubspec.yaml'
));
String
content
=
await
pubspec
.
readAsString
();
content
=
content
.
replaceFirst
(
'
\n
# assets:
\n
'
,
'
\n
assets:
\n
- assets/read-only.txt
\n
'
,
);
await
pubspec
.
writeAsString
(
content
,
flush:
true
);
section
(
'Add plugins'
);
content
=
await
pubspec
.
readAsString
();
content
=
content
.
replaceFirst
(
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
device_info: 0.4.1
\n
package_info: 0.4.0+9
\n
'
,
);
await
pubspec
.
writeAsString
(
content
,
flush:
true
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'packages'
,
options:
<
String
>[
'get'
],
);
});
section
(
'Build Flutter module library archive'
);
await
inDirectory
(
Directory
(
path
.
join
(
projectDir
.
path
,
'.android'
)),
()
async
{
await
exec
(
gradlewExecutable
,
<
String
>[
'flutter:assembleDebug'
],
environment:
<
String
,
String
>{
'JAVA_HOME'
:
javaHome
},
);
});
final
bool
aarBuilt
=
exists
(
File
(
path
.
join
(
projectDir
.
path
,
'.android'
,
'Flutter'
,
'build'
,
'outputs'
,
'aar'
,
'flutter-debug.aar'
,
)));
if
(!
aarBuilt
)
{
return
TaskResult
.
failure
(
'Failed to build .aar'
);
}
section
(
'Build ephemeral host app'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'apk'
],
);
});
final
bool
ephemeralHostApkBuilt
=
exists
(
File
(
path
.
join
(
projectDir
.
path
,
'build'
,
'host'
,
'outputs'
,
'apk'
,
'release'
,
'app-release.apk'
,
)));
if
(!
ephemeralHostApkBuilt
)
{
return
TaskResult
.
failure
(
'Failed to build ephemeral host .apk'
);
}
section
(
'Clean build'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'clean'
);
});
section
(
'Make Android host app editable'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'make-host-app-editable'
,
options:
<
String
>[
'android'
],
);
});
section
(
'Build editable host app'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'apk'
],
);
});
final
bool
editableHostApkBuilt
=
exists
(
File
(
path
.
join
(
projectDir
.
path
,
'build'
,
'host'
,
'outputs'
,
'apk'
,
'release'
,
'app-release.apk'
,
)));
if
(!
editableHostApkBuilt
)
{
return
TaskResult
.
failure
(
'Failed to build editable host .apk'
);
}
section
(
'Add to existing Android app'
);
final
Directory
hostApp
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello_host_app'
));
mkdir
(
hostApp
);
recursiveCopy
(
Directory
(
path
.
join
(
flutterDirectory
.
path
,
'dev'
,
'integration_tests'
,
'android_custom_host_app'
,
),
),
hostApp
,
);
copy
(
File
(
path
.
join
(
projectDir
.
path
,
'.android'
,
gradlew
)),
hostApp
,
);
copy
(
File
(
path
.
join
(
projectDir
.
path
,
'.android'
,
'gradle'
,
'wrapper'
,
'gradle-wrapper.jar'
)),
Directory
(
path
.
join
(
hostApp
.
path
,
'gradle'
,
'wrapper'
)),
);
final
File
analyticsOutputFile
=
File
(
path
.
join
(
tempDir
.
path
,
'analytics.log'
));
section
(
'Build debug host APK'
);
await
inDirectory
(
hostApp
,
()
async
{
if
(!
Platform
.
isWindows
)
{
await
exec
(
'chmod'
,
<
String
>[
'+x'
,
'gradlew'
]);
}
await
exec
(
gradlewExecutable
,
<
String
>[
'SampleApp:assembleDebug'
],
environment:
<
String
,
String
>{
'JAVA_HOME'
:
javaHome
,
'FLUTTER_ANALYTICS_LOG_FILE'
:
analyticsOutputFile
.
path
,
},
);
});
section
(
'Check debug APK exists'
);
final
String
debugHostApk
=
path
.
join
(
hostApp
.
path
,
'SampleApp'
,
'build'
,
'outputs'
,
'apk'
,
'debug'
,
'SampleApp-debug.apk'
,
);
if
(!
exists
(
File
(
debugHostApk
)))
{
return
TaskResult
.
failure
(
'Failed to build debug host APK'
);
}
section
(
'Check files in debug APK'
);
checkCollectionContains
<
String
>(<
String
>[
...
flutterAssets
,
...
debugAssets
,
...
baseApkFiles
,
],
await
getFilesInApk
(
debugHostApk
));
section
(
'Check debug AndroidManifest.xml'
);
final
String
androidManifestDebug
=
await
getAndroidManifest
(
debugHostApk
);
if
(!
androidManifestDebug
.
contains
(
'''
<meta-data
android:name="flutterProjectType"
android:value="module" />'''
)
)
{
return
TaskResult
.
failure
(
"Debug host APK doesn't contain metadata: flutterProjectType = module "
);
}
final
String
analyticsOutput
=
analyticsOutputFile
.
readAsStringSync
();
if
(!
analyticsOutput
.
contains
(
'cd24: android'
)
||
!
analyticsOutput
.
contains
(
'cd25: true'
)
||
!
analyticsOutput
.
contains
(
'viewName: assemble'
))
{
return
TaskResult
.
failure
(
'Building outer app produced the following analytics: "
$analyticsOutput
" '
'but not the expected strings: "cd24: android", "cd25: true" and '
'"viewName: assemble"'
);
}
section
(
'Check file access modes for read-only asset from Flutter module'
);
final
String
readonlyDebugAssetFilePath
=
path
.
join
(
hostApp
.
path
,
'SampleApp'
,
'build'
,
'intermediates'
,
'merged_assets'
,
'debug'
,
'out'
,
'flutter_assets/assets/read-only.txt'
,
);
final
File
readonlyDebugAssetFile
=
File
(
readonlyDebugAssetFilePath
);
if
(!
exists
(
readonlyDebugAssetFile
))
{
return
TaskResult
.
failure
(
'Failed to copy read-only asset file'
);
}
String
modes
=
readonlyDebugAssetFile
.
statSync
().
modeString
();
print
(
'
\n
read-only.txt file access modes =
$modes
'
);
if
(
modes
!=
null
&&
modes
.
compareTo
(
fileReadWriteMode
)
!=
0
)
{
return
TaskResult
.
failure
(
'Failed to make assets user-readable and writable'
);
}
section
(
'Build release host APK'
);
await
inDirectory
(
hostApp
,
()
async
{
await
exec
(
gradlewExecutable
,
<
String
>[
'SampleApp:assembleRelease'
],
environment:
<
String
,
String
>{
'JAVA_HOME'
:
javaHome
,
'FLUTTER_ANALYTICS_LOG_FILE'
:
analyticsOutputFile
.
path
,
},
);
});
final
String
releaseHostApk
=
path
.
join
(
hostApp
.
path
,
'SampleApp'
,
'build'
,
'outputs'
,
'apk'
,
'release'
,
'SampleApp-release-unsigned.apk'
,
);
if
(!
exists
(
File
(
releaseHostApk
)))
{
return
TaskResult
.
failure
(
'Failed to build release host APK'
);
}
section
(
'Check files in release APK'
);
checkCollectionContains
<
String
>(<
String
>[
...
flutterAssets
,
...
baseApkFiles
,
'lib/arm64-v8a/libapp.so'
,
'lib/arm64-v8a/libflutter.so'
,
'lib/armeabi-v7a/libapp.so'
,
'lib/armeabi-v7a/libflutter.so'
,
],
await
getFilesInApk
(
releaseHostApk
));
section
(
'Check release AndroidManifest.xml'
);
final
String
androidManifestRelease
=
await
getAndroidManifest
(
debugHostApk
);
if
(!
androidManifestRelease
.
contains
(
'''
<meta-data
android:name="flutterProjectType"
android:value="module" />'''
)
)
{
return
TaskResult
.
failure
(
"Release host APK doesn't contain metadata: flutterProjectType = module "
);
}
section
(
'Check file access modes for read-only asset from Flutter module'
);
final
String
readonlyReleaseAssetFilePath
=
path
.
join
(
hostApp
.
path
,
'SampleApp'
,
'build'
,
'intermediates'
,
'merged_assets'
,
'release'
,
'out'
,
'flutter_assets/assets/read-only.txt'
,
);
final
File
readonlyReleaseAssetFile
=
File
(
readonlyReleaseAssetFilePath
);
if
(!
exists
(
readonlyReleaseAssetFile
))
{
return
TaskResult
.
failure
(
'Failed to copy read-only asset file'
);
}
modes
=
readonlyReleaseAssetFile
.
statSync
().
modeString
();
print
(
'
\n
read-only.txt file access modes =
$modes
'
);
if
(
modes
!=
null
&&
modes
.
compareTo
(
fileReadWriteMode
)
!=
0
)
{
return
TaskResult
.
failure
(
'Failed to make assets user-readable and writable'
);
}
return
TaskResult
.
success
(
null
);
}
on
TaskResult
catch
(
taskResult
)
{
return
taskResult
;
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
finally
{
rmTree
(
tempDir
);
}
});
}
dev/integration_tests/android_custom_host_app/README.md
0 → 100644
View file @
be6234d5
# Android custom host app
Android host app for a Flutter module created using
```
$ flutter create -t module hello
```
and placed in a sibling folder to (a clone of) the host app.
Used by the
`module_custom_host_app_name_test.dart`
device lab test.
dev/integration_tests/android_custom_host_app/SampleApp/build.gradle
0 → 100644
View file @
be6234d5
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
apply
plugin:
'com.android.application'
android
{
compileSdkVersion
28
compileOptions
{
sourceCompatibility
1.8
targetCompatibility
1.8
}
defaultConfig
{
applicationId
"io.flutter.add2app"
minSdkVersion
16
targetSdkVersion
28
versionCode
1
versionName
"1.0"
}
}
dependencies
{
implementation
project
(
':flutter'
)
implementation
'androidx.appcompat:appcompat:1.1.0'
}
dev/integration_tests/android_custom_host_app/SampleApp/src/main/AndroidManifest.xml
0 → 100644
View file @
be6234d5
<!-- Copyright 2014 The Flutter Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
package=
"io.flutter.add2app"
>
<application
android:allowBackup=
"false"
tools:ignore=
"GoogleAppIndexingWarning,MissingApplicationIcon"
>
<activity
android:name=
".MainActivity"
/>
</application>
</manifest>
dev/integration_tests/android_custom_host_app/SampleApp/src/main/java/io/flutter/add2app/MainActivity.java
0 → 100644
View file @
be6234d5
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package
io
.
flutter
.
add2app
;
import
android.os.Bundle
;
import
androidx.appcompat.app.AppCompatActivity
;
import
io.flutter.embedding.android.FlutterActivity
;
public
class
MainActivity
extends
FlutterActivity
{
}
dev/integration_tests/android_custom_host_app/build.gradle
0 → 100644
View file @
be6234d5
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
buildscript
{
repositories
{
google
()
jcenter
()
}
dependencies
{
classpath
'com.android.tools.build:gradle:3.5.0'
}
}
allprojects
{
repositories
{
google
()
jcenter
()
}
}
task
clean
(
type:
Delete
)
{
delete
rootProject
.
buildDir
}
dev/integration_tests/android_custom_host_app/gradle.properties
0 → 100644
View file @
be6234d5
org.gradle.jvmargs
=
-Xmx1536m
android.useAndroidX
=
true
android.enableJetifier
=
true
flutter.hostAppProjectName
=
SampleApp
dev/integration_tests/android_custom_host_app/gradle/wrapper/gradle-wrapper.properties
0 → 100644
View file @
be6234d5
#Mon Jun 25 14:13:36 CEST 2018
distributionBase
=
GRADLE_USER_HOME
distributionPath
=
wrapper/dists
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-5.6.2-all.zip
dev/integration_tests/android_custom_host_app/local.properties
0 → 100644
View file @
be6234d5
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Thu Mar 26 18:32:27 GMT+07:00 2020
sdk.dir
=
/Users/alekseyanisov/Library/Android/sdk
dev/integration_tests/android_custom_host_app/settings.gradle
0 → 100644
View file @
be6234d5
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
include
':SampleApp'
setBinding
(
new
Binding
([
gradle:
this
]))
evaluate
(
new
File
(
settingsDir
.
parentFile
,
'hello/.android/include_flutter.groovy'
))
packages/flutter_tools/gradle/flutter.gradle
View file @
be6234d5
...
...
@@ -721,8 +721,9 @@ class FlutterPlugin implements Plugin<Project> {
return
}
// Flutter module included as a subproject in add to app.
Project
appProject
=
project
.
rootProject
.
findProject
(
':app'
)
assert
appProject
!=
null
String
hostAppProjectName
=
project
.
rootProject
.
hasProperty
(
'flutter.hostAppProjectName'
)
?
project
.
rootProject
.
property
(
'flutter.hostAppProjectName'
)
:
"app"
Project
appProject
=
project
.
rootProject
.
findProject
(
":${hostAppProjectName}"
)
assert
appProject
!=
null
:
"Project :${hostAppProjectName} doesn't exist. To custom the host app project name, set `org.gradle.project.flutter.hostAppProjectName=<project-name>` in gradle.properties."
appProject
.
afterEvaluate
{
assert
appProject
.
android
!=
null
appProject
.
android
.
applicationVariants
.
all
{
appProjectVariant
->
...
...
@@ -750,7 +751,7 @@ class FlutterPlugin implements Plugin<Project> {
}
Task
mergeAssets
=
project
.
tasks
.
findByPath
(
":
app
:merge${appProjectVariant.name.capitalize()}Assets"
)
.
findByPath
(
":
${hostAppProjectName}
:merge${appProjectVariant.name.capitalize()}Assets"
)
assert
mergeAssets
mergeAssets
.
dependsOn
(
copyFlutterAssetsTask
)
}
...
...
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