Unverified Commit 944fcda6 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] remove UWP tooling (#102174)

parent a75743e8
# 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.
# Retrieves the AMUID from a given application name
[CmdletBinding()]
param(
[Parameter()]
[string]$Name
)
$foo = get-appxpackage | Where-Object { $_.Name -like $name }
$aumid = $foo.packagefamilyname + "!" + (Get-AppxPackageManifest $foo).package.applications.application.id
Write-Output $aumid
......@@ -61,9 +61,8 @@ or
else
'flutter'
]);
final bool uwp = targetPlatform.contains('uwp');
final String bundlePlatform = targetPlatform.startsWith('windows') ? 'windows' : targetPlatform;
final String target = '${buildMode}_bundle_${bundlePlatform}_assets${uwp ? '_uwp' : ''}';
final String target = '${buildMode}_bundle_${bundlePlatform}_assets';
final Process assembleProcess = await Process.start(
flutterExecutable,
<String>[
......
......@@ -227,7 +227,6 @@ class AndroidDevice extends Device {
case TargetPlatform.linux_x64:
case TargetPlatform.tester:
case TargetPlatform.web_javascript:
case TargetPlatform.windows_uwp_x64:
case TargetPlatform.windows_x64:
throw UnsupportedError('Invalid target platform for Android');
}
......@@ -565,7 +564,6 @@ class AndroidDevice extends Device {
case TargetPlatform.linux_x64:
case TargetPlatform.tester:
case TargetPlatform.web_javascript:
case TargetPlatform.windows_uwp_x64:
case TargetPlatform.windows_x64:
_logger.printError('Android platforms are only supported.');
return LaunchResult.failed();
......
......@@ -38,10 +38,7 @@ enum Artifact {
windowsDesktopPath,
/// The root of the cpp client code for Windows desktop.
windowsCppClientWrapper,
/// The root of the cpp client code for Windows UWP desktop.
windowsUwpCppClientWrapper,
/// The root of the Windows UWP desktop sources.
windowsUwpDesktopPath,
/// The root of the sky_engine package.
skyEnginePath,
/// The location of the macOS engine podspec file.
......@@ -54,9 +51,6 @@ enum Artifact {
/// Tools related to subsetting or icon font files.
fontSubset,
constFinder,
// Windows UWP app management tool.
uwptool,
}
/// A subset of [Artifact]s that are platform and build mode independent
......@@ -120,7 +114,6 @@ TargetPlatform? _mapTargetPlatform(TargetPlatform? targetPlatform) {
case TargetPlatform.linux_x64:
case TargetPlatform.linux_arm64:
case TargetPlatform.windows_x64:
case TargetPlatform.windows_uwp_x64:
case TargetPlatform.fuchsia_arm64:
case TargetPlatform.fuchsia_x64:
case TargetPlatform.tester:
......@@ -137,7 +130,6 @@ TargetPlatform? _mapTargetPlatform(TargetPlatform? targetPlatform) {
bool _isWindows(TargetPlatform? platform) {
switch (platform) {
case TargetPlatform.windows_x64:
case TargetPlatform.windows_uwp_x64:
return true;
case TargetPlatform.android:
case TargetPlatform.android_arm:
......@@ -190,9 +182,7 @@ String? _artifactToFileName(Artifact artifact, [ TargetPlatform? platform, Build
case Artifact.linuxHeaders:
return 'flutter_linux';
case Artifact.windowsCppClientWrapper:
case Artifact.windowsUwpCppClientWrapper:
return 'cpp_client_wrapper';
case Artifact.windowsUwpDesktopPath:
case Artifact.windowsDesktopPath:
return '';
case Artifact.skyEnginePath:
......@@ -209,8 +199,6 @@ String? _artifactToFileName(Artifact artifact, [ TargetPlatform? platform, Build
return 'font-subset$exe';
case Artifact.constFinder:
return 'const_finder.dart.snapshot';
case Artifact.uwptool:
return 'uwptool$exe';
}
}
......@@ -431,7 +419,6 @@ class CachedArtifacts implements Artifacts {
case TargetPlatform.linux_x64:
case TargetPlatform.linux_arm64:
case TargetPlatform.windows_x64:
case TargetPlatform.windows_uwp_x64:
return _getDesktopArtifactPath(artifact, platform, mode);
case TargetPlatform.fuchsia_arm64:
case TargetPlatform.fuchsia_x64:
......@@ -483,12 +470,9 @@ class CachedArtifacts implements Artifacts {
case Artifact.platformKernelDill:
case Artifact.platformLibrariesJson:
case Artifact.skyEnginePath:
case Artifact.uwptool:
case Artifact.vmSnapshotData:
case Artifact.windowsCppClientWrapper:
case Artifact.windowsDesktopPath:
case Artifact.windowsUwpCppClientWrapper:
case Artifact.windowsUwpDesktopPath:
return _getHostArtifactPath(artifact, platform, mode);
}
}
......@@ -519,12 +503,9 @@ class CachedArtifacts implements Artifacts {
case Artifact.platformKernelDill:
case Artifact.platformLibrariesJson:
case Artifact.skyEnginePath:
case Artifact.uwptool:
case Artifact.vmSnapshotData:
case Artifact.windowsCppClientWrapper:
case Artifact.windowsDesktopPath:
case Artifact.windowsUwpCppClientWrapper:
case Artifact.windowsUwpDesktopPath:
return _getHostArtifactPath(artifact, platform, mode);
}
}
......@@ -567,12 +548,9 @@ class CachedArtifacts implements Artifacts {
case Artifact.linuxHeaders:
case Artifact.platformLibrariesJson:
case Artifact.skyEnginePath:
case Artifact.uwptool:
case Artifact.vmSnapshotData:
case Artifact.windowsCppClientWrapper:
case Artifact.windowsDesktopPath:
case Artifact.windowsUwpCppClientWrapper:
case Artifact.windowsUwpDesktopPath:
return _getHostArtifactPath(artifact, platform, mode);
}
}
......@@ -626,15 +604,9 @@ class CachedArtifacts implements Artifacts {
}
final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
return _fileSystem.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact, platform, mode));
case Artifact.windowsUwpDesktopPath:
final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
return _fileSystem.path.join(engineArtifactsPath, 'windows-uwp-x64-${getNameForBuildMode(mode!)}', _artifactToFileName(artifact, platform, mode));
case Artifact.windowsCppClientWrapper:
final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
return _fileSystem.path.join(engineArtifactsPath, 'windows-x64', _artifactToFileName(artifact, platform, mode));
case Artifact.windowsUwpCppClientWrapper:
final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
return _fileSystem.path.join(engineArtifactsPath, 'windows-uwp-x64-debug', _artifactToFileName(artifact, platform, mode));
case Artifact.skyEnginePath:
final Directory dartPackageDirectory = _cache.getCacheDir('pkg');
return _fileSystem.path.join(dartPackageDirectory.path, _artifactToFileName(artifact));
......@@ -644,11 +616,6 @@ class CachedArtifacts implements Artifacts {
.childDirectory(_enginePlatformDirectoryName(platform))
.childFile(_artifactToFileName(artifact, platform, mode)!)
.path;
case Artifact.uwptool:
return _cache.getArtifactDirectory('engine')
.childDirectory('windows-uwp-x64-${getNameForBuildMode(mode ?? BuildMode.debug)}')
.childFile(_artifactToFileName(artifact, platform, mode)!)
.path;
case Artifact.flutterFramework:
case Artifact.flutterXcframework:
case Artifact.fuchsiaFlutterRunner:
......@@ -684,7 +651,6 @@ class CachedArtifacts implements Artifacts {
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
case TargetPlatform.windows_uwp_x64:
assert(mode != null, 'Need to specify a build mode for platform $platform.');
final String suffix = mode != BuildMode.debug ? '-${snakeCase(getModeName(mode!), '-')}' : '';
return _fileSystem.path.join(engineDir, platformName + suffix);
......@@ -914,19 +880,15 @@ class CachedLocalEngineArtifacts implements LocalEngineArtifacts {
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
case Artifact.constFinder:
return _fileSystem.path.join(_hostEngineOutPath, 'gen', artifactFileName);
case Artifact.windowsUwpDesktopPath:
case Artifact.linuxDesktopPath:
case Artifact.linuxHeaders:
case Artifact.windowsDesktopPath:
case Artifact.windowsCppClientWrapper:
case Artifact.windowsUwpCppClientWrapper:
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
case Artifact.frontendServerSnapshotForEngineDartSdk:
return _fileSystem.path.join(
_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', artifactFileName,
);
case Artifact.uwptool:
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
}
}
......
......@@ -314,7 +314,6 @@ class AOTSnapshotter {
TargetPlatform.linux_x64,
TargetPlatform.linux_arm64,
TargetPlatform.windows_x64,
TargetPlatform.windows_uwp_x64,
].contains(platform);
}
}
......@@ -527,7 +527,6 @@ enum TargetPlatform {
linux_x64,
linux_arm64,
windows_x64,
windows_uwp_x64,
fuchsia_arm64,
fuchsia_x64,
tester,
......@@ -660,8 +659,6 @@ String getNameForTargetPlatform(TargetPlatform platform, {DarwinArch? darwinArch
return 'linux-arm64';
case TargetPlatform.windows_x64:
return 'windows-x64';
case TargetPlatform.windows_uwp_x64:
return 'windows-uwp-x64';
case TargetPlatform.fuchsia_arm64:
return 'fuchsia-arm64';
case TargetPlatform.fuchsia_x64:
......@@ -705,8 +702,6 @@ TargetPlatform getTargetPlatformForName(String platform) {
return TargetPlatform.linux_arm64;
case 'windows-x64':
return TargetPlatform.windows_x64;
case 'windows-uwp-x64':
return TargetPlatform.windows_uwp_x64;
case 'web-javascript':
return TargetPlatform.web_javascript;
}
......@@ -770,7 +765,6 @@ String fuchsiaArchForTargetPlatform(TargetPlatform targetPlatform) {
case TargetPlatform.linux_x64:
case TargetPlatform.tester:
case TargetPlatform.web_javascript:
case TargetPlatform.windows_uwp_x64:
case TargetPlatform.windows_x64:
throw UnsupportedError('Unexpected Fuchsia platform $targetPlatform');
}
......@@ -859,11 +853,6 @@ String getWindowsBuildDirectory() {
return globals.fs.path.join(getBuildDirectory(), 'windows');
}
/// Returns the Windows UWP build output directory.
String getWindowsBuildUwpDirectory() {
return globals.fs.path.join(getBuildDirectory(), 'winuwp');
}
/// Returns the Fuchsia build output directory.
String getFuchsiaBuildDirectory() {
return globals.fs.path.join(getBuildDirectory(), 'fuchsia');
......@@ -1030,7 +1019,6 @@ String getNameForTargetPlatformArch(TargetPlatform platform) {
case TargetPlatform.ios:
case TargetPlatform.tester:
case TargetPlatform.web_javascript:
case TargetPlatform.windows_uwp_x64:
throw UnsupportedError('Unexpected target platform $platform');
}
}
......
......@@ -204,7 +204,6 @@ class KernelSnapshot extends Target {
case TargetPlatform.linux_arm64:
case TargetPlatform.tester:
case TargetPlatform.web_javascript:
case TargetPlatform.windows_uwp_x64:
forceLinkPlatform = false;
break;
}
......
......@@ -26,20 +26,7 @@ const List<String> _kWindowsArtifacts = <String>[
'flutter_windows.h',
];
const List<String> _kWindowsUwpArtifacts = <String>[
'flutter_windows_winuwp.dll',
'flutter_windows_winuwp.dll.exp',
'flutter_windows_winuwp.dll.lib',
'flutter_windows_winuwp.dll.pdb',
'flutter_export.h',
'flutter_messenger.h',
'flutter_plugin_registrar.h',
'flutter_texture_registrar.h',
'flutter_windows.h',
];
const String _kWindowsDepfile = 'windows_engine_sources.d';
const String _kWindowsUwpDepfile = 'windows_uwp_engine_sources.d';
/// Copies the Windows desktop embedding files to the copy directory.
class UnpackWindows extends Target {
......@@ -111,84 +98,6 @@ class UnpackWindows extends Target {
}
}
/// Copies the Windows desktop embedding files to the copy directory.
class UnpackWindowsUwp extends Target {
const UnpackWindowsUwp();
@override
String get name => 'unpack_windows_uwp';
@override
List<Source> get inputs => const <Source>[
Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/windows.dart'),
];
@override
List<Source> get outputs => const <Source>[];
@override
List<String> get depfiles => const <String>[_kWindowsUwpDepfile];
@override
List<Target> get dependencies => const <Target>[];
@override
Future<void> build(Environment environment) async {
final String? buildModeEnvironment = environment.defines[kBuildMode];
if (buildModeEnvironment == null) {
throw MissingDefineException(kBuildMode, name);
}
final BuildMode buildMode = getBuildModeForName(buildModeEnvironment);
final String engineSourcePath = environment.artifacts
.getArtifactPath(
Artifact.windowsUwpDesktopPath,
platform: TargetPlatform.windows_x64,
mode: buildMode,
);
final String clientSourcePath = environment.artifacts
.getArtifactPath(
Artifact.windowsUwpCppClientWrapper,
platform: TargetPlatform.windows_x64,
mode: buildMode,
);
final Directory outputDirectory = environment.fileSystem.directory(
environment.fileSystem.path.join(
environment.projectDir.path,
'winuwp',
'flutter',
'ephemeral',
),
);
final Depfile depfile = unpackDesktopArtifacts(
fileSystem: environment.fileSystem,
artifacts: _kWindowsUwpArtifacts,
engineSourcePath: engineSourcePath,
outputDirectory: outputDirectory,
clientSourcePaths: <String>[clientSourcePath],
icuDataPath: environment.artifacts.getArtifactPath(
Artifact.icuData,
platform: TargetPlatform.windows_x64
)
);
// Copy flutter_windows.h into flutter directory as well.
final File flutterWindows = outputDirectory.childFile('flutter_windows.h');
final File flutterWindowsDest = flutterWindows.parent.parent.childFile('flutter_windows.h');
flutterWindows.copySync(flutterWindowsDest.path);
depfile.outputs.add(flutterWindowsDest);
//
final DepfileService depfileService = DepfileService(
fileSystem: environment.fileSystem,
logger: environment.logger,
);
depfileService.writeToFile(
depfile,
environment.buildDir.childFile(_kWindowsUwpDepfile),
);
}
}
/// Creates a bundle for the Windows desktop target.
abstract class BundleWindowsAssets extends Target {
const BundleWindowsAssets();
......@@ -245,31 +154,16 @@ abstract class BundleWindowsAssets extends Target {
}
}
/// Creates a bundle for the Windows desktop target.
abstract class BundleWindowsAssetsUwp extends BundleWindowsAssets {
const BundleWindowsAssetsUwp();
@override
List<Target> get dependencies => const <Target>[
KernelSnapshot(),
UnpackWindowsUwp(),
];
}
/// A wrapper for AOT compilation that copies app.so into the output directory.
class WindowsAotBundle extends Target {
/// Create a [WindowsAotBundle] wrapper for [aotTarget].
const WindowsAotBundle(this.aotTarget, {required this.uwp});
const WindowsAotBundle(this.aotTarget);
/// The [AotElfBase] subclass that produces the app.so.
final AotElfBase aotTarget;
/// Whether this is the UWP target.
final bool uwp;
@override
String get name => uwp ? 'windows_uwp_aot_bundle' : 'windows_aot_bundle';
String get name => 'windows_aot_bundle';
@override
List<Source> get inputs => const <Source>[
......@@ -277,10 +171,7 @@ class WindowsAotBundle extends Target {
];
@override
List<Source> get outputs => uwp ?
const <Source>[
Source.pattern('{OUTPUT_DIR}/winuwp/app.so'),
] :
List<Source> get outputs =>
const <Source>[
Source.pattern('{OUTPUT_DIR}/windows/app.so'),
];
......@@ -293,44 +184,7 @@ class WindowsAotBundle extends Target {
@override
Future<void> build(Environment environment) async {
final File outputFile = environment.buildDir.childFile('app.so');
final Directory outputDirectory = environment.outputDir.childDirectory(uwp ? 'winuwp' : 'windows');
if (!outputDirectory.existsSync()) {
outputDirectory.createSync(recursive: true);
}
outputFile.copySync(outputDirectory.childFile('app.so').path);
}
}
/// A wrapper for AOT compilation that copies app.so into the output directory.
class WindowsUwpAotBundle extends Target {
/// Create a [WindowsAotBundle] wrapper for [aotTarget].
const WindowsUwpAotBundle(this.aotTarget);
/// The [AotElfBase] subclass that produces the app.so.
final AotElfBase aotTarget;
@override
String get name => 'windows_uwp_aot_bundle';
@override
List<Source> get inputs => const <Source>[
Source.pattern('{BUILD_DIR}/app.so'),
];
@override
List<Source> get outputs => const <Source>[
Source.pattern('{OUTPUT_DIR}/winuwp/app.so'),
];
@override
List<Target> get dependencies => <Target>[
aotTarget,
];
@override
Future<void> build(Environment environment) async {
final File outputFile = environment.buildDir.childFile('app.so');
final Directory outputDirectory = environment.outputDir.childDirectory('winuwp');
final Directory outputDirectory = environment.outputDir.childDirectory('windows');
if (!outputDirectory.existsSync()) {
outputDirectory.createSync(recursive: true);
}
......@@ -350,7 +204,7 @@ class ReleaseBundleWindowsAssets extends BundleWindowsAssets {
@override
List<Target> get dependencies => <Target>[
...super.dependencies,
const WindowsAotBundle(AotElfRelease(TargetPlatform.windows_x64), uwp: false),
const WindowsAotBundle(AotElfRelease(TargetPlatform.windows_x64)),
];
}
......@@ -366,7 +220,7 @@ class ProfileBundleWindowsAssets extends BundleWindowsAssets {
@override
List<Target> get dependencies => <Target>[
...super.dependencies,
const WindowsAotBundle(AotElfProfile(TargetPlatform.windows_x64), uwp: false),
const WindowsAotBundle(AotElfProfile(TargetPlatform.windows_x64)),
];
}
......@@ -386,52 +240,3 @@ class DebugBundleWindowsAssets extends BundleWindowsAssets {
const Source.pattern('{OUTPUT_DIR}/flutter_assets/kernel_blob.bin'),
];
}
class ReleaseBundleWindowsAssetsUwp extends BundleWindowsAssetsUwp {
const ReleaseBundleWindowsAssetsUwp();
@override
String get name => 'release_bundle_windows_assets_uwp';
@override
List<Source> get outputs => const <Source>[];
@override
List<Target> get dependencies => <Target>[
...super.dependencies,
const WindowsAotBundle(AotElfRelease(TargetPlatform.windows_uwp_x64), uwp: true),
];
}
class ProfileBundleWindowsAssetsUwp extends BundleWindowsAssetsUwp {
const ProfileBundleWindowsAssetsUwp();
@override
String get name => 'profile_bundle_windows_assets_uwp';
@override
List<Source> get outputs => const <Source>[];
@override
List<Target> get dependencies => <Target>[
...super.dependencies,
const WindowsAotBundle(AotElfProfile(TargetPlatform.windows_uwp_x64), uwp: true),
];
}
class DebugBundleWindowsAssetsUwp extends BundleWindowsAssetsUwp {
const DebugBundleWindowsAssetsUwp();
@override
String get name => 'debug_bundle_windows_assets_uwp';
@override
List<Source> get inputs => <Source>[
const Source.pattern('{BUILD_DIR}/app.dill'),
];
@override
List<Source> get outputs => <Source>[
const Source.pattern('{OUTPUT_DIR}/flutter_assets/kernel_blob.bin'),
];
}
......@@ -70,9 +70,6 @@ class DevelopmentArtifact {
/// Artifacts required for the Flutter Runner.
static const DevelopmentArtifact flutterRunner = DevelopmentArtifact._('flutter_runner', feature: flutterFuchsiaFeature);
/// Artifacts required for desktop Windows UWP.
static const DevelopmentArtifact windowsUwp = DevelopmentArtifact._('winuwp', feature: windowsUwpEmbedding);
/// Artifacts required for any development platform.
///
/// This does not need to be explicitly returned from requiredArtifacts as
......@@ -92,7 +89,6 @@ class DevelopmentArtifact {
fuchsia,
universal,
flutterRunner,
windowsUwp,
];
@override
......
......@@ -2,13 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:meta/meta.dart';
import 'package:xml/xml.dart';
import 'base/common.dart';
import 'base/file_system.dart';
import 'base/utils.dart';
import 'cmake.dart';
import 'platform_plugins.dart';
import 'project.dart';
......@@ -84,45 +79,6 @@ class WindowsProject extends FlutterProjectPlatform implements CmakeBasedProject
Future<void> ensureReadyForPlatformSpecificTooling() async {}
}
/// The Windows UWP version of the Windows project.
class WindowsUwpProject extends WindowsProject {
WindowsUwpProject.fromFlutter(super.parent) : super.fromFlutter();
@override
String get _childDirectory => 'winuwp';
File get runnerCmakeFile => _editableDirectory.childDirectory('runner_uwp').childFile('CMakeLists.txt');
/// Eventually this will be used to check if the user's unstable project needs to be regenerated.
int? get projectVersion => int.tryParse(_editableDirectory.childFile('project_version').readAsStringSync());
/// Retrieve the GUID of the UWP package.
late final String? packageGuid = getCmakePackageGuid(runnerCmakeFile);
File get appManifest => _editableDirectory.childDirectory('runner_uwp').childFile('appxmanifest.in');
late final String? packageVersion = parseAppVersion(this);
}
@visibleForTesting
String? parseAppVersion(WindowsUwpProject project) {
final File appManifestFile = project.appManifest;
if (!appManifestFile.existsSync()) {
return null;
}
XmlDocument document;
try {
document = XmlDocument.parse(appManifestFile.readAsStringSync());
} on XmlParserException {
throwToolExit('Error parsing $appManifestFile. Please ensure that the appx manifest is a valid XML document and try again.');
}
for (final XmlElement metaData in document.findAllElements('Identity')) {
return metaData.getAttribute('Version');
}
return null;
}
/// The Linux sub project.
class LinuxProject extends FlutterProjectPlatform implements CmakeBasedProject {
LinuxProject.fromFlutter(this.parent);
......
......@@ -79,10 +79,6 @@ List<Target> _kDefaultTargets = <Target>[
const DebugBundleWindowsAssets(),
const ProfileBundleWindowsAssets(),
const ReleaseBundleWindowsAssets(),
// Windows UWP targets
const DebugBundleWindowsAssetsUwp(),
const ProfileBundleWindowsAssetsUwp(),
const ReleaseBundleWindowsAssetsUwp(),
];
/// Assemble provides a low level API to interact with the flutter tool build
......
......@@ -18,7 +18,6 @@ import 'build_fuchsia.dart';
import 'build_ios.dart';
import 'build_ios_framework.dart';
import 'build_web.dart';
import 'build_winuwp.dart';
class BuildCommand extends FlutterCommand {
BuildCommand({ bool verboseHelp = false }) {
......@@ -39,7 +38,6 @@ class BuildCommand extends FlutterCommand {
verboseHelp: verboseHelp
));
_addSubcommand(BuildWindowsCommand(verboseHelp: verboseHelp));
_addSubcommand(BuildWindowsUwpCommand(verboseHelp: verboseHelp));
_addSubcommand(BuildFuchsiaCommand(verboseHelp: verboseHelp));
}
......
......@@ -108,7 +108,6 @@ class BuildBundleCommand extends BuildSubCommand {
}
break;
case TargetPlatform.windows_x64:
case TargetPlatform.windows_uwp_x64:
if (!featureFlags.isWindowsEnabled) {
throwToolExit('Windows is not a supported target platform.');
}
......
// 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:meta/meta.dart';
import '../base/common.dart';
import '../build_info.dart';
import '../cache.dart';
import '../features.dart';
import '../globals.dart' as globals;
import '../project.dart';
import '../runner/flutter_command.dart' show FlutterCommandResult;
import '../windows/build_windows.dart';
import '../windows/visual_studio.dart';
import 'build.dart';
/// A command to build a Windows UWP desktop target.
class BuildWindowsUwpCommand extends BuildSubCommand {
BuildWindowsUwpCommand({
bool verboseHelp = false,
}) : super(verboseHelp: verboseHelp) {
addCommonDesktopBuildOptions(verboseHelp: verboseHelp);
}
@override
final String name = 'winuwp';
@override
bool get hidden => !featureFlags.isWindowsUwpEnabled || !globals.platform.isWindows;
@override
Future<Set<DevelopmentArtifact>> get requiredArtifacts async => <DevelopmentArtifact>{
DevelopmentArtifact.windowsUwp,
};
@override
String get description => 'Build a Windows UWP desktop application.';
@visibleForTesting
VisualStudio? visualStudioOverride;
@override
Future<FlutterCommandResult> runCommand() async {
final FlutterProject flutterProject = FlutterProject.current();
final BuildInfo buildInfo = await getBuildInfo();
if (!featureFlags.isWindowsUwpEnabled) {
throwToolExit('"build winuwp" is not currently supported.');
}
if (!globals.platform.isWindows) {
throwToolExit('"build winuwp" only supported on Windows hosts.');
}
displayNullSafetyMode(buildInfo);
await buildWindowsUwp(
flutterProject.windowsUwp,
buildInfo,
target: targetFile,
visualStudioOverride: visualStudioOverride,
);
return FlutterCommandResult.success();
}
}
......@@ -289,7 +289,6 @@ class CreateCommand extends CreateBase {
linux: featureFlags.isLinuxEnabled && platforms.contains('linux'),
macos: featureFlags.isMacOSEnabled && platforms.contains('macos'),
windows: featureFlags.isWindowsEnabled && platforms.contains('windows'),
windowsUwp: featureFlags.isWindowsUwpEnabled && platforms.contains('winuwp'),
// Enable null safety everywhere.
dartSdkVersionBounds: "'>=$dartSdk <3.0.0'",
implementationTests: boolArg('implementation-tests'),
......
......@@ -20,7 +20,6 @@ import '../cache.dart';
import '../convert.dart';
import '../dart/generate_synthetic_packages.dart';
import '../dart/pub.dart';
import '../features.dart';
import '../flutter_project_metadata.dart';
import '../globals.dart' as globals;
import '../project.dart';
......@@ -45,7 +44,6 @@ const List<String> kAllCreatePlatforms = <String>[
'linux',
'macos',
'web',
'winuwp',
];
const String _kDefaultPlatformArgumentHelp =
......@@ -165,13 +163,9 @@ abstract class CreateBase extends FlutterCommand {
aliases: <String>[ 'platform' ],
defaultsTo: <String>[
..._kAvailablePlatforms,
if (featureFlags.isWindowsUwpEnabled)
'winuwp',
],
allowed: <String>[
..._kAvailablePlatforms,
if (featureFlags.isWindowsUwpEnabled)
'winuwp',
],
);
}
......@@ -355,7 +349,6 @@ abstract class CreateBase extends FlutterCommand {
bool linux = false,
bool macos = false,
bool windows = false,
bool windowsUwp = false,
bool implementationTests = false,
}) {
final String pluginDartClass = _createPluginClassName(projectName);
......@@ -418,7 +411,6 @@ abstract class CreateBase extends FlutterCommand {
'linux': linux,
'macos': macos,
'windows': windows,
'winuwp': windowsUwp,
'year': DateTime.now().year,
'dartSdkVersionBounds': dartSdkVersionBounds,
'implementationTests': implementationTests,
......@@ -522,7 +514,6 @@ abstract class CreateBase extends FlutterCommand {
final bool macOSPlatform = templateContext['macos'] as bool ?? false;
final bool windowsPlatform = templateContext['windows'] as bool ?? false;
final bool webPlatform = templateContext['web'] as bool ?? false;
final bool winUwpPlatform = templateContext['winuwp'] as bool ?? false;
if (boolArg('pub')) {
final Environment environment = Environment(
......@@ -562,7 +553,6 @@ abstract class CreateBase extends FlutterCommand {
macOSPlatform: macOSPlatform,
windowsPlatform: windowsPlatform,
webPlatform: webPlatform,
winUwpPlatform: winUwpPlatform,
);
}
final List<SupportedPlatform> platformsForMigrateConfig = <SupportedPlatform>[SupportedPlatform.root];
......@@ -585,9 +575,6 @@ abstract class CreateBase extends FlutterCommand {
if (windowsPlatform) {
platformsForMigrateConfig.add(SupportedPlatform.windows);
}
if (winUwpPlatform) {
platformsForMigrateConfig.add(SupportedPlatform.windowsuwp);
}
if (templateContext['fuchsia'] == true) {
platformsForMigrateConfig.add(SupportedPlatform.fuchsia);
}
......
......@@ -50,8 +50,6 @@ class PrecacheCommand extends FlutterCommand {
help: 'Precache artifacts for Linux desktop development.');
argParser.addFlag('windows', negatable: true, defaultsTo: false,
help: 'Precache artifacts for Windows desktop development.');
argParser.addFlag('winuwp', negatable: true, defaultsTo: false,
help: 'Precache artifacts for Windows UWP desktop development.');
argParser.addFlag('macos', negatable: true, defaultsTo: false,
help: 'Precache artifacts for macOS desktop development.');
argParser.addFlag('fuchsia', negatable: true, defaultsTo: false,
......
......@@ -64,7 +64,6 @@ import 'run_hot.dart';
import 'runner/local_engine.dart';
import 'version.dart';
import 'web/workflow.dart';
import 'windows/uwptool.dart';
import 'windows/visual_studio.dart';
import 'windows/visual_studio_validator.dart';
import 'windows/windows_workflow.dart';
......@@ -207,11 +206,6 @@ Future<T> runInContext<T>(
operatingSystemUtils: globals.os,
terminal: globals.terminal,
customDevicesConfig: globals.customDevicesConfig,
uwptool: UwpTool(
artifacts: globals.artifacts,
logger: globals.logger,
processManager: globals.processManager,
),
),
DevtoolsLauncher: () => DevtoolsServerLauncher(
processManager: globals.processManager,
......
......@@ -47,9 +47,6 @@ abstract class FeatureFlags {
/// Whether fast single widget reloads are enabled.
bool get isSingleWidgetReloadEnabled => false;
/// Whether the windows UWP embedding is enabled.
bool get isWindowsUwpEnabled => false;
/// Whether a particular feature is enabled for the current channel.
///
/// Prefer using one of the specific getters above instead of this API.
......@@ -62,7 +59,6 @@ const List<Feature> allFeatures = <Feature>[
flutterLinuxDesktopFeature,
flutterMacOSDesktopFeature,
flutterWindowsDesktopFeature,
windowsUwpEmbedding,
singleWidgetReload,
flutterAndroidFeature,
flutterIOSFeature,
......@@ -212,16 +208,6 @@ const Feature singleWidgetReload = Feature(
),
);
/// The feature for enabling the Windows UWP embedding.
const Feature windowsUwpEmbedding = Feature(
name: 'Flutter for Windows UWP',
configSetting: 'enable-windows-uwp-desktop',
extraHelpText: 'Warning: Windows UWP support is obsolete and will be removed.',
master: FeatureChannelSetting(
available: true,
),
);
/// A [Feature] is a process for conditionally enabling tool features.
///
/// All settings are optional, and if not provided will generally default to
......
......@@ -105,8 +105,6 @@ class FlutterApplicationPackageFactory extends ApplicationPackageFactory {
return applicationBinary == null
? FuchsiaApp.fromFuchsiaProject(FlutterProject.current().fuchsia)
: FuchsiaApp.fromPrebuiltApp(applicationBinary);
case TargetPlatform.windows_uwp_x64:
return BuildableUwpApp(project: FlutterProject.current().windowsUwp);
}
}
}
......@@ -38,7 +38,6 @@ class FlutterCache extends Cache {
registerArtifact(FlutterWebSdk(this, platform: platform));
registerArtifact(FlutterSdk(this, platform: platform));
registerArtifact(WindowsEngineArtifacts(this, platform: platform));
registerArtifact(WindowsUwpEngineArtifacts(this, platform: platform));
registerArtifact(MacOSEngineArtifacts(this, platform: platform));
registerArtifact(LinuxEngineArtifacts(this, platform: platform));
registerArtifact(LinuxFuchsiaSDKArtifacts(this, platform: platform));
......@@ -305,33 +304,6 @@ class WindowsEngineArtifacts extends EngineCachedArtifact {
List<String> getLicenseDirs() => const <String>[];
}
class WindowsUwpEngineArtifacts extends EngineCachedArtifact {
WindowsUwpEngineArtifacts(Cache cache, {
required Platform platform,
}) : _platform = platform,
super(
'windows-uwp-sdk',
cache,
DevelopmentArtifact.windowsUwp,
);
final Platform _platform;
@override
List<String> getPackageDirs() => const <String>[];
@override
List<List<String>> getBinaryDirs() {
if (_platform.isWindows || ignorePlatformFiltering) {
return _windowsUwpDesktopBinaryDirs;
}
return const <List<String>>[];
}
@override
List<String> getLicenseDirs() => const <String>[];
}
/// Artifacts required for desktop Linux builds.
class LinuxEngineArtifacts extends EngineCachedArtifact {
LinuxEngineArtifacts(Cache cache, {
......@@ -864,13 +836,6 @@ const List<List<String>> _windowsDesktopBinaryDirs = <List<String>>[
<String>['windows-x64-release', 'windows-x64-release/windows-x64-flutter.zip'],
];
const List<List<String>> _windowsUwpDesktopBinaryDirs = <List<String>>[
<String>['windows-uwp-x64-debug', 'windows-x64-debug/windows-uwp-x64-flutter.zip'],
<String>['windows-uwp-x64-debug', 'windows-x64/flutter-cpp-client-wrapper.zip'],
<String>['windows-uwp-x64-profile', 'windows-x64-profile/windows-uwp-x64-flutter.zip'],
<String>['windows-uwp-x64-release', 'windows-x64-release/windows-uwp-x64-flutter.zip'],
];
const List<List<String>> _macOSDesktopBinaryDirs = <List<String>>[
<String>['darwin-x64', 'darwin-x64/FlutterMacOS.framework.zip'],
<String>['darwin-x64', 'darwin-x64/gen_snapshot.zip'],
......
......@@ -29,7 +29,7 @@ import 'macos/xcdevice.dart';
import 'tester/flutter_tester.dart';
import 'version.dart';
import 'web/web_device.dart';
import 'windows/uwptool.dart';
import 'windows/windows_device.dart';
import 'windows/windows_workflow.dart';
......@@ -56,7 +56,6 @@ class FlutterDeviceManager extends DeviceManager {
required WindowsWorkflow windowsWorkflow,
required super.terminal,
required CustomDevicesConfig customDevicesConfig,
required UwpTool uwptool,
}) : deviceDiscoverers = <DeviceDiscovery>[
AndroidDevices(
logger: logger,
......@@ -120,8 +119,6 @@ class FlutterDeviceManager extends DeviceManager {
logger: logger,
fileSystem: fileSystem,
windowsWorkflow: windowsWorkflow,
featureFlags: featureFlags,
uwptool: uwptool,
),
WebDevices(
featureFlags: featureFlags,
......
......@@ -47,9 +47,6 @@ class FlutterFeatureFlags implements FeatureFlags {
@override
bool get isSingleWidgetReloadEnabled => isEnabled(singleWidgetReload);
@override
bool get isWindowsUwpEnabled => isEnabled(windowsUwpEmbedding);
@override
bool isEnabled(Feature feature) {
final String currentChannel = _flutterVersion.channel;
......
......@@ -922,25 +922,6 @@ Future<void> writeWindowsPluginFiles(FlutterProject project, List<Plugin> plugin
await _writePluginCmakefile(project.windows.generatedPluginCmakeFile, context, templateRenderer);
}
/// The tooling currently treats UWP and win32 as identical, other than variant
/// filtering, for the purposes of tooling support and initial UWP bootstrap.
@visibleForTesting
Future<void> writeWindowsUwpPluginFiles(FlutterProject project, List<Plugin> plugins, TemplateRenderer templateRenderer) async {
final List<Plugin> methodChannelPlugins = _filterMethodChannelPlugins(plugins, WindowsPlugin.kConfigKey);
final List<Plugin> uwpPlugins = _filterPluginsByVariant(methodChannelPlugins, WindowsPlugin.kConfigKey, PluginPlatformVariant.winuwp);
final List<Map<String, Object?>> windowsMethodChannelPlugins = _extractPlatformMaps(uwpPlugins, WindowsPlugin.kConfigKey);
final List<Plugin> ffiPlugins = _filterFfiPlugins(plugins, WindowsPlugin.kConfigKey)..removeWhere(methodChannelPlugins.contains);
final List<Map<String, Object?>> windowsFfiPlugins = _extractPlatformMaps(ffiPlugins, WindowsPlugin.kConfigKey);
final Map<String, Object> context = <String, Object>{
'os': 'windows',
'methodChannelPlugins': windowsMethodChannelPlugins,
'ffiPlugins': windowsFfiPlugins,
'pluginsDir': _cmakeRelativePluginSymlinkDirectoryPath(project.windowsUwp),
};
await _writeCppPluginRegistrant(project.windowsUwp.managedDirectory, context, templateRenderer);
await _writePluginCmakefile(project.windowsUwp.generatedPluginCmakeFile, context, templateRenderer);
}
Future<void> _writeCppPluginRegistrant(Directory destination, Map<String, Object> templateContext, TemplateRenderer templateRenderer) async {
_renderTemplateToFile(
_cppPluginRegistryHeaderTemplate,
......@@ -1006,13 +987,6 @@ void createPluginSymlinks(FlutterProject project, {bool force = false, @visibleF
force: force,
);
}
if (localFeatureFlags.isWindowsUwpEnabled && project.windowsUwp.existsSync()) {
_createPlatformPluginSymlinks(
project.windowsUwp.pluginSymlinkDirectory,
platformPlugins[project.windows.pluginConfigKey] as List<Object?>?,
force: force,
);
}
}
/// Handler for symlink failures which provides specific instructions for known
......@@ -1104,7 +1078,6 @@ Future<void> injectPlugins(
bool linuxPlatform = false,
bool macOSPlatform = false,
bool windowsPlatform = false,
bool winUwpPlatform = false,
bool webPlatform = false,
}) async {
final List<Plugin> plugins = await findPlugins(project);
......@@ -1125,9 +1098,6 @@ Future<void> injectPlugins(
if (windowsPlatform) {
await writeWindowsPluginFiles(project, plugins, globals.templateRenderer);
}
if (winUwpPlatform) {
await writeWindowsUwpPluginFiles(project, plugins, globals.templateRenderer);
}
if (!project.isModule) {
final List<XcodeBasedProject> darwinProjects = <XcodeBasedProject>[
if (iosPlatform) project.ios,
......
......@@ -217,7 +217,6 @@ class MDnsObservatoryDiscovery {
case TargetPlatform.linux_x64:
case TargetPlatform.tester:
case TargetPlatform.web_javascript:
case TargetPlatform.windows_uwp_x64:
case TargetPlatform.windows_x64:
_logger.printTrace('No interface with an ipv4 link local address was found.');
break;
......
......@@ -26,9 +26,6 @@ const String kSupportedVariants = 'supportedVariants';
enum PluginPlatformVariant {
/// Win32 variant of Windows.
win32,
// UWP variant of Windows.
winuwp,
}
/// Marker interface for all platform specific plugin config implementations.
......@@ -396,7 +393,6 @@ class WindowsPlugin extends PluginPlatform
} else {
const Map<String, PluginPlatformVariant> variantByName = <String, PluginPlatformVariant>{
'win32': PluginPlatformVariant.win32,
'uwp': PluginPlatformVariant.winuwp,
};
for (final String variantName in variantList.cast<String>()) {
final PluginPlatformVariant? variant = variantByName[variantName];
......
......@@ -35,7 +35,6 @@ enum SupportedPlatform {
macos,
web,
windows,
windowsuwp,
fuchsia,
root, // Special platform to represent the root project directory
}
......@@ -194,9 +193,6 @@ class FlutterProject {
/// The Windows sub project of this project.
late final WindowsProject windows = WindowsProject.fromFlutter(this);
/// The Windows UWP sub project of this project.
late final WindowsUwpProject windowsUwp = WindowsUwpProject.fromFlutter(this);
/// The Fuchsia sub project of this project.
late final FuchsiaProject fuchsia = FuchsiaProject._(this);
......@@ -278,9 +274,6 @@ class FlutterProject {
if (windows.existsSync()) {
platforms.add(SupportedPlatform.windows);
}
if (windowsUwp.existsSync()) {
platforms.add(SupportedPlatform.windowsuwp);
}
if (fuchsia.existsSync()) {
platforms.add(SupportedPlatform.fuchsia);
}
......@@ -336,7 +329,6 @@ class FlutterProject {
macOSPlatform: featureFlags.isMacOSEnabled && macos.existsSync(),
windowsPlatform: featureFlags.isWindowsEnabled && windows.existsSync(),
webPlatform: featureFlags.isWebEnabled && web.existsSync(),
winUwpPlatform: featureFlags.isWindowsUwpEnabled && windowsUwp.existsSync(),
deprecationBehavior: deprecationBehavior,
);
}
......@@ -350,7 +342,6 @@ class FlutterProject {
bool macOSPlatform = false,
bool windowsPlatform = false,
bool webPlatform = false,
bool winUwpPlatform = false,
DeprecationBehavior deprecationBehavior = DeprecationBehavior.none,
}) async {
if (!directory.existsSync() || isPlugin) {
......@@ -375,9 +366,6 @@ class FlutterProject {
if (webPlatform) {
await web.ensureReadyForPlatformSpecificTooling();
}
if (winUwpPlatform) {
await windowsUwp.ensureReadyForPlatformSpecificTooling();
}
await injectPlugins(
this,
androidPlatform: androidPlatform,
......@@ -386,7 +374,6 @@ class FlutterProject {
macOSPlatform: macOSPlatform,
windowsPlatform: windowsPlatform,
webPlatform: webPlatform,
winUwpPlatform: winUwpPlatform,
);
}
......
......@@ -1523,7 +1523,6 @@ Future<String> getMissingPackageHintForPlatform(TargetPlatform platform) async {
case TargetPlatform.linux_x64:
case TargetPlatform.tester:
case TargetPlatform.web_javascript:
case TargetPlatform.windows_uwp_x64:
case TargetPlatform.windows_x64:
return null;
}
......
......@@ -1591,10 +1591,6 @@ DevelopmentArtifact? artifactFromTargetPlatform(TargetPlatform targetPlatform) {
case TargetPlatform.fuchsia_arm64:
case TargetPlatform.fuchsia_x64:
case TargetPlatform.tester:
case TargetPlatform.windows_uwp_x64:
if (featureFlags.isWindowsUwpEnabled) {
return DevelopmentArtifact.windowsUwp;
}
return null;
}
}
......
......@@ -150,10 +150,6 @@ class LocalEngineLocator {
// Determine the host engine directory associated with the local engine:
// Strip '_sim_' since there are no host simulator builds.
String _getHostEngineBasename(String localEngineBasename) {
// Allow winuwp builds to be treated as host builds.
if (localEngineBasename.startsWith('winuwp')) {
return localEngineBasename;
}
String tmpBasename = localEngineBasename.replaceFirst('_sim_', '_');
tmpBasename = tmpBasename.substring(tmpBasename.indexOf('_') + 1);
// Strip suffix for various archs.
......
......@@ -54,7 +54,6 @@ Future<String?> sharedSkSlWriter(Device device, Map<String, Object> data, {
case TargetPlatform.linux_x64:
case TargetPlatform.tester:
case TargetPlatform.web_javascript:
case TargetPlatform.windows_uwp_x64:
case TargetPlatform.windows_x64:
break;
}
......
......@@ -214,11 +214,6 @@ class Template {
if (relativeDestinationPath.startsWith('windows.tmpl') && !windows) {
return null;
}
// Only build a Windows UWP project if explicitly asked.
final bool windowsUwp = (context['winuwp'] as bool?) ?? false;
if (relativeDestinationPath.startsWith('winuwp.tmpl') && !windowsUwp) {
return null;
}
final String? projectName = context['projectName'] as String?;
final String? androidIdentifier = context['androidIdentifier'] as String?;
......
......@@ -71,14 +71,3 @@ class BuildableWindowsApp extends WindowsApp {
@override
String get name => project.parent.manifest.appName;
}
class BuildableUwpApp extends ApplicationPackage {
BuildableUwpApp({required this.project}) : super(id: project.packageGuid ?? 'com.example.placeholder');
final WindowsUwpProject project;
String? get projectVersion => project.packageVersion;
@override
String? get name => getCmakeExecutableName(project);
}
......@@ -17,12 +17,8 @@ import '../convert.dart';
import '../flutter_plugins.dart';
import '../globals.dart' as globals;
import '../migrations/cmake_custom_command_migration.dart';
import 'install_manifest.dart';
import 'visual_studio.dart';
/// Update the string when non-backwards compatible changes are made to the UWP template.
const int kCurrentUwpTemplateVersion = 0;
/// Builds the Windows project using msbuild.
Future<void> buildWindows(WindowsProject windowsProject, BuildInfo buildInfo, {
String? target,
......@@ -116,132 +112,6 @@ Future<void> buildWindows(WindowsProject windowsProject, BuildInfo buildInfo, {
}
}
/// Build the Windows UWP project.
///
/// Note that this feature is currently unfinished.
Future<void> buildWindowsUwp(WindowsUwpProject windowsProject, BuildInfo buildInfo, {
String? target,
VisualStudio? visualStudioOverride,
}) async {
final Directory buildDirectory = globals.fs.directory(getWindowsBuildUwpDirectory());
if (!windowsProject.existsSync()) {
throwToolExit(
'No Windows UWP desktop project configured. See '
'https://docs.flutter.dev/desktop#add-desktop-support-to-an-existing-flutter-app '
'to learn about adding Windows support to a project.',
);
}
if (windowsProject.projectVersion != kCurrentUwpTemplateVersion) {
throwToolExit(
'The Windows UWP project template and build process has changed. In order to build '
'you must delete the winuwp directory and re-create the project.',
);
}
// Ensure that necessary ephemeral files are generated and up to date.
_writeGeneratedFlutterConfig(windowsProject, buildInfo, target);
createPluginSymlinks(windowsProject.parent);
await createManifest(
buildDirectory: buildDirectory,
logger: globals.logger,
platform: globals.platform,
project: windowsProject,
buildInfo: buildInfo,
fileSystem: globals.fs,
);
final VisualStudio visualStudio = visualStudioOverride ?? VisualStudio(
fileSystem: globals.fs,
platform: globals.platform,
logger: globals.logger,
processManager: globals.processManager,
);
final String? cmakePath = visualStudio.cmakePath;
final String? cmakeGenerator = visualStudio.cmakeGenerator;
if (cmakePath == null || cmakeGenerator == null) {
throwToolExit('Unable to find suitable Visual Studio toolchain. '
'Please run `flutter doctor` for more details.');
}
final String buildModeName = getNameForBuildMode(buildInfo.mode);
final Status status = globals.logger.startProgress(
'Building Windows UWP application...',
);
try {
// The Cmake re-entrant build does not work for UWP, so the flutter build is
// run in advance.
await _runFlutterBuild(buildDirectory, buildInfo, target);
await _runCmakeGeneration(
cmakePath: cmakePath,
generator: cmakeGenerator,
buildDir: buildDirectory,
sourceDir: windowsProject.cmakeFile.parent,
);
await _runBuild(cmakePath, buildDirectory, buildModeName, install: false);
} finally {
status.cancel();
}
}
const Map<BuildMode, String> _targets = <BuildMode, String>{
BuildMode.debug: 'debug_bundle_windows_assets_uwp',
BuildMode.profile: 'profile_bundle_windows_assets_uwp',
BuildMode.release: 'release_bundle_windows_assets_uwp',
};
Future<void> _runFlutterBuild(Directory buildDirectory, BuildInfo buildInfo, String? targetFile) async {
await buildDirectory.create(recursive: true);
int result;
String? flutterEngine;
String? localEngine;
final Artifacts artifacts = globals.artifacts!;
if (artifacts is LocalEngineArtifacts) {
final String engineOutPath = artifacts.engineOutPath;
flutterEngine = globals.fs.path.dirname(globals.fs.path.dirname(engineOutPath));
localEngine = globals.fs.path.basename(engineOutPath);
}
try {
final String? buildMode = _targets[buildInfo.mode];
result = await globals.processUtils.stream(
<String>[
globals.fs.path.join(Cache.flutterRoot!, 'bin', 'flutter'),
if (globals.logger.isVerbose)
'--verbose',
if (flutterEngine != null) '--local-engine-src-path=$flutterEngine',
if (localEngine != null) '--local-engine=$localEngine',
'assemble',
'--no-version-check',
'--output=build',
'-dTargetPlatform=windows-uwp-x64',
'-dTrackWidgetCreation=${buildInfo.trackWidgetCreation}',
'-dBuildMode=${getNameForBuildMode(buildInfo.mode)}',
'-dTargetFile=$targetFile',
'-dTreeShakeIcons="${buildInfo.treeShakeIcons}"',
'-dDartObfuscation=${buildInfo.dartObfuscation}',
if (buildInfo.bundleSkSLPath != null)
'-dBundleSkSLPath=${buildInfo.bundleSkSLPath}',
if (buildInfo.codeSizeDirectory != null)
'-dCodeSizeDirectory=${buildInfo.codeSizeDirectory}',
if (buildInfo.splitDebugInfoPath != null)
'-dSplitDebugInfo=${buildInfo.splitDebugInfoPath}',
if (buildInfo.dartDefines != null && buildInfo.dartDefines.isNotEmpty)
'--DartDefines=${encodeDartDefines(buildInfo.dartDefines)}',
if (buildInfo.extraGenSnapshotOptions != null && buildInfo.extraGenSnapshotOptions.isNotEmpty)
'--ExtraGenSnapshotOptions=${buildInfo.extraGenSnapshotOptions}',
if (buildInfo.extraFrontEndOptions != null && buildInfo.extraFrontEndOptions.isNotEmpty)
'--ExtraFrontEndOptions=${buildInfo.extraFrontEndOptions}',
if (buildMode != null)
buildMode,
],
trace: true,
);
} on ArgumentError {
throwToolExit("cmake not found. Run 'flutter doctor' for more information.");
}
if (result != 0) {
throwToolExit('Unable to generate build files');
}
}
Future<void> _runCmakeGeneration({
required String cmakePath,
required String generator,
......
// 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 '../asset.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/platform.dart';
import '../build_info.dart';
import '../cmake_project.dart';
/// Generate an install manifest that is required for CMAKE on UWP projects.
Future<void> createManifest({
required Logger logger,
required FileSystem fileSystem,
required Platform platform,
required WindowsUwpProject project,
required BuildInfo buildInfo,
required Directory buildDirectory,
}) async {
final List<File> outputs = <File>[];
final AssetBundle assetBundle = AssetBundleFactory.defaultInstance(
logger: logger,
fileSystem: fileSystem,
platform: platform,
).createBundle();
final int resultCode = await assetBundle.build(
packagesPath: buildInfo.packagesPath,
assetDirPath: buildDirectory.childDirectory('flutter_assets').path,
);
if (resultCode != 0) {
throwToolExit('Failed to build assets.');
}
if (buildInfo.mode.isPrecompiled) {
outputs.add(buildDirectory.childFile('app.so'));
} else {
outputs.add(buildDirectory.parent.childDirectory('flutter_assets').childFile('kernel_blob.bin'));
}
for (final String key in assetBundle.entries.keys) {
outputs.add(buildDirectory.parent.childDirectory('flutter_assets').childFile(key));
}
outputs.add(project.ephemeralDirectory.childFile('flutter_windows_winuwp.dll'));
outputs.add(project.ephemeralDirectory.childFile('flutter_windows_winuwp.dll.pdb'));
outputs.add(project.ephemeralDirectory.childFile('icudtl.dat'));
project.ephemeralDirectory.childFile('install_manifest')
..createSync(recursive: true)
..writeAsStringSync(outputs.map((File file) => file.absolute.uri.path.substring(1)).join('\n'));
}
// 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 'package:process/process.dart';
import '../artifacts.dart';
import '../base/logger.dart';
import '../base/process.dart';
/// The uwptool command-line tool.
///
/// `uwptool` is a host utility command-line tool that supports a variety of
/// actions related to Universal Windows Platform (UWP) applications, including
/// installing and uninstalling apps, querying installed apps, and launching
/// apps.
class UwpTool {
UwpTool({
required Artifacts artifacts,
required Logger logger,
required ProcessManager processManager,
}) : _artifacts = artifacts,
_logger = logger,
_processUtils = ProcessUtils(processManager: processManager, logger: logger);
final Artifacts _artifacts;
final Logger _logger;
final ProcessUtils _processUtils;
String get _binaryPath => _artifacts.getArtifactPath(Artifact.uwptool);
Future<List<String>> listApps() async {
final List<String> launchCommand = <String>[
_binaryPath,
'listapps',
];
final RunResult result = await _processUtils.run(launchCommand);
if (result.exitCode != 0) {
_logger.printError('Failed to list installed UWP apps: ${result.stderr}');
return <String>[];
}
final List<String> packageFamilies = <String>[];
for (final String line in result.stdout.split('\n')) {
final String packageFamily = line.trim();
if (packageFamily.isNotEmpty) {
packageFamilies.add(packageFamily);
}
}
return packageFamilies;
}
/// Returns the package family name for the specified package name.
///
/// If no installed application on the system matches the specified package
/// name, returns null.
Future<String?> getPackageFamilyName(String packageName) async {
for (final String packageFamily in await listApps()) {
if (packageFamily.startsWith(packageName)) {
return packageFamily;
}
}
return null;
}
/// Launches the app with the specified package family name.
///
/// On success, returns the process ID of the launched app, otherwise null.
Future<int?> launchApp(String packageFamily, List<String> args) async {
final List<String> launchCommand = <String>[
_binaryPath,
'launch',
packageFamily
] + args;
final RunResult result = await _processUtils.run(launchCommand);
if (result.exitCode != 0) {
_logger.printError('Failed to launch app $packageFamily: ${result.stderr}');
return null;
}
// Read the process ID from stdout.
final int? processId = int.tryParse(result.stdout.trim());
_logger.printTrace('Launched application $packageFamily with process ID $processId');
return processId;
}
/// Returns `true` if the specified package signature is valid.
Future<bool> isSignatureValid(String packagePath) async {
final List<String> launchCommand = <String>[
'powershell.exe',
'-command',
'if ((Get-AuthenticodeSignature "$packagePath").Status -eq "Valid") { exit 0 } else { exit 1 }'
];
final RunResult result = await _processUtils.run(launchCommand);
if (result.exitCode != 0) {
_logger.printTrace('Invalid signature found for $packagePath');
return false;
}
_logger.printTrace('Valid signature found for $packagePath');
return true;
}
/// Installs a developer signing certificate.
///
/// Returns `true` on success.
Future<bool> installCertificate(String certificatePath) async {
final List<String> launchCommand = <String>[
'powershell.exe',
'start',
'certutil',
'-argumentlist',
'\'-addstore TrustedPeople "$certificatePath"\'',
'-verb',
'runas'
];
final RunResult result = await _processUtils.run(launchCommand);
if (result.exitCode != 0) {
_logger.printError('Failed to install certificate $certificatePath');
return false;
}
_logger.printTrace('Waiting for certificate store update');
// TODO(cbracken): Determine how we can query for success until some timeout.
// https://github.com/flutter/flutter/issues/82665
await Future<void>.delayed(const Duration(seconds: 1));
_logger.printTrace('Installed certificate $certificatePath');
return true;
}
/// Installs the app with the specified build directory.
///
/// Returns `true` on success.
Future<bool> installApp(String packageUri, List<String> dependencyUris) async {
final List<String> launchCommand = <String>[
_binaryPath,
'install',
packageUri,
] + dependencyUris;
final RunResult result = await _processUtils.run(launchCommand);
if (result.exitCode != 0) {
_logger.printError('Failed to install $packageUri');
return false;
}
_logger.printTrace('Installed application $packageUri');
return true;
}
Future<bool> uninstallApp(String packageFamily) async {
final List<String> launchCommand = <String>[
_binaryPath,
'uninstall',
packageFamily
];
final RunResult result = await _processUtils.run(launchCommand);
if (result.exitCode != 0) {
_logger.printError('Failed to uninstall $packageFamily');
return false;
}
_logger.printTrace('Uninstalled application $packageFamily');
return true;
}
}
......@@ -6,20 +6,15 @@ import 'dart:async';
import 'package:process/process.dart';
import '../application_package.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../desktop_device.dart';
import '../device.dart';
import '../device_port_forwarder.dart';
import '../features.dart';
import '../project.dart';
import 'application_package.dart';
import 'build_windows.dart';
import 'uwptool.dart';
import 'windows_workflow.dart';
/// A device that represents a desktop Windows target.
......@@ -72,332 +67,6 @@ class WindowsDevice extends DesktopDevice {
}
}
// A device that represents a desktop Windows UWP target.
class WindowsUWPDevice extends Device {
WindowsUWPDevice({
required ProcessManager processManager,
required Logger logger,
required FileSystem fileSystem,
required OperatingSystemUtils operatingSystemUtils,
required UwpTool uwptool,
}) : _logger = logger,
_processManager = processManager,
_operatingSystemUtils = operatingSystemUtils,
_fileSystem = fileSystem,
_uwptool = uwptool,
super(
'winuwp',
platformType: PlatformType.windows,
ephemeral: false,
category: Category.desktop,
);
final ProcessManager _processManager;
final Logger _logger;
final FileSystem _fileSystem;
final OperatingSystemUtils _operatingSystemUtils;
final UwpTool _uwptool;
BuildMode? _buildMode;
int? _processId;
@override
bool isSupported() => true;
@override
String get name => 'Windows (UWP)';
@override
Future<TargetPlatform> get targetPlatform async => TargetPlatform.windows_uwp_x64;
@override
bool isSupportedForProject(FlutterProject flutterProject) {
return flutterProject.windowsUwp.existsSync();
}
@override
void clearLogs() { }
@override
Future<void> dispose() async { }
@override
Future<String?> get emulatorId async => null;
@override
FutureOr<DeviceLogReader> getLogReader({covariant BuildableUwpApp? app, bool includePastLogs = false}) {
return NoOpDeviceLogReader('winuwp');
}
// Returns `true` if the specified file is a valid package based on file extension.
bool _isValidPackage(String packagePath) {
const List<String> validPackageExtensions = <String>[
'.appx', '.msix', // Architecture-specific application.
'.appxbundle', '.msixbundle', // Architecture-independent application.
'.eappx', '.emsix', // Encrypted architecture-specific application.
'.eappxbundle', '.emsixbundle', // Encrypted architecture-independent application.
];
return validPackageExtensions.any(packagePath.endsWith);
}
// Walks the build directory for any dependent packages for the specified architecture.
List<String> _getPackagePaths(String directory) {
if (!_fileSystem.isDirectorySync(directory)) {
return <String>[];
}
final List<String> packagePaths = <String>[];
for (final FileSystemEntity entity in _fileSystem.directory(directory).listSync()) {
if (entity.statSync().type != FileSystemEntityType.file) {
continue;
}
final String packagePath = entity.absolute.path;
if (_isValidPackage(packagePath)) {
packagePaths.add(packagePath);
}
}
return packagePaths;
}
// Walks the build directory for any dependent packages for the specified architecture.
String? _getAppPackagePath(String buildDirectory) {
final List<String> packagePaths = _getPackagePaths(buildDirectory);
return packagePaths.isNotEmpty ? packagePaths.first : null;
}
// Walks the build directory for any dependent packages for the specified architecture.
List<String> _getDependencyPaths(String buildDirectory, String architecture) {
final String depsDirectory = _fileSystem.path.join(buildDirectory, 'Dependencies', architecture);
return _getPackagePaths(depsDirectory);
}
String _getPackageName(String binaryName, String version, String config, {String? architecture}) {
final List<String> components = <String>[
binaryName,
version,
if (architecture != null) architecture,
config,
];
return components.join('_');
}
@override
Future<bool> installApp(covariant BuildableUwpApp app, {String? userIdentifier}) async {
/// The cmake build generates an install powershell script.
/// build\winuwp\runner_uwp\AppPackages\<app-name>\<app-name>_<app-version>_<cmake-config>\Add-AppDevPackage.ps1
final String? binaryName = app.name;
final String? packageVersion = app.projectVersion;
if (binaryName == null || packageVersion == null) {
return false;
}
final String binaryDir = _fileSystem.path.absolute(
_fileSystem.path.join('build', 'winuwp', 'runner_uwp', 'AppPackages', binaryName));
final String config = sentenceCase(getNameForBuildMode(_buildMode ?? BuildMode.debug));
// If a multi-architecture package exists, install that; otherwise install
// the single-architecture package.
final List<String> packageNames = <String>[
// Multi-archtitecture package.
_getPackageName(binaryName, packageVersion, config),
// Single-archtitecture package.
_getPackageName(binaryName, packageVersion, config, architecture: 'x64'),
];
String? packageName;
String? buildDirectory;
String? packagePath;
for (final String name in packageNames) {
packageName = name;
buildDirectory = _fileSystem.path.join(binaryDir, '${packageName}_Test');
if (_fileSystem.isDirectorySync(buildDirectory)) {
packagePath = _getAppPackagePath(buildDirectory);
if (packagePath != null && _fileSystem.isFileSync(packagePath)) {
break;
}
}
}
if (packagePath == null) {
_logger.printError('Failed to locate app package to install');
return false;
}
// Verify package signature.
if (!await _uwptool.isSignatureValid(packagePath)) {
// If signature is invalid, install the developer certificate.
final String certificatePath = _fileSystem.path.join(buildDirectory!, '$packageName.cer');
if (_logger.terminal.stdinHasTerminal) {
final String response = await _logger.terminal.promptForCharInput(
<String>['Y', 'y', 'N', 'n'],
logger: _logger,
prompt: 'Install developer certificate.\n'
'\n'
'Windows UWP apps are signed with a developer certificate during the build\n'
'process. On the first install of an app with a signature from a new\n'
'certificate, the certificate must be installed.\n'
'\n'
'If desired, this certificate can later be removed by launching the \n'
'"Manage Computer Certificates" control panel from the Start menu and deleting\n'
'the "CMake Test Cert" certificate from the "Trusted People" > "Certificates"\n'
'section.\n'
'\n'
'Press "Y" to continue, or "N" to cancel.',
displayAcceptedCharacters: false,
);
if (response == 'N' || response == 'n') {
return false;
}
}
await _uwptool.installCertificate(certificatePath);
}
// Install the application and dependencies.
final String packageUri = Uri.file(packagePath).toString();
final List<String> dependencyUris = _getDependencyPaths(buildDirectory!, 'x64')
.map((String path) => Uri.file(path).toString())
.toList();
return _uwptool.installApp(packageUri, dependencyUris);
}
@override
Future<bool> isAppInstalled(covariant ApplicationPackage app, {String? userIdentifier}) async {
final String packageName = app.id;
return await _uwptool.getPackageFamilyName(packageName) != null;
}
@override
Future<bool> isLatestBuildInstalled(covariant ApplicationPackage app) async => false;
@override
Future<bool> get isLocalEmulator async => false;
@override
DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder();
@override
Future<String> get sdkNameAndVersion async => '';
@override
Future<LaunchResult> startApp(covariant BuildableUwpApp package, {
String? mainPath,
String? route,
required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object>{},
bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier,
}) async {
_buildMode = debuggingOptions.buildInfo.mode;
if (!prebuiltApplication) {
await buildWindowsUwp(
package.project,
debuggingOptions.buildInfo,
target: mainPath,
);
}
if (await isAppInstalled(package) && !await uninstallApp(package)) {
_logger.printError('Failed to uninstall previous app package');
return LaunchResult.failed();
}
if (!await installApp(package)) {
_logger.printError('Failed to install app package');
return LaunchResult.failed();
}
final String packageName = package.id;
if (packageName == null) {
_logger.printError('Could not find PACKAGE_GUID in ${package.project.runnerCmakeFile.path}');
return LaunchResult.failed();
}
final String? packageFamily = await _uwptool.getPackageFamilyName(packageName);
if (packageFamily == null) {
_logger.printError('Could not find package family name from $packageName');
return LaunchResult.failed();
}
if (debuggingOptions.buildInfo.mode.isRelease) {
_processId = await _uwptool.launchApp(packageFamily, <String>[]);
return _processId != null ? LaunchResult.succeeded() : LaunchResult.failed();
}
/// If the terminal is attached, prompt the user to open the firewall port.
if (_logger.terminal.stdinHasTerminal) {
final String response = await _logger.terminal.promptForCharInput(
<String>['Y', 'y', 'N', 'n'],
logger: _logger,
prompt: 'Enable Flutter debugging from localhost.\n'
'\n'
'Windows UWP apps run in a sandboxed environment. To enable Flutter debugging\n'
'and hot reload, you will need to enable inbound connections to the app from the\n'
'Flutter tool running on your machine. To do so:\n'
' 1. Launch PowerShell as an Administrator\n'
' 2. Enter the following command:\n'
' checknetisolation loopbackexempt -is -n=$packageFamily\n'
'\n'
'Press "Y" once this is complete, or "N" to abort.',
displayAcceptedCharacters: false,
);
if (response == 'N' || response == 'n') {
return LaunchResult.failed();
}
}
/// Currently we do not have a way to discover the VM Service URI.
final int port = debuggingOptions.deviceVmServicePort ?? await _operatingSystemUtils.findFreePort();
final List<String> args = <String>[
'--observatory-port=$port',
'--disable-service-auth-codes',
'--enable-dart-profiling',
if (debuggingOptions.startPaused) '--start-paused',
if (debuggingOptions.useTestFonts) '--use-test-fonts',
if (debuggingOptions.debuggingEnabled) ...<String>[
'--enable-checked-mode',
'--verify-entry-points',
],
if (debuggingOptions.enableSoftwareRendering) '--enable-software-rendering',
if (debuggingOptions.skiaDeterministicRendering) '--skia-deterministic-rendering',
if (debuggingOptions.traceSkia) '--trace-skia',
if (debuggingOptions.traceAllowlist != null) '--trace-allowlist="${debuggingOptions.traceAllowlist}"',
if (debuggingOptions.traceSkiaAllowlist != null) '--trace-skia-allowlist="${debuggingOptions.traceSkiaAllowlist}"',
if (debuggingOptions.endlessTraceBuffer) '--endless-trace-buffer',
if (debuggingOptions.dumpSkpOnShaderCompilation) '--dump-skp-on-shader-compilation',
if (debuggingOptions.verboseSystemLogs) '--verbose-logging',
if (debuggingOptions.cacheSkSL) '--cache-sksl',
if (debuggingOptions.purgePersistentCache) '--purge-persistent-cache',
if (platformArgs['trace-startup'] as bool? ?? false) '--trace-startup',
];
_processId = await _uwptool.launchApp(packageFamily, args);
if (_processId == null) {
return LaunchResult.failed();
}
return LaunchResult.succeeded(observatoryUri: Uri.parse('http://localhost:$port'));
}
@override
Future<bool> stopApp(covariant BuildableUwpApp app, {String? userIdentifier}) async {
if (_processId != null) {
return _processManager.killPid(_processId!);
}
return false;
}
@override
Future<bool> uninstallApp(covariant BuildableUwpApp app, {String? userIdentifier}) async {
final String packageName = app.id;
if (packageName == null) {
_logger.printError('Could not find PACKAGE_GUID in ${app.project.runnerCmakeFile.path}');
return false;
}
final String? packageFamily = await _uwptool.getPackageFamilyName(packageName);
if (packageFamily == null) {
// App is not installed.
return true;
}
return _uwptool.uninstallApp(packageFamily);
}
@override
FutureOr<bool> supportsRuntimeMode(BuildMode buildMode) => buildMode != BuildMode.jitRelease;
}
class WindowsDevices extends PollingDeviceDiscovery {
WindowsDevices({
required ProcessManager processManager,
......@@ -405,15 +74,11 @@ class WindowsDevices extends PollingDeviceDiscovery {
required FileSystem fileSystem,
required OperatingSystemUtils operatingSystemUtils,
required WindowsWorkflow windowsWorkflow,
required FeatureFlags featureFlags,
required UwpTool uwptool,
}) : _fileSystem = fileSystem,
_logger = logger,
_processManager = processManager,
_operatingSystemUtils = operatingSystemUtils,
_windowsWorkflow = windowsWorkflow,
_featureFlags = featureFlags,
_uwptool = uwptool,
super('windows devices');
final FileSystem _fileSystem;
......@@ -421,8 +86,6 @@ class WindowsDevices extends PollingDeviceDiscovery {
final ProcessManager _processManager;
final OperatingSystemUtils _operatingSystemUtils;
final WindowsWorkflow _windowsWorkflow;
final FeatureFlags _featureFlags;
final UwpTool _uwptool;
@override
bool get supportsPlatform => _windowsWorkflow.appliesToHostPlatform;
......@@ -442,14 +105,6 @@ class WindowsDevices extends PollingDeviceDiscovery {
processManager: _processManager,
operatingSystemUtils: _operatingSystemUtils,
),
if (_featureFlags.isWindowsUwpEnabled)
WindowsUWPDevice(
fileSystem: _fileSystem,
logger: _logger,
processManager: _processManager,
operatingSystemUtils: _operatingSystemUtils,
uwptool: _uwptool,
)
];
}
......@@ -457,5 +112,5 @@ class WindowsDevices extends PollingDeviceDiscovery {
Future<List<String>> getDiagnostics() async => const <String>[];
@override
List<String> get wellKnownIds => const <String>['windows', 'winuwp'];
List<String> get wellKnownIds => const <String>['windows'];
}
flutter/ephemeral/
# Visual Studio user-specific files.
*.suo
*.user
*.userosscache
*.sln.docstates
# Visual Studio build-related files.
x64/
x86/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Project-level configuration.
cmake_minimum_required(VERSION 3.8)
set(CMAKE_SYSTEM_NAME WindowsStore)
set(CMAKE_SYSTEM_VERSION 10.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
project({{projectName}} LANGUAGES CXX)
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy(SET CMP0079 NEW)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "{{projectName}}")
# Define build configuration options.
get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(IS_MULTICONFIG)
set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
CACHE STRING "" FORCE)
else()
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE
STRING "Flutter build mode" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Profile" "Release")
endif()
endif()
# Define settings for the Profile build mode.
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
# Use Unicode for all projects.
add_definitions(-DUNICODE -D_UNICODE)
# Compilation settings that should be applied to most targets.
#
# Be cautious about adding new options here, as plugins use this function by
# default. In most cases, you should add new options to specific targets instead
# of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_17)
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100" /await)
target_compile_options(${TARGET} PRIVATE /EHsc)
target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>")
target_compile_definitions(${TARGET} PRIVATE WINUWP)
set_target_properties(${TARGET} PROPERTIES VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION 10.0.18362.0)
endfunction()
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
# Flutter library and tool build rules.
add_subdirectory(${FLUTTER_MANAGED_DIR})
# Application build; see runner/CMakeLists.txt.
add_subdirectory("runner_uwp")
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)
# This file controls Flutter-level build steps. It should not be edited.
cmake_minimum_required(VERSION 3.8)
set(CMAKE_SYSTEM_NAME WindowsStore)
set(CMAKE_SYSTEM_VERSION 10.0)
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
include(CMakePrintHelpers)
# Configuration provided via flutter tool.
include(${EPHEMERAL_DIR}/generated_config.cmake)
# TODO: Move the rest of this into files in ephemeral. See
# https://github.com/flutter/flutter/issues/57146.
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
# === Flutter Library ===
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows_winuwp.dll")
# === Assets ===
set(CMAKE_INSTALL_MANIFEST "${EPHEMERAL_DIR}/install_manifest")
file(STRINGS ${CMAKE_INSTALL_MANIFEST} INSTALL_MANIFEST_CONTENT)
# Published to parent scope for install step.
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
set(INSTALL_MANIFEST_CONTENT ${INSTALL_MANIFEST_CONTENT} PARENT_SCOPE)
list(APPEND FLUTTER_LIBRARY_HEADERS
"flutter_export.h"
"flutter_windows.h"
"flutter_messenger.h"
"flutter_plugin_registrar.h"
"flutter_texture_registrar.h"
)
list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
add_library(flutter INTERFACE)
target_include_directories(flutter INTERFACE
"${EPHEMERAL_DIR}"
)
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
add_dependencies(flutter flutter_assemble)
# === Wrapper ===
list(APPEND CPP_WRAPPER_SOURCES_CORE
"core_implementations.cc"
"standard_codec.cc"
)
list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
"plugin_registrar.cc"
)
list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
list(APPEND CPP_WRAPPER_SOURCES_APP
"flutter_engine.cc"
"flutter_view_controller.cc"
)
list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
# Wrapper sources needed for a plugin.
add_library(flutter_wrapper_plugin STATIC
${CPP_WRAPPER_SOURCES_CORE}
${CPP_WRAPPER_SOURCES_PLUGIN}
)
apply_standard_settings(flutter_wrapper_plugin)
set_target_properties(flutter_wrapper_plugin PROPERTIES
POSITION_INDEPENDENT_CODE ON)
set_target_properties(flutter_wrapper_plugin PROPERTIES
CXX_VISIBILITY_PRESET hidden)
target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
target_include_directories(flutter_wrapper_plugin PUBLIC
"${WRAPPER_ROOT}/include"
)
add_dependencies(flutter_wrapper_plugin flutter_assemble)
# Wrapper sources needed for the runner.
add_library(flutter_wrapper_app STATIC
${CPP_WRAPPER_SOURCES_CORE}
${CPP_WRAPPER_SOURCES_APP}
)
apply_standard_settings(flutter_wrapper_app)
target_link_libraries(flutter_wrapper_app PUBLIC flutter)
target_include_directories(flutter_wrapper_app PUBLIC
"${WRAPPER_ROOT}/include"
)
add_dependencies(flutter_wrapper_app flutter_assemble)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"
${FLUTTER_LIBRARY_HEADERS}
${CPP_WRAPPER_SOURCES_CORE}
${CPP_WRAPPER_SOURCES_PLUGIN}
${CPP_WRAPPER_SOURCES_APP}
)
cmake_minimum_required (VERSION 3.8)
set(CMAKE_SYSTEM_NAME WindowsStore)
set(CMAKE_SYSTEM_VERSION 10.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
include(CMakePrintHelpers)
project (runner LANGUAGES CXX)
# UWP tile and icon assets.
set(ASSET_FILES ${ASSET_FILES}
Assets/LargeTile.scale-100.png
Assets/LargeTile.scale-125.png
Assets/LargeTile.scale-150.png
Assets/LargeTile.scale-200.png
Assets/LargeTile.scale-400.png
Assets/LockScreenLogo.scale-200.png
Assets/SmallTile.scale-100.png
Assets/SmallTile.scale-125.png
Assets/SmallTile.scale-150.png
Assets/SmallTile.scale-200.png
Assets/SmallTile.scale-400.png
Assets/SplashScreen.scale-100.png
Assets/SplashScreen.scale-125.png
Assets/SplashScreen.scale-150.png
Assets/SplashScreen.scale-200.png
Assets/SplashScreen.scale-400.png
Assets/Square44x44Logo.altform-unplated_targetsize-16.png
Assets/Square44x44Logo.altform-unplated_targetsize-32.png
Assets/Square44x44Logo.altform-unplated_targetsize-48.png
Assets/Square44x44Logo.altform-unplated_targetsize-256.png
Assets/Square44x44Logo.scale-100.png
Assets/Square44x44Logo.scale-125.png
Assets/Square44x44Logo.scale-150.png
Assets/Square44x44Logo.scale-200.png
Assets/Square44x44Logo.scale-400.png
Assets/Square44x44Logo.targetsize-16.png
Assets/Square44x44Logo.targetsize-24.png
Assets/Square44x44Logo.targetsize-24_altform-unplated.png
Assets/Square44x44Logo.targetsize-32.png
Assets/Square44x44Logo.targetsize-48.png
Assets/Square44x44Logo.targetsize-256.png
Assets/Square150x150Logo.scale-100.png
Assets/Square150x150Logo.scale-125.png
Assets/Square150x150Logo.scale-150.png
Assets/Square150x150Logo.scale-200.png
Assets/Square150x150Logo.scale-400.png
Assets/StoreLogo.png
Assets/StoreLogo.scale-100.png
Assets/StoreLogo.scale-125.png
Assets/StoreLogo.scale-150.png
Assets/StoreLogo.scale-200.png
Assets/StoreLogo.scale-400.png
Assets/Wide310x150Logo.scale-200.png
Assets/WideTile.scale-100.png
Assets/WideTile.scale-125.png
Assets/WideTile.scale-150.png
Assets/WideTile.scale-200.png
Assets/WideTile.scale-400.png
)
# Configure package manifest file.
set(APP_MANIFEST_NAME Package.appxmanifest)
set(APP_MANIFEST_TARGET_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${APP_MANIFEST_NAME})
set(SHORT_NAME ${BINARY_NAME})
set(PACKAGE_GUID "{{windowsIdentifier}}")
configure_file(
appxmanifest.in
${APP_MANIFEST_TARGET_LOCATION}
@ONLY)
set(CONTENT_FILES ${APP_MANIFEST_TARGET_LOCATION})
# Configure package content files.
set_property(SOURCE ${CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1)
set(RESOURCE_FILES ${ASSET_FILES} ${CONTENT_FILES} Windows_TemporaryKey.pfx)
set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1)
set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_LOCATION "Assets")
set(STRING_FILES Resources.pri)
set_property(SOURCE ${STRING_FILES} PROPERTY VS_TOOL_OVERRIDE "PRIResource")
source_group("Resource Files" FILES ${RESOURCE_FILES} ${CONTENT_FILES} ${STRING_FILES})
# Configure Flutter assets using tool generated install manifest
foreach(ITEM ${INSTALL_MANIFEST_CONTENT})
get_filename_component(ITEM_REL ${CMAKE_BINARY_DIR} DIRECTORY)
file(RELATIVE_PATH RELPATH ${ITEM_REL} ${ITEM})
get_filename_component(RELPATH ${RELPATH} DIRECTORY)
get_filename_component(ITEMEXT ${ITEM} LAST_EXT)
if("${ITEMEXT}" STREQUAL ".dll" OR "${ITEMEXT}" STREQUAL ".pdb")
string(CONCAT RELPATH "")
elseif ("${ITEMEXT}" STREQUAL ".so")
file(RELATIVE_PATH RELPATH "${ITEM_REL}/winuwp" ${ITEM})
string(REGEX REPLACE "/" "\\\\" RELPATH ${RELPATH})
string(CONCAT RELPATH "Assets\\Data")
elseif("${ITEMEXT}" STREQUAL ".dat")
string(CONCAT RELPATH "Assets\\Data")
else()
string(REGEX REPLACE "/" "\\\\" RELPATH ${RELPATH})
string(CONCAT RELPATH "Assets\\Data\\" ${RELPATH})
endif()
cmake_print_variables(${RELPATH})
set_property(SOURCE ${ITEM} PROPERTY VS_DEPLOYMENT_CONTENT 1)
set_property(SOURCE ${ITEM} PROPERTY VS_DEPLOYMENT_LOCATION ${RELPATH})
endforeach()
# Define the application target. To change its name, change BINARY_NAME in the
# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
# work.
#
# Any new source files that you add to the application should be added here.
add_executable (${BINARY_NAME} WIN32
main.cpp
flutter_frameworkview.cpp
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
${RESOURCE_FILES}
${INSTALL_MANIFEST_CONTENT}
)
# Apply the standard set of build settings. This can be removed for applications
# that need different build settings.
apply_standard_settings(${BINARY_NAME})
# Disable Windows macros that collide with C++ standard library functions.
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
# Add dependency libraries and include directories. Add any application-specific
# dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE WindowsApp flutter flutter_wrapper_app)
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
# Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble)
{
// See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file.
"configurations": [
{
"name": "Debug",
"generator": "Visual Studio 15 2017 Win64",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
},
{
"name": "Release",
"generator": "Visual Studio 15 2017 Win64",
"configurationType": "Release",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
}
]
}
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
IgnorableNamespaces="uap mp">
<Identity Name="@PACKAGE_GUID@" Publisher="CN=CMake Test Cert" Version="1.1.0.0" />
<mp:PhoneIdentity PhoneProductId="@PACKAGE_GUID@" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>@SHORT_NAME@</DisplayName>
<PublisherDisplayName>CMake Test Cert</PublisherDisplayName>
<Logo>Assets/StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.65535.65535" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="@SHORT_NAME@.App">
<uap:VisualElements
DisplayName="@SHORT_NAME@"
Description="@SHORT_NAME@"
BackgroundColor="#336699"
Square150x150Logo="Assets/Square150x150Logo.png"
Square44x44Logo="Assets/Square44x44Logo.png"
>
<uap:SplashScreen Image="Assets/SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClientServer"/>
<Capability Name="internetClient"/>
<Capability Name="privateNetworkClientServer"/>
<Capability Name="codeGeneration"/></Capabilities>
</Package>
#include "winrt/Windows.ApplicationModel.Core.h"
#include "winrt/Windows.Foundation.h"
#include "winrt/Windows.System.Profile.h"
#include "winrt/Windows.System.Threading.h"
#include "winrt/Windows.UI.Core.h"
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Graphics.Display.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.UI.Popups.h>
#include <winrt/Windows.UI.ViewManagement.Core.h>
#include <winrt/Windows.UI.ViewManagement.h>
#include <chrono>
#include <memory>
#include <thread>
#include <flutter/flutter_view_controller.h>
#include <flutter/flutter_windows.h>
#include <flutter/generated_plugin_registrant.h>
#include <flutter/plugin_registry.h>
struct FlutterFrameworkView
: winrt::implements<
FlutterFrameworkView,
winrt::Windows::ApplicationModel::Core::IFrameworkView> {
// |winrt::Windows::ApplicationModel::Core::IFrameworkView|
void
Initialize(winrt::Windows::ApplicationModel::Core::CoreApplicationView const
&applicationView) {
// Layout scaling must be disabled in the appinitialization phase in order
// to take effect correctly.
if (winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo()
.DeviceFamily() == L"Windows.Xbox") {
bool result = winrt::Windows::UI::ViewManagement::ApplicationViewScaling::
TrySetDisableLayoutScaling(true);
if (!result) {
OutputDebugString(L"Couldn't disable layout scaling");
}
}
main_view_ = applicationView;
main_view_.Activated({this, &FlutterFrameworkView::OnActivated});
}
// |winrt::Windows::ApplicationModel::Core::IFrameworkView|
void Uninitialize() {
main_view_.Activated(nullptr);
main_view_ = nullptr;
}
// |winrt::Windows::ApplicationModel::Core::IFrameworkView|
void Load(winrt::hstring const &) {}
// |winrt::Windows::ApplicationModel::Core::IFrameworkView|
void Run() {
winrt::Windows::UI::Core::CoreWindow window =
winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread();
winrt::Windows::UI::Core::CoreDispatcher dispatcher = window.Dispatcher();
dispatcher.ProcessEvents(
winrt::Windows::UI::Core::CoreProcessEventsOption::ProcessUntilQuit);
}
// |winrt::Windows::ApplicationModel::Core::IFrameworkView|
winrt::Windows::Foundation::IAsyncAction
SetWindow(winrt::Windows::UI::Core::CoreWindow const &window) {
// Capture reference to window.
window_ = window;
// Lay out the window's content within the region occupied by the
// CoreWindow.
auto appView = winrt::Windows::UI::ViewManagement::ApplicationView::
GetForCurrentView();
appView.SetDesiredBoundsMode(winrt::Windows::UI::ViewManagement::
ApplicationViewBoundsMode::UseCoreWindow);
// Configure folder paths.
try {
winrt::Windows::Storage::StorageFolder folder =
winrt::Windows::ApplicationModel::Package::Current()
.InstalledLocation();
winrt::Windows::Storage::StorageFolder assets =
co_await folder.GetFolderAsync(L"Assets");
winrt::Windows::Storage::StorageFolder data =
co_await assets.GetFolderAsync(L"data");
winrt::Windows::Storage::StorageFolder flutter_assets =
co_await data.GetFolderAsync(L"flutter_assets");
winrt::Windows::Storage::StorageFile icu_data =
co_await data.GetFileAsync(L"icudtl.dat");
#if NDEBUG
winrt::Windows::Storage::StorageFile aot_data =
co_await data.GetFileAsync(L"app.so");
#endif
std::wstring flutter_assets_path{flutter_assets.Path()};
std::wstring icu_data_path{icu_data.Path()};
std::wstring aot_data_path {
#if NDEBUG
aot_data.Path()
#endif
};
flutter::DartProject project(flutter_assets_path, icu_data_path,
aot_data_path);
// Construct viewcontroller using the Window and project
flutter_view_controller_ = std::make_unique<flutter::FlutterViewController>(
static_cast<ABI::Windows::ApplicationModel::Core::CoreApplicationView*>(winrt::get_abi(main_view_)),
static_cast<ABI::Windows::ApplicationModel::Activation::IActivatedEventArgs*>(winrt::get_abi(launch_args_)),
project);
// If plugins present, register them.
RegisterPlugins(flutter_view_controller_.get()->engine());
} catch (winrt::hresult_error &err) {
winrt::Windows::UI::Popups::MessageDialog md =
winrt::Windows::UI::Popups::MessageDialog::MessageDialog(
L"There was a problem starting the engine: " + err.message());
md.ShowAsync();
}
}
void OnActivated(
winrt::Windows::ApplicationModel::Core::CoreApplicationView const
&applicationView,
winrt::Windows::ApplicationModel::Activation::IActivatedEventArgs const
&args) {
// Activate the application window, making it visible and enabling it to
// receive events.
applicationView.CoreWindow().Activate();
// Capture launch args to later pass to Flutter.
launch_args_ = args;
}
// Current CoreApplicationView.
winrt::Windows::ApplicationModel::Core::CoreApplicationView main_view_{
nullptr};
// Current CoreWindow.
winrt::Windows::UI::Core::CoreWindow window_{nullptr};
// Current FlutterViewController.
std::unique_ptr<flutter::FlutterViewController> flutter_view_controller_{
nullptr};
// Launch args that were passed in on activation.
winrt::Windows::ApplicationModel::Activation::IActivatedEventArgs
launch_args_;
};
#include <windows.h>
#include "winrt/Windows.ApplicationModel.Core.h"
#include "winrt/Windows.Foundation.h"
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.UI.ViewManagement.Core.h>
#include <winrt/Windows.UI.ViewManagement.h>
#include <memory>
#include "flutter_frameworkview.cpp"
struct App
: winrt::implements<
App, winrt::Windows::ApplicationModel::Core::IFrameworkViewSource> {
App() { view_ = winrt::make_self<FlutterFrameworkView>(); }
// |winrt::Windows::ApplicationModel::Core::IFrameworkViewSource|
winrt::Windows::ApplicationModel::Core::IFrameworkView CreateView() {
return view_.as<winrt::Windows::ApplicationModel::Core::IFrameworkView>();
}
winrt::com_ptr<FlutterFrameworkView> view_;
};
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) {
winrt::Windows::ApplicationModel::Core::CoreApplication::Run(
winrt::make<App>());
}
......@@ -5,7 +5,6 @@
"templates/app/lib/main.dart.tmpl",
"templates/app/pubspec.yaml.tmpl",
"templates/app/README.md.tmpl",
"templates/app/winuwp.tmpl/.gitignore",
"templates/app_shared/.gitignore.tmpl",
"templates/app_shared/.idea/libraries/Dart_SDK.xml.tmpl",
......@@ -139,64 +138,6 @@
"templates/app_shared/windows.tmpl/runner/utils.h",
"templates/app_shared/windows.tmpl/runner/win32_window.cpp",
"templates/app_shared/windows.tmpl/runner/win32_window.h",
"templates/app_shared/winuwp.tmpl/CMakeLists.txt.tmpl",
"templates/app_shared/winuwp.tmpl/flutter/CMakeLists.txt",
"templates/app_shared/winuwp.tmpl/project_version",
"templates/app_shared/winuwp.tmpl/runner_uwp/appxmanifest.in",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/LargeTile.scale-100.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/LargeTile.scale-125.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/LargeTile.scale-150.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/LargeTile.scale-200.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/LargeTile.scale-400.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/LockScreenLogo.scale-200.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/SmallTile.scale-100.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/SmallTile.scale-125.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/SmallTile.scale-150.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/SmallTile.scale-200.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/SmallTile.scale-400.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/SplashScreen.scale-100.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/SplashScreen.scale-125.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/SplashScreen.scale-150.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/SplashScreen.scale-200.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/SplashScreen.scale-400.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square150x150Logo.scale-100.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square150x150Logo.scale-125.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square150x150Logo.scale-150.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square150x150Logo.scale-200.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square150x150Logo.scale-400.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.altform-unplated_targetsize-16.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.altform-unplated_targetsize-256.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.altform-unplated_targetsize-32.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.altform-unplated_targetsize-48.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.scale-100.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.scale-125.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.scale-150.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.scale-200.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.scale-400.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.targetsize-16.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.targetsize-24.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.targetsize-256.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.targetsize-32.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Square44x44Logo.targetsize-48.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/StoreLogo.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/StoreLogo.scale-100.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/StoreLogo.scale-125.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/StoreLogo.scale-150.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/StoreLogo.scale-200.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/StoreLogo.scale-400.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/Wide310x150Logo.scale-200.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/WideTile.scale-100.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/WideTile.scale-125.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/WideTile.scale-150.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/WideTile.scale-200.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Assets/WideTile.scale-400.png.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/CMakeLists.txt.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/CMakeSettings.json",
"templates/app_shared/winuwp.tmpl/runner_uwp/flutter_frameworkview.cpp",
"templates/app_shared/winuwp.tmpl/runner_uwp/main.cpp",
"templates/app_shared/winuwp.tmpl/runner_uwp/resources.pri.img.tmpl",
"templates/app_shared/winuwp.tmpl/runner_uwp/Windows_TemporaryKey.pfx.img.tmpl",
"templates/app_test_widget/test/widget_test.dart.tmpl",
......
......@@ -10,7 +10,6 @@ import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build_windows.dart';
import 'package:flutter_tools/src/commands/build_winuwp.dart';
import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/windows/visual_studio.dart';
......@@ -23,7 +22,6 @@ import '../../src/test_flutter_command_runner.dart';
const String flutterRoot = r'C:\flutter';
const String buildFilePath = r'C:\windows\CMakeLists.txt';
const String buildUwpFilePath = r'C:\winuwp\CMakeLists.txt';
const String visualStudioPath = r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community';
const String _cmakePath = visualStudioPath + r'\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe';
const String _defaultGenerator = 'Visual Studio 16 2019';
......@@ -72,31 +70,19 @@ void main() {
setUpMockCoreProjectFiles();
}
void setUpMockUwpFilesForBuild(int version) {
final Directory projectDirectory = (fileSystem.file(buildUwpFilePath)
..createSync(recursive: true))
.parent;
projectDirectory.childFile('project_version').writeAsString(version.toString());
setUpMockCoreProjectFiles();
}
// Returns the command matching the build_windows call to generate CMake
// files.
FakeCommand cmakeGenerationCommand({
void Function() onRun,
bool winuwp = false,
String generator = _defaultGenerator,
}) {
return FakeCommand(
command: <String>[
_cmakePath,
'-S',
fileSystem.path.dirname(winuwp ? buildUwpFilePath : buildFilePath),
fileSystem.path.dirname(buildFilePath),
'-B',
if (winuwp)
r'build\winuwp'
else
r'build\windows',
r'build\windows',
'-G',
generator,
],
......@@ -109,20 +95,15 @@ void main() {
bool verbose = false,
void Function() onRun,
String stdout = '',
bool winuwp = false,
}) {
return FakeCommand(
command: <String>[
_cmakePath,
'--build',
if (winuwp)
r'build\winuwp'
else
r'build\windows',
r'build\windows',
'--config',
buildMode,
if (!winuwp)
...<String>['--target', 'INSTALL'],
...<String>['--target', 'INSTALL'],
if (verbose)
'--verbose'
],
......@@ -615,125 +596,6 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: windowsPlatform),
Usage: () => usage,
});
testUsingContext('Windows UWP build fails when there is no windows project', () async {
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
..visualStudioOverride = fakeVisualStudio;
setUpMockCoreProjectFiles();
expect(createTestCommandRunner(command).run(
const <String>['winuwp', '--no-pub']
), throwsToolExit(message: 'No Windows UWP desktop project configured. See '
'https://docs.flutter.dev/desktop#add-desktop-support-to-an-existing-flutter-app '
'to learn about adding Windows support to a project.'));
}, overrides: <Type, Generator>{
Platform: () => windowsPlatform,
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
FeatureFlags: () => TestFeatureFlags(isWindowsUwpEnabled: true),
});
testUsingContext('Windows build fails on non windows platform', () async {
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
..visualStudioOverride = fakeVisualStudio;
setUpMockUwpFilesForBuild(0);
expect(createTestCommandRunner(command).run(
const <String>['winuwp', '--no-pub']
), throwsToolExit());
}, overrides: <Type, Generator>{
Platform: () => notWindowsPlatform,
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
FeatureFlags: () => TestFeatureFlags(isWindowsUwpEnabled: true),
});
testUsingContext('Windows UWP build fails on non windows platform', () async {
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
..visualStudioOverride = fakeVisualStudio;
setUpMockProjectFilesForBuild();
expect(createTestCommandRunner(command).run(
const <String>['winuwp', '--no-pub']
), throwsToolExit(message: '"build winuwp" only supported on Windows hosts.'));
}, overrides: <Type, Generator>{
Platform: () => notWindowsPlatform,
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
FeatureFlags: () => TestFeatureFlags(isWindowsUwpEnabled: true),
});
testUsingContext('Windows UWP build fails when the project version is out of date', () async {
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
..visualStudioOverride = fakeVisualStudio;
setUpMockUwpFilesForBuild(-1);
expect(createTestCommandRunner(command).run(
const <String>['winuwp', '--no-pub']
), throwsToolExit(message: 'The Windows UWP project template and build process has changed. '
'In order to build you must delete the winuwp directory and re-create the project'));
}, overrides: <Type, Generator>{
Platform: () => windowsPlatform,
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
FeatureFlags: () => TestFeatureFlags(isWindowsUwpEnabled: true),
});
testUsingContext('Windows UWP build fails when feature is disabled', () async {
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
..visualStudioOverride = fakeVisualStudio;
setUpMockProjectFilesForBuild();
// This message should include 'To enable, run "flutter config --enable-windows-uwp-desktop"."
// once the `windowsUwpEmbedding` feature is available on all channels.
expect(createTestCommandRunner(command).run(
const <String>['winuwp', '--no-pub']
), throwsToolExit(message: RegExp(r'"build winuwp" is not currently supported\.$')));
}, overrides: <Type, Generator>{
Platform: () => windowsPlatform,
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
FeatureFlags: () => TestFeatureFlags(),
});
testUsingContext('Windows UWP build completes successfully', () async {
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
..visualStudioOverride = fakeVisualStudio;
setUpMockUwpFilesForBuild(0);
await createTestCommandRunner(command).run(
const <String>['winuwp', '--no-pub']
);
}, overrides: <Type, Generator>{
Platform: () => windowsPlatform,
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
const FakeCommand(
command: <String>[
r'C:\flutter\bin\flutter',
'assemble',
'--no-version-check',
'--output=build',
'-dTargetPlatform=windows-uwp-x64',
'-dTrackWidgetCreation=true',
'-dBuildMode=release',
r'-dTargetFile=lib\main.dart',
'-dTreeShakeIcons="true"',
'-dDartObfuscation=false',
'release_bundle_windows_assets_uwp'
],
),
cmakeGenerationCommand(winuwp: true),
buildCommand('Release', stdout: 'STDOUT STUFF', winuwp: true),
]),
FeatureFlags: () => TestFeatureFlags(isWindowsUwpEnabled: true),
});
}
class FakeVisualStudio extends Fake implements VisualStudio {
......
......@@ -811,7 +811,6 @@ void main() {
expect(projectDir.childDirectory('macos'), isNot(exists));
expect(projectDir.childDirectory('windows'), isNot(exists));
expect(projectDir.childDirectory('web'), isNot(exists));
expect(projectDir.childDirectory('winuwp'), isNot(exists));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(),
});
......@@ -830,42 +829,14 @@ void main() {
expect(projectDir.childDirectory('macos'), isNot(exists));
expect(projectDir.childDirectory('windows'), isNot(exists));
expect(projectDir.childDirectory('web'), isNot(exists));
expect(projectDir.childDirectory('winuwp'), isNot(exists));
expect(projectDir.childDirectory('example').childDirectory('linux'), isNot(exists));
expect(projectDir.childDirectory('example').childDirectory('macos'), isNot(exists));
expect(projectDir.childDirectory('example').childDirectory('windows'), isNot(exists));
expect(projectDir.childDirectory('example').childDirectory('web'), isNot(exists));
expect(projectDir.childDirectory('example').childDirectory('winuwp'), isNot(exists));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(),
});
testUsingContext('app supports Windows UWP if requested', () async {
Cache.flutterRoot = '../..';
final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>[
'create',
'--no-pub',
'--platform=winuwp',
projectDir.path,
]);
expect(projectDir.childDirectory('linux'), isNot(exists));
expect(projectDir.childDirectory('android'), isNot(exists));
expect(projectDir.childDirectory('ios'), isNot(exists));
expect(projectDir.childDirectory('windows'), isNot(exists));
expect(projectDir.childDirectory('macos'), isNot(exists));
expect(projectDir.childDirectory('web'), isNot(exists));
expect(projectDir.childDirectory('winuwp'), exists);
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsUwpEnabled: true),
Logger: () => logger,
});
testUsingContext('app supports Linux if requested', () async {
Cache.flutterRoot = '../..';
......@@ -885,7 +856,6 @@ void main() {
expect(projectDir.childDirectory('windows'), isNot(exists));
expect(projectDir.childDirectory('macos'), isNot(exists));
expect(projectDir.childDirectory('web'), isNot(exists));
expect(projectDir.childDirectory('winuwp'), isNot(exists));
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
......
......@@ -141,18 +141,6 @@ void main() {
artifacts.getArtifactPath(Artifact.flutterTester, platform: TargetPlatform.linux_arm64),
fileSystem.path.join('root', 'bin', 'cache', 'artifacts', 'engine', 'linux-arm64', 'flutter_tester'),
);
expect(
artifacts.getArtifactPath(Artifact.windowsUwpDesktopPath, platform: TargetPlatform.windows_uwp_x64, mode: BuildMode.debug),
fileSystem.path.join('root', 'bin', 'cache', 'artifacts', 'engine', 'windows-uwp-x64-debug'),
);
expect(
artifacts.getArtifactPath(Artifact.windowsUwpDesktopPath, platform: TargetPlatform.windows_uwp_x64, mode: BuildMode.profile),
fileSystem.path.join('root', 'bin', 'cache', 'artifacts', 'engine', 'windows-uwp-x64-profile'),
);
expect(
artifacts.getArtifactPath(Artifact.windowsUwpDesktopPath, platform: TargetPlatform.windows_uwp_x64, mode: BuildMode.release),
fileSystem.path.join('root', 'bin', 'cache', 'artifacts', 'engine', 'windows-uwp-x64-release'),
);
expect(
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
fileSystem.path.join('root', 'bin', 'cache', 'dart-sdk', 'bin', 'snapshots', 'frontend_server.dart.snapshot')
......@@ -358,20 +346,6 @@ void main() {
expect(artifacts.getHostArtifact(HostArtifact.engineDartBinary).path, contains('.exe'));
});
testWithoutContext('Looks up windows UWP artifacts in host engine', () async {
artifacts = LocalEngineArtifacts(
fileSystem.path.join(fileSystem.currentDirectory.path, 'out', 'winuwp_debug_unopt'),
fileSystem.path.join(fileSystem.currentDirectory.path, 'out', 'winuwp_debug_unopt'),
cache: cache,
fileSystem: fileSystem,
platform: FakePlatform(operatingSystem: 'windows'),
processManager: FakeProcessManager.any(),
operatingSystemUtils: FakeOperatingSystemUtils(),
);
expect(artifacts.getArtifactPath(Artifact.windowsUwpDesktopPath), '/out/winuwp_debug_unopt');
});
testWithoutContext('Looks up dart on linux platforms', () async {
expect(artifacts.getHostArtifact(HostArtifact.engineDartBinary).path, isNot(contains('.exe')));
});
......
......@@ -131,7 +131,6 @@ void main() {
'linux-x64': false,
'linux-arm64': false,
'windows-x64': false,
'windows-uwp-x64': false,
'web-javascript': true,
'ios': false,
'android': false,
......
......@@ -125,107 +125,6 @@ void main() {
]));
});
testWithoutContext('UnpackWindowsUwp copies files to the correct winuwp/ cache directory', () async {
final Artifacts artifacts = Artifacts.test();
final FileSystem fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
final Environment environment = Environment.test(
fileSystem.currentDirectory,
artifacts: artifacts,
processManager: FakeProcessManager.any(),
fileSystem: fileSystem,
logger: BufferLogger.test(),
defines: <String, String>{
kBuildMode: 'debug',
},
);
final DepfileService depfileService = DepfileService(
logger: BufferLogger.test(),
fileSystem: fileSystem,
);
environment.buildDir.createSync(recursive: true);
final String windowsDesktopPath = artifacts.getArtifactPath(Artifact.windowsUwpDesktopPath, platform: TargetPlatform.windows_x64, mode: BuildMode.debug);
final String windowsCppClientWrapper = artifacts.getArtifactPath(Artifact.windowsUwpCppClientWrapper, platform: TargetPlatform.windows_x64, mode: BuildMode.debug);
final String icuData = artifacts.getArtifactPath(Artifact.icuData, platform: TargetPlatform.windows_x64);
final List<String> requiredFiles = <String>[
'$windowsDesktopPath\\flutter_export.h',
'$windowsDesktopPath\\flutter_messenger.h',
'$windowsDesktopPath\\flutter_windows_winuwp.dll',
'$windowsDesktopPath\\flutter_windows_winuwp.dll.exp',
'$windowsDesktopPath\\flutter_windows_winuwp.dll.lib',
'$windowsDesktopPath\\flutter_windows_winuwp.dll.pdb',
'$windowsDesktopPath\\flutter_plugin_registrar.h',
'$windowsDesktopPath\\flutter_texture_registrar.h',
'$windowsDesktopPath\\flutter_windows.h',
icuData,
'$windowsCppClientWrapper\\foo',
r'C:\packages\flutter_tools\lib\src\build_system\targets\windows.dart',
];
for (final String path in requiredFiles) {
fileSystem.file(path).createSync(recursive: true);
}
fileSystem.directory('windows').createSync();
await const UnpackWindowsUwp().build(environment);
// Output files are copied correctly.
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_export.h'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_messenger.h'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_windows_winuwp.dll'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_windows_winuwp.dll.exp'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_windows_winuwp.dll.lib'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_windows_winuwp.dll.pdb'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_export.h'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_messenger.h'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_plugin_registrar.h'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_texture_registrar.h'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\ephemeral\flutter_windows.h'), exists);
expect(fileSystem.file(r'C:\winuwp\flutter\flutter_windows.h'), exists);
expect(fileSystem.file('C:\\winuwp\\flutter\\ephemeral\\$icuData'), exists);
expect(fileSystem.file('C:\\winuwp\\flutter\\ephemeral\\$windowsCppClientWrapper\\foo'), exists);
final File outputDepfile = environment.buildDir
.childFile('windows_uwp_engine_sources.d');
// Depfile is created correctly.
expect(outputDepfile, exists);
final List<String> inputPaths = depfileService.parse(outputDepfile)
.inputs.map((File file) => file.path).toList();
final List<String> outputPaths = depfileService.parse(outputDepfile)
.outputs.map((File file) => file.path).toList();
// Depfile has expected sources.
expect(inputPaths, unorderedEquals(<String>[
'$windowsDesktopPath\\flutter_export.h',
'$windowsDesktopPath\\flutter_messenger.h',
'$windowsDesktopPath\\flutter_windows_winuwp.dll',
'$windowsDesktopPath\\flutter_windows_winuwp.dll.exp',
'$windowsDesktopPath\\flutter_windows_winuwp.dll.lib',
'$windowsDesktopPath\\flutter_windows_winuwp.dll.pdb',
'$windowsDesktopPath\\flutter_plugin_registrar.h',
'$windowsDesktopPath\\flutter_texture_registrar.h',
'$windowsDesktopPath\\flutter_windows.h',
icuData,
'$windowsCppClientWrapper\\foo',
]));
expect(outputPaths, unorderedEquals(<String>[
r'C:\winuwp\flutter\ephemeral\flutter_export.h',
r'C:\winuwp\flutter\ephemeral\flutter_messenger.h',
r'C:\winuwp\flutter\ephemeral\flutter_windows_winuwp.dll',
r'C:\winuwp\flutter\ephemeral\flutter_windows_winuwp.dll.exp',
r'C:\winuwp\flutter\ephemeral\flutter_windows_winuwp.dll.lib',
r'C:\winuwp\flutter\ephemeral\flutter_windows_winuwp.dll.pdb',
r'C:\winuwp\flutter\ephemeral\flutter_plugin_registrar.h',
r'C:\winuwp\flutter\ephemeral\flutter_texture_registrar.h',
r'C:\winuwp\flutter\ephemeral\flutter_windows.h',
r'C:\winuwp\flutter\flutter_windows.h',
'C:\\winuwp\\flutter\\ephemeral\\$icuData',
'C:\\winuwp\\flutter\\ephemeral\\$windowsCppClientWrapper\\foo',
]));
});
// AssetBundleFactory still uses context injection
FileSystem fileSystem;
......@@ -288,7 +187,7 @@ void main() {
environment.buildDir.childFile('app.so').createSync(recursive: true);
await const WindowsAotBundle(AotElfProfile(TargetPlatform.windows_x64), uwp: false).build(environment);
await const WindowsAotBundle(AotElfProfile(TargetPlatform.windows_x64)).build(environment);
await const ProfileBundleWindowsAssets().build(environment);
// Depfile is created and so is copied.
......@@ -301,60 +200,6 @@ void main() {
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('ReleaseBundleWindowsAssets creates correct bundle structure with UWP', () async {
final Environment environment = Environment.test(
fileSystem.currentDirectory,
artifacts: Artifacts.test(),
processManager: FakeProcessManager.any(),
fileSystem: fileSystem,
logger: BufferLogger.test(),
defines: <String, String>{
kBuildMode: 'release',
}
);
environment.buildDir.childFile('app.so').createSync(recursive: true);
await const WindowsAotBundle(AotElfRelease(TargetPlatform.windows_x64), uwp: true).build(environment);
await const ReleaseBundleWindowsAssets().build(environment);
// Depfile is created and so is copied.
expect(environment.buildDir.childFile('flutter_assets.d'), exists);
expect(fileSystem.file(r'C:\winuwp\app.so'), exists);
expect(fileSystem.file(r'C:\flutter_assets\kernel_blob.bin').existsSync(), false);
expect(fileSystem.file(r'C:\flutter_assets\AssetManifest.json'), exists);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('ProfileBundleWindowsAssets creates correct bundle structure with UWP', () async {
final Environment environment = Environment.test(
fileSystem.currentDirectory,
artifacts: Artifacts.test(),
processManager: FakeProcessManager.any(),
fileSystem: fileSystem,
logger: BufferLogger.test(),
defines: <String, String>{
kBuildMode: 'profile',
}
);
environment.buildDir.childFile('app.so').createSync(recursive: true);
await const WindowsAotBundle(AotElfProfile(TargetPlatform.windows_x64), uwp: true).build(environment);
await const ProfileBundleWindowsAssets().build(environment);
// Depfile is created and so is copied.
expect(environment.buildDir.childFile('flutter_assets.d'), exists);
expect(fileSystem.file(r'C:\winuwp\app.so'), exists);
expect(fileSystem.file(r'C:\flutter_assets\kernel_blob.bin').existsSync(), false);
expect(fileSystem.file(r'C:\flutter_assets\AssetManifest.json'), exists);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('ReleaseBundleWindowsAssets creates correct bundle structure', () async {
final Environment environment = Environment.test(
fileSystem.currentDirectory,
......@@ -369,7 +214,7 @@ void main() {
environment.buildDir.childFile('app.so').createSync(recursive: true);
await const WindowsAotBundle(AotElfRelease(TargetPlatform.windows_x64), uwp: false).build(environment);
await const WindowsAotBundle(AotElfRelease(TargetPlatform.windows_x64)).build(environment);
await const ReleaseBundleWindowsAssets().build(environment);
// Depfile is created and so is copied.
......
......@@ -604,20 +604,6 @@ void main() {
]));
});
testWithoutContext('Windows UWP desktop artifacts include profile, debug, and release artifacts', () {
final Cache cache = Cache.test(processManager: FakeProcessManager.any());
final WindowsUwpEngineArtifacts artifacts = WindowsUwpEngineArtifacts(
cache,
platform: FakePlatform(operatingSystem: 'windows'),
);
expect(artifacts.getBinaryDirs(), containsAll(<Matcher>[
contains(contains('profile')),
contains(contains('release')),
contains(contains('debug')),
]));
});
testWithoutContext('Linux desktop artifacts ignore filtering when requested', () {
fakeProcessManager.addCommand(unameCommandForX64);
......
......@@ -1054,7 +1054,4 @@ class FakeFlutterProject extends Fake implements FlutterProject {
@override
WindowsProject windows;
@override
WindowsUwpProject windowsUwp;
}
......@@ -366,37 +366,5 @@ void main() {
expect(featureFlags.isWindowsEnabled, true);
});
// Windows UWP desktop
testWithoutContext('Flutter Windows UWP desktop off by default on master', () {
final FeatureFlags featureFlags = createFlags('master');
expect(featureFlags.isWindowsUwpEnabled, false);
});
testWithoutContext('Flutter Windows UWP desktop enabled with config on master', () {
final FeatureFlags featureFlags = createFlags('master');
testConfig.setValue('enable-windows-uwp-desktop', true);
expect(featureFlags.isWindowsUwpEnabled, true);
});
testWithoutContext('Flutter Windows UWP desktop config includes removal warning', () {
expect(windowsUwpEmbedding.extraHelpText, contains('Windows UWP support is obsolete and will be removed'));
});
testWithoutContext('Flutter Windows UWP desktop off by default on stable', () {
final FeatureFlags featureFlags = createFlags('stable');
expect(featureFlags.isWindowsUwpEnabled, false);
});
testWithoutContext('Flutter Windows UWP desktop not enabled with config on stable', () {
final FeatureFlags featureFlags = createFlags('stable');
testConfig.setValue('enable-windows-uwp-desktop', true);
expect(featureFlags.isWindowsUwpEnabled, false);
});
});
}
......@@ -272,8 +272,7 @@ void main() {
' windows:\n'
' pluginClass: WinSamplePlugin\n'
' supportedVariants:\n'
' - win32\n'
' - uwp\n';
' - win32\n';
final YamlMap pluginYaml = loadYaml(pluginYamlRaw) as YamlMap;
final Plugin plugin = Plugin.fromYaml(
......@@ -288,7 +287,6 @@ void main() {
final WindowsPlugin windowsPlugin = plugin.platforms[WindowsPlugin.kConfigKey]! as WindowsPlugin;
expect(windowsPlugin.supportedVariants, <PluginPlatformVariant>[
PluginPlatformVariant.win32,
PluginPlatformVariant.winuwp,
]);
});
......@@ -322,8 +320,7 @@ void main() {
' windows:\n'
' pluginClass: WinSamplePlugin\n'
' supportedVariants:\n'
' - not_yet_invented_variant\n'
' - uwp\n';
' - not_yet_invented_variant\n';
final YamlMap pluginYaml = loadYaml(pluginYamlRaw) as YamlMap;
final Plugin plugin = Plugin.fromYaml(
......@@ -336,9 +333,7 @@ void main() {
);
final WindowsPlugin windowsPlugin = plugin.platforms[WindowsPlugin.kConfigKey]! as WindowsPlugin;
expect(windowsPlugin.supportedVariants, <PluginPlatformVariant>{
PluginPlatformVariant.winuwp,
});
expect(windowsPlugin.supportedVariants, <PluginPlatformVariant>{});
});
testWithoutContext('Plugin parsing throws a fatal error on an empty plugin', () {
......
......@@ -1682,9 +1682,6 @@ class FakeFlutterProject extends Fake implements FlutterProject {
@override
WindowsProject windows;
@override
WindowsUwpProject windowsUwp;
}
class FakeMacOSProject extends Fake implements MacOSProject {
......
......@@ -93,31 +93,6 @@ void main() {
expect(logger.traceText, contains('Local engine source at /arbitrary/engine/src'));
});
testWithoutContext('treats winuwp_debug_unopt as a host engine', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
final Directory localEngine = fileSystem
.directory('$kArbitraryEngineRoot/src/out/winuwp_debug_unopt/')
..createSync(recursive: true);
fileSystem.directory('$kArbitraryEngineRoot/src/out/winuwp_debug_unopt/').createSync(recursive: true);
final BufferLogger logger = BufferLogger.test();
final LocalEngineLocator localEngineLocator = LocalEngineLocator(
fileSystem: fileSystem,
flutterRoot: 'flutter/flutter',
logger: logger,
userMessages: UserMessages(),
platform: FakePlatform(environment: <String, String>{}),
);
expect(
await localEngineLocator.findEnginePath(null, localEngine.path, null),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/winuwp_debug_unopt',
targetEngine: '/arbitrary/engine/src/out/winuwp_debug_unopt',
),
);
});
testWithoutContext('works if --local-engine is specified and --local-engine-src-path '
'is determined by --local-engine', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
......
// 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.
// @dart = 2.8
import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/windows/install_manifest.dart';
import '../../src/common.dart';
import '../../src/context.dart';
final Platform platform = FakePlatform(operatingSystem: 'windows');
void main() {
FileSystem fileSystem;
setUp(() {
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
});
testUsingContext('Generates install manifest for a debug build', () async {
final Logger logger = BufferLogger.test();
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
final Directory buildDirectory = fileSystem.currentDirectory
.childDirectory('build')
.childDirectory('winuwp');
await createManifest(
logger: logger,
fileSystem: fileSystem,
platform: platform,
project: flutterProject.windowsUwp,
buildDirectory: buildDirectory,
buildInfo: BuildInfo.debug,
);
final File manifest = flutterProject.windowsUwp.ephemeralDirectory.childFile('install_manifest');
expect(manifest, exists);
expect(manifest.readAsLinesSync(), unorderedEquals(<String>[
'C:/build/flutter_assets/kernel_blob.bin',
'C:/build/flutter_assets/AssetManifest.json',
'C:/winuwp/flutter/ephemeral/flutter_windows_winuwp.dll',
'C:/winuwp/flutter/ephemeral/flutter_windows_winuwp.dll.pdb',
'C:/winuwp/flutter/ephemeral/icudtl.dat',
]));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('Generates install manifest for a release build', () async {
final Logger logger = BufferLogger.test();
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
final Directory buildDirectory = fileSystem.currentDirectory
.childDirectory('build')
.childDirectory('winuwp');
await createManifest(
logger: logger,
fileSystem: fileSystem,
platform: platform,
project: flutterProject.windowsUwp,
buildDirectory: buildDirectory,
buildInfo: BuildInfo.release,
);
final File manifest = flutterProject.windowsUwp.ephemeralDirectory.childFile('install_manifest');
expect(manifest, exists);
expect(manifest.readAsLinesSync(), unorderedEquals(<String>[
'C:/build/winuwp/app.so',
'C:/build/flutter_assets/AssetManifest.json',
'C:/winuwp/flutter/ephemeral/flutter_windows_winuwp.dll',
'C:/winuwp/flutter/ephemeral/flutter_windows_winuwp.dll.pdb',
'C:/winuwp/flutter/ephemeral/icudtl.dat'
]));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('Generates install manifest for a release build with assets', () async {
final BufferLogger logger = BufferLogger.test();
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
final Directory buildDirectory = fileSystem.currentDirectory
.childDirectory('build')
.childDirectory('winuwp');
fileSystem.currentDirectory.childDirectory('.dart_tool').childFile('package_config.json')
..createSync(recursive: true)
..writeAsStringSync('''
{
"configVersion": 2,
"packages": []
}
''');
fileSystem.currentDirectory.childFile('pubspec.yaml')
..createSync()
..writeAsStringSync('''
name: foo
flutter:
assets:
- assets/foo.png
''');
fileSystem.currentDirectory
.childDirectory('assets')
.childFile('foo.png')
.createSync(recursive: true);
await createManifest(
logger: logger,
fileSystem: fileSystem,
platform: platform,
project: flutterProject.windowsUwp,
buildDirectory: buildDirectory,
buildInfo: BuildInfo.release,
);
final File manifest = flutterProject.windowsUwp.ephemeralDirectory.childFile('install_manifest');
expect(manifest, exists);
expect(manifest.readAsLinesSync(), unorderedEquals(<String>[
'C:/build/winuwp/app.so',
'C:/build/flutter_assets/assets/foo.png',
'C:/build/flutter_assets/AssetManifest.json',
'C:/build/flutter_assets/FontManifest.json',
'C:/build/flutter_assets/NOTICES.Z',
'C:/winuwp/flutter/ephemeral/flutter_windows_winuwp.dll',
'C:/winuwp/flutter/ephemeral/flutter_windows_winuwp.dll.pdb',
'C:/winuwp/flutter/ephemeral/icudtl.dat'
]));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
}
......@@ -13,7 +13,6 @@ import 'package:flutter_tools/src/plugins.dart';
import 'package:flutter_tools/src/project.dart';
import '../../src/common.dart';
import '../../src/fakes.dart';
const TemplateRenderer renderer = MustacheTemplateRenderer();
......@@ -63,94 +62,8 @@ void main() {
contains('#include <test/foo.h>'),
);
});
testWithoutContext('UWP injects plugins marked as UWP-compatible', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
setUpProject(fileSystem);
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
await writeWindowsUwpPluginFiles(flutterProject, <Plugin>[
Plugin(
name: 'test',
path: 'foo',
defaultPackagePlatforms: const <String, String>{},
pluginDartClassPlatforms: const <String, String>{},
platforms: const <String, PluginPlatform>{
WindowsPlugin.kConfigKey: WindowsPlugin(
name: 'test',
pluginClass: 'Foo',
variants: <PluginPlatformVariant>{PluginPlatformVariant.winuwp},
)},
dependencies: <String>[],
isDirectDependency: true,
),
], renderer);
final Directory managed = flutterProject.windowsUwp.managedDirectory;
expect(flutterProject.windowsUwp.generatedPluginCmakeFile, exists);
expect(managed.childFile('generated_plugin_registrant.h'), exists);
expect(
managed.childFile('generated_plugin_registrant.cc').readAsStringSync(),
contains('#include <test/foo.h>'),
);
});
testWithoutContext('UWP does not inject Win32-only plugins', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
setUpProject(fileSystem);
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
await writeWindowsUwpPluginFiles(flutterProject, <Plugin>[
Plugin(
name: 'test',
path: 'foo',
defaultPackagePlatforms: const <String, String>{},
pluginDartClassPlatforms: const <String, String>{},
platforms: const <String, PluginPlatform>{
WindowsPlugin.kConfigKey: WindowsPlugin(
name: 'test',
pluginClass: 'Foo',
variants: <PluginPlatformVariant>{PluginPlatformVariant.win32},
)},
dependencies: <String>[],
isDirectDependency: true,
),
], renderer);
final Directory managed = flutterProject.windowsUwp.managedDirectory;
expect(flutterProject.windowsUwp.generatedPluginCmakeFile, exists);
expect(managed.childFile('generated_plugin_registrant.h'), exists);
expect(
managed.childFile('generated_plugin_registrant.cc').readAsStringSync(),
isNot(contains('#include <test/foo.h>')),
);
});
testWithoutContext('Symlink injection treats UWP as Win32', () {
final FileSystem fileSystem = MemoryFileSystem.test();
setUpProject(fileSystem);
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
flutterProject.flutterPluginsDependenciesFile.writeAsStringSync(kPluginDependencies);
createPluginSymlinks(
flutterProject,
featureFlagsOverride: TestFeatureFlags(isWindowsUwpEnabled: true),
);
expect(flutterProject.windowsUwp.pluginSymlinkDirectory, exists);
final Link link = flutterProject.windowsUwp.pluginSymlinkDirectory.listSync().single as Link;
expect(link.path, '/winuwp/flutter/ephemeral/.plugin_symlinks/example');
expect(link.targetSync(), r'C:\\example\\');
});
}
void setUpProject(FileSystem fileSystem) {
fileSystem.file('pubspec.yaml').createSync();
fileSystem.file('winuwp/CMakeLists.txt')
.createSync(recursive: true);
fileSystem.file('winuwp/project_version')
..createSync(recursive: true)
..writeAsStringSync('0');
}
// 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:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/project.dart';
import '../../src/common.dart';
const String kExampleManifest = r'''
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
IgnorableNamespaces="uap mp">
<Identity Name="@PACKAGE_GUID@" Publisher="CN=CMake Test Cert" Version="2.3.1.4" />
<mp:PhoneIdentity PhoneProductId="@PACKAGE_GUID@" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>@SHORT_NAME@</DisplayName>
<PublisherDisplayName>CMake Test Cert</PublisherDisplayName>
<Logo>Assets/StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.65535.65535" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="@SHORT_NAME@.App">
<uap:VisualElements
DisplayName="@SHORT_NAME@"
Description="@SHORT_NAME@"
BackgroundColor="#336699"
Square150x150Logo="Assets/Square150x150Logo.png"
Square44x44Logo="Assets/Square44x44Logo.png"
>
<uap:SplashScreen Image="Assets/SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClientServer"/>
<Capability Name="internetClient"/>
<Capability Name="privateNetworkClientServer"/>
<Capability Name="codeGeneration"/></Capabilities>
</Package>
''';
void main() {
testWithoutContext('Project can parse the app version from the appx manifest', () {
final FileSystem fileSystem = MemoryFileSystem.test();
fileSystem.file('winuwp/runner_uwp/appxmanifest.in')
..createSync(recursive: true)
..writeAsStringSync(kExampleManifest);
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
expect(flutterProject.windowsUwp.packageVersion, '2.3.1.4');
});
testWithoutContext('Project returns null if appx manifest does not exist', () {
final FileSystem fileSystem = MemoryFileSystem.test();
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
expect(flutterProject.windowsUwp.packageVersion, null);
});
testWithoutContext('Project throws a tool exit if appxmanifest is not valid xml', () {
final FileSystem fileSystem = MemoryFileSystem.test();
fileSystem.file('winuwp/runner_uwp/appxmanifest.in')
..createSync(recursive: true)
..writeAsStringSync('[');
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
expect(() => flutterProject.windowsUwp.packageVersion, throwsToolExit());
});
testWithoutContext('Can parse the PACKAGE_GUID from the Cmake manifest', () {
final FileSystem fileSystem = MemoryFileSystem.test();
fileSystem.file('winuwp/runner_uwp/CMakeLists.txt')
..createSync(recursive: true)
..writeAsStringSync(r'''
cmake_minimum_required (VERSION 3.8)
set(CMAKE_SYSTEM_NAME WindowsStore)
set(CMAKE_SYSTEM_VERSION 10.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
include(CMakePrintHelpers)
project ("TestBedUWP")
set(APP_MANIFEST_NAME Package.appxmanifest)
set(APP_MANIFEST_TARGET_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${APP_MANIFEST_NAME})
set(SHORT_NAME ${BINARY_NAME})
set(PACKAGE_GUID "F941A77F-8AE1-4E3E-9611-68FBD3C62AE8")
''');
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
expect(flutterProject.windowsUwp.packageGuid, 'F941A77F-8AE1-4E3E-9611-68FBD3C62AE8');
});
testWithoutContext('Returns null if the PACKAGE_GUID cannot be found in the Cmake file', () {
final FileSystem fileSystem = MemoryFileSystem.test();
fileSystem.file('winuwp/runner_uwp/CMakeLists.txt')
..createSync(recursive: true)
..writeAsStringSync(r'''
cmake_minimum_required (VERSION 3.8)
set(CMAKE_SYSTEM_NAME WindowsStore)
set(CMAKE_SYSTEM_VERSION 10.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
include(CMakePrintHelpers)
project ("TestBedUWP")
set(APP_MANIFEST_NAME Package.appxmanifest)
set(APP_MANIFEST_TARGET_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${APP_MANIFEST_NAME})
set(SHORT_NAME ${BINARY_NAME})
''');
final FlutterProject flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
expect(flutterProject.windowsUwp.packageGuid, null);
});
}
......@@ -9,12 +9,9 @@ import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/windows/application_package.dart';
import 'package:flutter_tools/src/windows/uwptool.dart';
import 'package:flutter_tools/src/windows/windows_device.dart';
import 'package:flutter_tools/src/windows/windows_workflow.dart';
import 'package:test/fake.dart';
......@@ -42,46 +39,16 @@ void main() {
expect(windowsDevice.supportsRuntimeMode(BuildMode.jitRelease), false);
});
testWithoutContext('WindowsUwpDevice defaults', () async {
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
final String packagePath = fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
);
fileSystem.file(packagePath).createSync(recursive:true);
expect(await windowsDevice.targetPlatform, TargetPlatform.windows_uwp_x64);
expect(windowsDevice.name, 'Windows (UWP)');
expect(await windowsDevice.installApp(package), true);
expect(await windowsDevice.uninstallApp(package), true);
expect(await windowsDevice.isLatestBuildInstalled(package), false);
expect(await windowsDevice.isAppInstalled(package), false);
expect(windowsDevice.category, Category.desktop);
expect(windowsDevice.supportsRuntimeMode(BuildMode.debug), true);
expect(windowsDevice.supportsRuntimeMode(BuildMode.profile), true);
expect(windowsDevice.supportsRuntimeMode(BuildMode.release), true);
expect(windowsDevice.supportsRuntimeMode(BuildMode.jitRelease), false);
});
testWithoutContext('WindowsDevices does not list devices if the workflow is unsupported', () async {
expect(await WindowsDevices(
windowsWorkflow: WindowsWorkflow(
featureFlags: TestFeatureFlags(),
platform: FakePlatform(operatingSystem: 'windows'),
),
featureFlags: TestFeatureFlags(),
operatingSystemUtils: FakeOperatingSystemUtils(),
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
fileSystem: MemoryFileSystem.test(),
uwptool: FakeUwpTool(),
).devices, <Device>[]);
});
......@@ -95,61 +62,9 @@ void main() {
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
fileSystem: MemoryFileSystem.test(),
featureFlags: TestFeatureFlags(isWindowsEnabled: true),
uwptool: FakeUwpTool(),
).devices, hasLength(1));
});
testWithoutContext('WindowsDevices lists a UWP Windows device if feature is enabled', () async {
final FeatureFlags featureFlags = TestFeatureFlags(isWindowsEnabled: true, isWindowsUwpEnabled: true);
expect(await WindowsDevices(
windowsWorkflow: WindowsWorkflow(
featureFlags: featureFlags,
platform: FakePlatform(operatingSystem: 'windows')
),
operatingSystemUtils: FakeOperatingSystemUtils(),
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
fileSystem: MemoryFileSystem.test(),
featureFlags: featureFlags,
uwptool: FakeUwpTool(),
).devices, hasLength(2));
});
testWithoutContext('WindowsDevices has windows and winuwp well known devices', () async {
final FeatureFlags featureFlags = TestFeatureFlags(isWindowsEnabled: true, isWindowsUwpEnabled: true);
expect(WindowsDevices(
windowsWorkflow: WindowsWorkflow(
featureFlags: featureFlags,
platform: FakePlatform(operatingSystem: 'windows')
),
operatingSystemUtils: FakeOperatingSystemUtils(),
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
fileSystem: MemoryFileSystem.test(),
featureFlags: featureFlags,
uwptool: FakeUwpTool(),
).wellKnownIds, <String>['windows', 'winuwp']);
});
testWithoutContext('WindowsDevices ignores the timeout provided to discoverDevices', () async {
final WindowsDevices windowsDevices = WindowsDevices(
windowsWorkflow: WindowsWorkflow(
featureFlags: TestFeatureFlags(isWindowsEnabled: true),
platform: FakePlatform(operatingSystem: 'windows')
),
operatingSystemUtils: FakeOperatingSystemUtils(),
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
fileSystem: MemoryFileSystem.test(),
featureFlags: TestFeatureFlags(isWindowsEnabled: true),
uwptool: FakeUwpTool(),
);
// Timeout ignored.
final List<Device> devices = await windowsDevices.discoverDevices(timeout: const Duration(seconds: 10));
expect(devices, hasLength(1));
});
testWithoutContext('isSupportedForProject is true with editable host app', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsDevice windowsDevice = setUpWindowsDevice(fileSystem: fileSystem);
......@@ -191,196 +106,6 @@ void main() {
expect(windowsDevice.executablePathForDevice(fakeApp, BuildMode.profile), 'profile/executable');
expect(windowsDevice.executablePathForDevice(fakeApp, BuildMode.release), 'release/executable');
});
testWithoutContext('WinUWPDevice installs cert if not installed', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
uwptool.hasValidSignature = false;
final String packagePath = fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
);
fileSystem.file(packagePath).createSync(recursive:true);
final bool result = await windowsDevice.installApp(package);
expect(result, isTrue);
expect(uwptool.installCertRequests, hasLength(1));
expect(uwptool.installAppRequests, hasLength(1));
});
testWithoutContext('WinUWPDevice does not install cert if not installed', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
uwptool.hasValidSignature = true;
final String packagePath = fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
);
fileSystem.file(packagePath).createSync(recursive:true);
final bool result = await windowsDevice.installApp(package);
expect(result, isTrue);
expect(uwptool.installCertRequests, isEmpty);
expect(uwptool.installAppRequests, hasLength(1));
});
testWithoutContext('WinUWPDevice prefers installing multi-arch binaries', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
final String singleArchPath = fileSystem.path.absolute(fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
));
fileSystem.file(singleArchPath).createSync(recursive:true);
final String multiArchPath = fileSystem.path.absolute(fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_Debug_Test', 'testapp_1.2.3.4_Debug.msix',
));
fileSystem.file(multiArchPath).createSync(recursive:true);
final bool result = await windowsDevice.installApp(package);
expect(result, isTrue);
expect(uwptool.installAppRequests.single.packageUri, Uri.file(multiArchPath).toString());
});
testWithoutContext('WinUWPDevice falls back to installing single-arch binaries', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
final String singleArchPath = fileSystem.path.absolute(fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
));
fileSystem.file(singleArchPath).createSync(recursive:true);
final bool result = await windowsDevice.installApp(package);
expect(result, isTrue);
expect(uwptool.installAppRequests.single.packageUri, Uri.file(singleArchPath).toString());
});
testWithoutContext('WinUWPDevice can launch application if cert is installed', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
uwptool.hasValidSignature = true;
final String packagePath = fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
);
fileSystem.file(packagePath).createSync(recursive:true);
final LaunchResult result = await windowsDevice.startApp(
package,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
prebuiltApplication: true,
platformArgs: <String, Object>{},
);
expect(result.started, true);
expect(uwptool.installCertRequests, isEmpty);
expect(uwptool.launchAppRequests.single.packageFamily, 'PACKAGE-ID_publisher');
expect(uwptool.launchAppRequests.single.args, <String>[
'--observatory-port=12345',
'--disable-service-auth-codes',
'--enable-dart-profiling',
'--enable-checked-mode',
'--verify-entry-points',
]);
});
testWithoutContext('WinUWPDevice installs cert and can launch application if cert not installed', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
uwptool.hasValidSignature = false;
final String packagePath = fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
);
fileSystem.file(packagePath).createSync(recursive:true);
final LaunchResult result = await windowsDevice.startApp(
package,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
prebuiltApplication: true,
platformArgs: <String, Object>{},
);
expect(result.started, true);
expect(uwptool.installCertRequests, isNotEmpty);
expect(uwptool.launchAppRequests.single.packageFamily, 'PACKAGE-ID_publisher');
expect(uwptool.launchAppRequests.single.args, <String>[
'--observatory-port=12345',
'--disable-service-auth-codes',
'--enable-dart-profiling',
'--enable-checked-mode',
'--verify-entry-points',
]);
});
testWithoutContext('WinUWPDevice can launch application in release mode', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
final String packagePath = fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Release_Test', 'testapp_1.2.3.4_x64_Release.msix',
);
fileSystem.file(packagePath).createSync(recursive:true);
final LaunchResult result = await windowsDevice.startApp(
package,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.release),
prebuiltApplication: true,
platformArgs: <String, Object>{},
);
expect(result.started, true);
expect(uwptool.launchAppRequests.single.packageFamily, 'PACKAGE-ID_publisher');
expect(uwptool.launchAppRequests.single.args, <String>[]);
});
}
FlutterProject setUpFlutterProject(Directory directory) {
......@@ -404,119 +129,7 @@ WindowsDevice setUpWindowsDevice({
);
}
WindowsUWPDevice setUpWindowsUwpDevice({
FileSystem fileSystem,
Logger logger,
ProcessManager processManager,
UwpTool uwptool,
}) {
return WindowsUWPDevice(
fileSystem: fileSystem ?? MemoryFileSystem.test(),
logger: logger ?? BufferLogger.test(),
processManager: processManager ?? FakeProcessManager.any(),
operatingSystemUtils: FakeOperatingSystemUtils(),
uwptool: uwptool ?? FakeUwpTool(),
);
}
class FakeWindowsApp extends Fake implements WindowsApp {
@override
String executable(BuildMode buildMode) => '${buildMode.name}/executable';
}
class FakeBuildableUwpApp extends Fake implements BuildableUwpApp {
@override
String get id => 'PACKAGE-ID';
@override
String get name => 'testapp';
@override
String get projectVersion => '1.2.3.4';
// Test helper to get the expected package family.
static const String packageFamily = 'PACKAGE-ID_publisher';
}
class FakeUwpTool implements UwpTool {
bool isInstalled = false;
bool hasValidSignature = false;
final List<_GetPackageFamilyRequest> getPackageFamilyRequests = <_GetPackageFamilyRequest>[];
final List<_LaunchAppRequest> launchAppRequests = <_LaunchAppRequest>[];
final List<_InstallCertRequest> installCertRequests = <_InstallCertRequest>[];
final List<_InstallAppRequest> installAppRequests = <_InstallAppRequest>[];
final List<_UninstallAppRequest> uninstallAppRequests = <_UninstallAppRequest>[];
@override
Future<List<String>> listApps() async {
return isInstalled ? <String>[FakeBuildableUwpApp.packageFamily] : <String>[];
}
@override
Future<String/*?*/> getPackageFamilyName(String packageName) async {
getPackageFamilyRequests.add(_GetPackageFamilyRequest(packageName));
return isInstalled ? FakeBuildableUwpApp.packageFamily : null;
}
@override
Future<int/*?*/> launchApp(String packageFamily, List<String> args) async {
launchAppRequests.add(_LaunchAppRequest(packageFamily, args));
return 42;
}
@override
Future<bool> isSignatureValid(String packagePath) async {
return hasValidSignature;
}
@override
Future<bool> installCertificate(String certificatePath) async {
installCertRequests.add(_InstallCertRequest(certificatePath));
return true;
}
@override
Future<bool> installApp(String packageUri, List<String> dependencyUris) async {
installAppRequests.add(_InstallAppRequest(packageUri, dependencyUris));
isInstalled = true;
return true;
}
@override
Future<bool> uninstallApp(String packageFamily) async {
uninstallAppRequests.add(_UninstallAppRequest(packageFamily));
isInstalled = false;
return true;
}
}
class _GetPackageFamilyRequest {
const _GetPackageFamilyRequest(this.packageId);
final String packageId;
}
class _LaunchAppRequest {
const _LaunchAppRequest(this.packageFamily, this.args);
final String packageFamily;
final List<String> args;
}
class _InstallCertRequest {
const _InstallCertRequest(this.certificatePath);
final String certificatePath;
}
class _InstallAppRequest {
const _InstallAppRequest(this.packageUri, this.dependencyUris);
final String packageUri;
final List<String> dependencyUris;
}
class _UninstallAppRequest {
const _UninstallAppRequest(this.packageFamily);
final String packageFamily;
}
......@@ -425,7 +425,6 @@ class TestFeatureFlags implements FeatureFlags {
this.isIOSEnabled = true,
this.isFuchsiaEnabled = false,
this.areCustomDevicesEnabled = false,
this.isWindowsUwpEnabled = false,
});
@override
......@@ -455,9 +454,6 @@ class TestFeatureFlags implements FeatureFlags {
@override
final bool areCustomDevicesEnabled;
@override
final bool isWindowsUwpEnabled;
@override
bool isEnabled(Feature feature) {
switch (feature) {
......@@ -479,8 +475,6 @@ class TestFeatureFlags implements FeatureFlags {
return isFuchsiaEnabled;
case flutterCustomDevicesFeature:
return areCustomDevicesEnabled;
case windowsUwpEmbedding:
return isWindowsUwpEnabled;
}
return false;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment