module_host_with_custom_build_test.dart 8.07 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7 8
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:io';

import 'package:flutter_devicelab/framework/apk_utils.dart';
import 'package:flutter_devicelab/framework/framework.dart';
9
import 'package:flutter_devicelab/framework/task_result.dart';
10 11 12 13
import 'package:flutter_devicelab/framework/utils.dart';
import 'package:path/path.dart' as path;

final String gradlew = Platform.isWindows ? 'gradlew.bat' : 'gradlew';
14
final String gradlewExecutable = Platform.isWindows ? '.\\$gradlew' : './$gradlew';
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

/// Tests that the Android app containing a Flutter module can be built when
/// it has custom build types and flavors.
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('\nUsing JAVA_HOME=$javaHome');

    section('Create Flutter module project');

32 33 34 35 36
    await flutter(
      'precache',
      options: <String>['--android', '--no-ios'],
    );

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
    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('Run flutter pub get');

      await inDirectory(projectDir, () async {
        await flutter(
          'pub',
          options: <String>['get'],
        );
      });

      section('Add to existing Android app');

      final Directory hostAppDir = Directory(path.join(tempDir.path, 'hello_host_app_with_custom_build'));
      mkdir(hostAppDir);
      recursiveCopy(
61 62 63 64 65
        Directory(
          path.join(
            flutterDirectory.path,
            'dev',
            'integration_tests',
66
            'module_host_with_custom_build_v2_embedding',
67 68
          ),
        ),
69 70 71 72 73 74 75 76 77 78 79
        hostAppDir,
      );
      copy(
        File(path.join(projectDir.path, '.android', gradlew)),
        hostAppDir,
      );
      copy(
        File(path.join(projectDir.path, '.android', 'gradle', 'wrapper', 'gradle-wrapper.jar')),
        Directory(path.join(hostAppDir.path, 'gradle', 'wrapper')),
      );

80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
      final Function clean = () async {
        section('Clean');
        await inDirectory(hostAppDir, () async {
          await exec(gradlewExecutable,
            <String>['clean'],
            environment: <String, String>{
              'JAVA_HOME': javaHome,
            },
          );
        });
      };

      if (!Platform.isWindows) {
        section('Make $gradlewExecutable executable');
        await inDirectory(hostAppDir, () async {
          await exec('chmod', <String>['+x', gradlewExecutable]);
        });
      }

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
      section('Build debug APKs');

      section('Run app:assembleDemoDebug');

      await inDirectory(hostAppDir, () async {
        await exec(gradlewExecutable,
          <String>['app:assembleDemoDebug'],
          environment: <String, String>{
            'JAVA_HOME': javaHome,
          },
        );
      });

      final String demoDebugApk = path.join(
        hostAppDir.path,
        'app',
        'build',
        'outputs',
        'apk',
        'demo',
        'debug',
        'app-demo-debug.apk',
      );

      if (!exists(File(demoDebugApk))) {
        return TaskResult.failure('Failed to build app-demo-debug.apk');
      }

      section('Verify snapshots in app-demo-debug.apk');

129
      checkCollectionContains<String>(<String>[
130
        ...flutterAssets,
131
        ...debugAssets,
132 133 134
      ], await getFilesInApk(demoDebugApk));

      await clean();
135

136 137 138
      // Change the order of the task and ensure that flutter_assets are in the APK.
      // https://github.com/flutter/flutter/pull/41333
      section('Run app:assembleDemoDebug - Merge assets before processing manifest');
139 140 141

      await inDirectory(hostAppDir, () async {
        await exec(gradlewExecutable,
142 143 144 145 146 147 148
          <String>[
            // Normally, `app:processDemoDebugManifest` runs before `app:mergeDemoDebugAssets`.
            // In this case, we run `app:mergeDemoDebugAssets` first.
            'app:mergeDemoDebugAssets',
            'app:processDemoDebugManifest',
            'app:assembleDemoDebug',
          ],
149 150 151 152 153 154
          environment: <String, String>{
            'JAVA_HOME': javaHome,
          },
        );
      });

155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
      final String demoDebugApk2 = path.join(
        hostAppDir.path,
        'app',
        'build',
        'outputs',
        'apk',
        'demo',
        'debug',
        'app-demo-debug.apk',
      );

      if (!exists(File(demoDebugApk2))) {
        return TaskResult.failure('Failed to build app-demo-debug.apk');
      }

      section('Verify snapshots in app-demo-debug.apk');

172
      checkCollectionContains<String>(<String>[
173
        ...flutterAssets,
174
        ...debugAssets,
175 176 177 178
      ], await getFilesInApk(demoDebugApk2));

      await clean();

179 180
      section('Run app:assembleDemoStaging');

181
      await inDirectory(hostAppDir, () async {
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
        await exec(gradlewExecutable,
          <String>['app:assembleDemoStaging'],
          environment: <String, String>{
            'JAVA_HOME': javaHome,
          },
        );
      });

      final String demoStagingApk = path.join(
        hostAppDir.path,
        'app',
        'build',
        'outputs',
        'apk',
        'demo',
        'staging',
        'app-demo-staging.apk',
      );

      if (!exists(File(demoStagingApk))) {
        return TaskResult.failure('Failed to build app-demo-staging.apk');
      }

      section('Verify snapshots in app-demo-staging.apk');

207
      checkCollectionContains<String>(<String>[
208
        ...flutterAssets,
209
        ...debugAssets,
210
      ], await getFilesInApk(demoStagingApk));
211

212
      await clean();
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241

      section('Build release APKs');

      section('Run app:assembleDemoRelease');

      await inDirectory(hostAppDir, () async {
        await exec(gradlewExecutable,
          <String>['app:assembleDemoRelease'],
          environment: <String, String>{
            'JAVA_HOME': javaHome,
          },
        );
      });

      final String demoReleaseApk = path.join(
        hostAppDir.path,
        'app',
        'build',
        'outputs',
        'apk',
        'demo',
        'release',
        'app-demo-release-unsigned.apk',
      );

      if (!exists(File(demoReleaseApk))) {
        return TaskResult.failure('Failed to build app-demo-release-unsigned.apk');
      }

242
      section('Verify AOT ELF in app-demo-release-unsigned.apk');
243

244
      checkCollectionContains<String>(<String>[
245
        ...flutterAssets,
246
        'lib/arm64-v8a/libflutter.so',
247
        'lib/arm64-v8a/libapp.so',
248
        'lib/armeabi-v7a/libflutter.so',
249
        'lib/armeabi-v7a/libapp.so',
250
      ], await getFilesInApk(demoReleaseApk));
251

252
      await clean();
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279

      section('Run app:assembleDemoProd');

       await inDirectory(hostAppDir, () async {
        await exec(gradlewExecutable,
          <String>['app:assembleDemoProd'],
          environment: <String, String>{
            'JAVA_HOME': javaHome,
          },
        );
      });

      final String demoProdApk = path.join(
        hostAppDir.path,
        'app',
        'build',
        'outputs',
        'apk',
        'demo',
        'prod',
        'app-demo-prod-unsigned.apk',
      );

      if (!exists(File(demoProdApk))) {
        return TaskResult.failure('Failed to build app-demo-prod-unsigned.apk');
      }

280
      section('Verify AOT ELF in app-demo-prod-unsigned.apk');
281

282
      checkCollectionContains<String>(<String>[
283 284 285 286 287 288
        ...flutterAssets,
        'lib/arm64-v8a/libapp.so',
        'lib/arm64-v8a/libflutter.so',
        'lib/armeabi-v7a/libapp.so',
        'lib/armeabi-v7a/libflutter.so',
      ], await getFilesInApk(demoProdApk));
289 290 291 292 293 294 295 296 297 298 299

      return TaskResult.success(null);
    } on TaskResult catch (taskResult) {
      return taskResult;
    } catch (e) {
      return TaskResult.failure(e.toString());
    } finally {
      rmTree(tempDir);
    }
  });
}