blob: a016e0a1ae8aad9f46ae1496ddcee8f0dffe10d5 [file] [log] [blame]
// 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 'package:xml/xml.dart';
import '../base/file_system.dart';
// These utility methods are used to generate the code for multidex support as
// well as verifying the project is properly set up.
File _getMultiDexApplicationFile(Directory projectDir) {
return projectDir.childDirectory('android')
.childDirectory('app')
.childDirectory('src')
.childDirectory('main')
.childDirectory('java')
.childDirectory('io')
.childDirectory('flutter')
.childDirectory('app')
.childFile('FlutterMultiDexApplication.java');
}
/// Creates the FlutterMultiDexApplication.java if it does not exist.
void ensureMultiDexApplicationExists(final Directory projectDir) {
final File applicationFile = _getMultiDexApplicationFile(projectDir);
if (applicationFile.existsSync()) {
return;
}
applicationFile.createSync(recursive: true);
final StringBuffer buffer = StringBuffer();
buffer.write('''
// Generated file.
// If you wish to remove Flutter's multidex support, delete this entire file.
package io.flutter.app;
import android.content.Context;
import androidx.annotation.CallSuper;
import androidx.multidex.MultiDex;
/**
* Extension of {@link io.flutter.app.FlutterApplication}, adding multidex support.
*/
public class FlutterMultiDexApplication extends FlutterApplication {
@Override
@CallSuper
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
''');
applicationFile.writeAsStringSync(buffer.toString(), flush: true);
}
/// Returns true if FlutterMultiDexApplication.java exists.
///
/// This function does not verify the contents of the file.
bool multiDexApplicationExists(final Directory projectDir) {
if (_getMultiDexApplicationFile(projectDir).existsSync()) {
return true;
}
return false;
}
File _getManifestFile(Directory projectDir) {
return projectDir.childDirectory('android')
.childDirectory('app')
.childDirectory('src')
.childDirectory('main')
.childFile('AndroidManifest.xml');
}
/// Returns true if the `app` module AndroidManifest.xml includes the
/// <application android:name="${applicationName}"> attribute.
bool androidManifestHasNameVariable(final Directory projectDir) {
final File manifestFile = _getManifestFile(projectDir);
if (!manifestFile.existsSync()) {
return false;
}
XmlDocument document;
try {
document = XmlDocument.parse(manifestFile.readAsStringSync());
} on XmlParserException {
return false;
} on FileSystemException {
return false;
}
// Check for the ${androidName} application attribute.
for (final XmlElement application in document.findAllElements('application')) {
final String? applicationName = application.getAttribute('android:name');
if (applicationName == r'${applicationName}') {
return true;
}
}
return false;
}