"Fossies" - the Fresh Open Source Software Archive

Member "flutter-1.22.4/dev/devicelab/bin/tasks/module_custom_host_app_name_test.dart" (13 Nov 2020, 10816 Bytes) of package /linux/misc/flutter-1.22.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Dart source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // Copyright 2014 The Flutter Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 import 'dart:async';
    6 import 'dart:io';
    7 
    8 import 'package:flutter_devicelab/framework/apk_utils.dart';
    9 import 'package:flutter_devicelab/framework/framework.dart';
   10 import 'package:flutter_devicelab/framework/utils.dart';
   11 import 'package:path/path.dart' as path;
   12 
   13 final String gradlew = Platform.isWindows ? 'gradlew.bat' : 'gradlew';
   14 final String gradlewExecutable = Platform.isWindows ? '.\\$gradlew' : './$gradlew';
   15 final String fileReadWriteMode = Platform.isWindows ? 'rw-rw-rw-' : 'rw-r--r--';
   16 
   17 /// Tests that the Flutter module project template works and supports
   18 /// adding Flutter to an existing Android app.
   19 Future<void> main() async {
   20   await task(() async {
   21 
   22     section('Find Java');
   23 
   24     final String javaHome = await findJavaHome();
   25     if (javaHome == null)
   26       return TaskResult.failure('Could not find Java');
   27     print('\nUsing JAVA_HOME=$javaHome');
   28 
   29     section('Create Flutter module project');
   30 
   31     final Directory tempDir = Directory.systemTemp.createTempSync('flutter_module_test.');
   32     final Directory projectDir = Directory(path.join(tempDir.path, 'hello'));
   33     try {
   34       await inDirectory(tempDir, () async {
   35         await flutter(
   36           'create',
   37           options: <String>['--org', 'io.flutter.devicelab', '--template=module', 'hello'],
   38         );
   39       });
   40 
   41       section('Add read-only asset');
   42 
   43       final File readonlyTxtAssetFile = await File(path.join(
   44         projectDir.path,
   45         'assets',
   46         'read-only.txt'
   47       ))
   48       .create(recursive: true);
   49 
   50       if (!exists(readonlyTxtAssetFile)) {
   51         return TaskResult.failure('Failed to create read-only asset');
   52       }
   53 
   54       if (!Platform.isWindows) {
   55         await exec('chmod', <String>[
   56           '444',
   57           readonlyTxtAssetFile.path
   58         ]);
   59       }
   60 
   61       final File pubspec = File(path.join(projectDir.path, 'pubspec.yaml'));
   62       String content = await pubspec.readAsString();
   63       content = content.replaceFirst(
   64         '\n  # assets:\n',
   65         '\n  assets:\n    - assets/read-only.txt\n',
   66       );
   67       await pubspec.writeAsString(content, flush: true);
   68 
   69       section('Add plugins');
   70 
   71       content = await pubspec.readAsString();
   72       content = content.replaceFirst(
   73         '\ndependencies:\n',
   74         '\ndependencies:\n  device_info: 0.4.1\n  package_info: 0.4.0+9\n',
   75       );
   76       await pubspec.writeAsString(content, flush: true);
   77       await inDirectory(projectDir, () async {
   78         await flutter(
   79           'packages',
   80           options: <String>['get'],
   81         );
   82       });
   83 
   84       section('Build Flutter module library archive');
   85 
   86       await inDirectory(Directory(path.join(projectDir.path, '.android')), () async {
   87         await exec(
   88           gradlewExecutable,
   89           <String>['flutter:assembleDebug'],
   90           environment: <String, String>{ 'JAVA_HOME': javaHome },
   91         );
   92       });
   93 
   94       final bool aarBuilt = exists(File(path.join(
   95         projectDir.path,
   96         '.android',
   97         'Flutter',
   98         'build',
   99         'outputs',
  100         'aar',
  101         'flutter-debug.aar',
  102       )));
  103 
  104       if (!aarBuilt) {
  105         return TaskResult.failure('Failed to build .aar');
  106       }
  107 
  108       section('Build ephemeral host app');
  109 
  110       await inDirectory(projectDir, () async {
  111         await flutter(
  112           'build',
  113           options: <String>['apk'],
  114         );
  115       });
  116 
  117       final bool ephemeralHostApkBuilt = exists(File(path.join(
  118         projectDir.path,
  119         'build',
  120         'host',
  121         'outputs',
  122         'apk',
  123         'release',
  124         'app-release.apk',
  125       )));
  126 
  127       if (!ephemeralHostApkBuilt) {
  128         return TaskResult.failure('Failed to build ephemeral host .apk');
  129       }
  130 
  131       section('Clean build');
  132 
  133       await inDirectory(projectDir, () async {
  134         await flutter('clean');
  135       });
  136 
  137       section('Make Android host app editable');
  138 
  139       await inDirectory(projectDir, () async {
  140         await flutter(
  141           'make-host-app-editable',
  142           options: <String>['android'],
  143         );
  144       });
  145 
  146       section('Build editable host app');
  147 
  148       await inDirectory(projectDir, () async {
  149         await flutter(
  150           'build',
  151           options: <String>['apk'],
  152         );
  153       });
  154 
  155       final bool editableHostApkBuilt = exists(File(path.join(
  156         projectDir.path,
  157         'build',
  158         'host',
  159         'outputs',
  160         'apk',
  161         'release',
  162         'app-release.apk',
  163       )));
  164 
  165       if (!editableHostApkBuilt) {
  166         return TaskResult.failure('Failed to build editable host .apk');
  167       }
  168 
  169       section('Add to existing Android app');
  170 
  171       final Directory hostApp = Directory(path.join(tempDir.path, 'hello_host_app'));
  172       mkdir(hostApp);
  173       recursiveCopy(
  174         Directory(
  175           path.join(
  176             flutterDirectory.path,
  177             'dev',
  178             'integration_tests',
  179             'android_custom_host_app',
  180           ),
  181         ),
  182         hostApp,
  183       );
  184       copy(
  185         File(path.join(projectDir.path, '.android', gradlew)),
  186         hostApp,
  187       );
  188       copy(
  189         File(path.join(projectDir.path, '.android', 'gradle', 'wrapper', 'gradle-wrapper.jar')),
  190         Directory(path.join(hostApp.path, 'gradle', 'wrapper')),
  191       );
  192 
  193       final File analyticsOutputFile = File(path.join(tempDir.path, 'analytics.log'));
  194 
  195       section('Build debug host APK');
  196 
  197       await inDirectory(hostApp, () async {
  198         if (!Platform.isWindows) {
  199           await exec('chmod', <String>['+x', 'gradlew']);
  200         }
  201         await exec(gradlewExecutable,
  202           <String>['SampleApp:assembleDebug'],
  203           environment: <String, String>{
  204             'JAVA_HOME': javaHome,
  205             'FLUTTER_ANALYTICS_LOG_FILE': analyticsOutputFile.path,
  206           },
  207         );
  208       });
  209 
  210       section('Check debug APK exists');
  211 
  212       final String debugHostApk = path.join(
  213         hostApp.path,
  214         'SampleApp',
  215         'build',
  216         'outputs',
  217         'apk',
  218         'debug',
  219         'SampleApp-debug.apk',
  220       );
  221       if (!exists(File(debugHostApk))) {
  222         return TaskResult.failure('Failed to build debug host APK');
  223       }
  224 
  225       section('Check files in debug APK');
  226 
  227       checkCollectionContains<String>(<String>[
  228         ...flutterAssets,
  229         ...debugAssets,
  230         ...baseApkFiles,
  231       ], await getFilesInApk(debugHostApk));
  232 
  233       section('Check debug AndroidManifest.xml');
  234 
  235       final String androidManifestDebug = await getAndroidManifest(debugHostApk);
  236       if (!androidManifestDebug.contains('''
  237         <meta-data
  238             android:name="flutterProjectType"
  239             android:value="module" />''')
  240       ) {
  241         return TaskResult.failure("Debug host APK doesn't contain metadata: flutterProjectType = module ");
  242       }
  243 
  244       final String analyticsOutput = analyticsOutputFile.readAsStringSync();
  245       if (!analyticsOutput.contains('cd24: android')
  246           || !analyticsOutput.contains('cd25: true')
  247           || !analyticsOutput.contains('viewName: assemble')) {
  248         return TaskResult.failure(
  249           'Building outer app produced the following analytics: "$analyticsOutput" '
  250           'but not the expected strings: "cd24: android", "cd25: true" and '
  251           '"viewName: assemble"'
  252         );
  253       }
  254 
  255       section('Check file access modes for read-only asset from Flutter module');
  256 
  257       final String readonlyDebugAssetFilePath = path.joinAll(<String>[
  258         hostApp.path,
  259         'SampleApp',
  260         'build',
  261         'intermediates',
  262         'merged_assets',
  263         'debug',
  264         'out',
  265         'flutter_assets',
  266         'assets',
  267         'read-only.txt',
  268       ]);
  269       final File readonlyDebugAssetFile = File(readonlyDebugAssetFilePath);
  270       if (!exists(readonlyDebugAssetFile)) {
  271         return TaskResult.failure('Failed to copy read-only asset file');
  272       }
  273 
  274       String modes = readonlyDebugAssetFile.statSync().modeString();
  275       print('\nread-only.txt file access modes = $modes');
  276       if (modes != null && modes.compareTo(fileReadWriteMode) != 0) {
  277         return TaskResult.failure('Failed to make assets user-readable and writable');
  278       }
  279 
  280       section('Build release host APK');
  281 
  282       await inDirectory(hostApp, () async {
  283         await exec(gradlewExecutable,
  284           <String>['SampleApp:assembleRelease'],
  285           environment: <String, String>{
  286             'JAVA_HOME': javaHome,
  287             'FLUTTER_ANALYTICS_LOG_FILE': analyticsOutputFile.path,
  288           },
  289         );
  290       });
  291 
  292       final String releaseHostApk = path.join(
  293         hostApp.path,
  294         'SampleApp',
  295         'build',
  296         'outputs',
  297         'apk',
  298         'release',
  299         'SampleApp-release-unsigned.apk',
  300       );
  301       if (!exists(File(releaseHostApk))) {
  302         return TaskResult.failure('Failed to build release host APK');
  303       }
  304 
  305       section('Check files in release APK');
  306 
  307       checkCollectionContains<String>(<String>[
  308         ...flutterAssets,
  309         ...baseApkFiles,
  310         'lib/arm64-v8a/libapp.so',
  311         'lib/arm64-v8a/libflutter.so',
  312         'lib/armeabi-v7a/libapp.so',
  313         'lib/armeabi-v7a/libflutter.so',
  314       ], await getFilesInApk(releaseHostApk));
  315 
  316       section('Check release AndroidManifest.xml');
  317 
  318       final String androidManifestRelease = await getAndroidManifest(debugHostApk);
  319       if (!androidManifestRelease.contains('''
  320         <meta-data
  321             android:name="flutterProjectType"
  322             android:value="module" />''')
  323       ) {
  324         return TaskResult.failure("Release host APK doesn't contain metadata: flutterProjectType = module ");
  325       }
  326 
  327       section('Check file access modes for read-only asset from Flutter module');
  328 
  329       final String readonlyReleaseAssetFilePath = path.joinAll(<String>[
  330         hostApp.path,
  331         'SampleApp',
  332         'build',
  333         'intermediates',
  334         'merged_assets',
  335         'release',
  336         'out',
  337         'flutter_assets',
  338         'assets',
  339         'read-only.txt',
  340       ]);
  341       final File readonlyReleaseAssetFile = File(readonlyReleaseAssetFilePath);
  342       if (!exists(readonlyReleaseAssetFile)) {
  343         return TaskResult.failure('Failed to copy read-only asset file');
  344       }
  345 
  346       modes = readonlyReleaseAssetFile.statSync().modeString();
  347       print('\nread-only.txt file access modes = $modes');
  348       if (modes != null && modes.compareTo(fileReadWriteMode) != 0) {
  349         return TaskResult.failure('Failed to make assets user-readable and writable');
  350       }
  351 
  352       return TaskResult.success(null);
  353     } on TaskResult catch (taskResult) {
  354       return taskResult;
  355     } catch (e) {
  356       return TaskResult.failure(e.toString());
  357     } finally {
  358       rmTree(tempDir);
  359     }
  360   });
  361 }