@@ -416,36 +416,167 @@ class DaemonDomain extends Domain {
416416 /// is correct.
417417 Future <Map <String , Object >> getSupportedPlatforms (Map <String , Object ?> args) async {
418418 final String ? projectRoot = _getStringArg (args, 'projectRoot' , required : true );
419- final List <String > result = < String > [];
419+ final List <String > platformTypes = < String > [];
420+ final Map <String , Object > platformTypesMap = < String , Object > {};
420421 try {
421422 final FlutterProject flutterProject = FlutterProject .fromDirectory (globals.fs.directory (projectRoot));
422423 final Set <SupportedPlatform > supportedPlatforms = flutterProject.getSupportedPlatforms ().toSet ();
423- if (featureFlags.isLinuxEnabled && supportedPlatforms.contains (SupportedPlatform .linux)) {
424- result.add ('linux' );
425- }
426- if (featureFlags.isMacOSEnabled && supportedPlatforms.contains (SupportedPlatform .macos)) {
427- result.add ('macos' );
428- }
429- if (featureFlags.isWindowsEnabled && supportedPlatforms.contains (SupportedPlatform .windows)) {
430- result.add ('windows' );
431- }
432- if (featureFlags.isIOSEnabled && supportedPlatforms.contains (SupportedPlatform .ios)) {
433- result.add ('ios' );
434- }
435- if (featureFlags.isAndroidEnabled && supportedPlatforms.contains (SupportedPlatform .android)) {
436- result.add ('android' );
437- }
438- if (featureFlags.isWebEnabled && supportedPlatforms.contains (SupportedPlatform .web)) {
439- result.add ('web' );
440- }
441- if (featureFlags.isFuchsiaEnabled && supportedPlatforms.contains (SupportedPlatform .fuchsia)) {
442- result.add ('fuchsia' );
443- }
444- if (featureFlags.areCustomDevicesEnabled) {
445- result.add ('custom' );
424+
425+ void handlePlatformType (
426+ PlatformType platform,
427+ ) {
428+ final List <Map <String , Object >> reasons = < Map <String , Object >> [];
429+ switch (platform) {
430+ case PlatformType .linux:
431+ if (! featureFlags.isLinuxEnabled) {
432+ reasons.add (< String , Object > {
433+ 'reasonText' : 'the Linux feature is not enabled' ,
434+ 'fixText' : 'Run "flutter config --enable-linux-desktop"' ,
435+ 'fixCode' : _ReasonCode .config.name,
436+ });
437+ }
438+ if (! supportedPlatforms.contains (SupportedPlatform .linux)) {
439+ reasons.add (< String , Object > {
440+ 'reasonText' : 'the Linux platform is not enabled for this project' ,
441+ 'fixText' : 'Run "flutter create --platforms=linux ." in your application directory' ,
442+ 'fixCode' : _ReasonCode .create.name,
443+ });
444+ }
445+ case PlatformType .macos:
446+ if (! featureFlags.isMacOSEnabled) {
447+ reasons.add (< String , Object > {
448+ 'reasonText' : 'the macOS feature is not enabled' ,
449+ 'fixText' : 'Run "flutter config --enable-macos-desktop"' ,
450+ 'fixCode' : _ReasonCode .config.name,
451+ });
452+ }
453+ if (! supportedPlatforms.contains (SupportedPlatform .macos)) {
454+ reasons.add (< String , Object > {
455+ 'reasonText' : 'the macOS platform is not enabled for this project' ,
456+ 'fixText' : 'Run "flutter create --platforms=macos ." in your application directory' ,
457+ 'fixCode' : _ReasonCode .create.name,
458+ });
459+ }
460+ case PlatformType .windows:
461+ if (! featureFlags.isWindowsEnabled) {
462+ reasons.add (< String , Object > {
463+ 'reasonText' : 'the Windows feature is not enabled' ,
464+ 'fixText' : 'Run "flutter config --enable-windows-desktop"' ,
465+ 'fixCode' : _ReasonCode .config.name,
466+ });
467+ }
468+ if (! supportedPlatforms.contains (SupportedPlatform .windows)) {
469+ reasons.add (< String , Object > {
470+ 'reasonText' : 'the Windows platform is not enabled for this project' ,
471+ 'fixText' : 'Run "flutter create --platforms=windows ." in your application directory' ,
472+ 'fixCode' : _ReasonCode .create.name,
473+ });
474+ }
475+ case PlatformType .ios:
476+ if (! featureFlags.isIOSEnabled) {
477+ reasons.add (< String , Object > {
478+ 'reasonText' : 'the iOS feature is not enabled' ,
479+ 'fixText' : 'Run "flutter config --enable-ios"' ,
480+ 'fixCode' : _ReasonCode .config.name,
481+ });
482+ }
483+ if (! supportedPlatforms.contains (SupportedPlatform .ios)) {
484+ reasons.add (< String , Object > {
485+ 'reasonText' : 'the iOS platform is not enabled for this project' ,
486+ 'fixText' : 'Run "flutter create --platforms=ios ." in your application directory' ,
487+ 'fixCode' : _ReasonCode .create.name,
488+ });
489+ }
490+ case PlatformType .android:
491+ if (! featureFlags.isAndroidEnabled) {
492+ reasons.add (< String , Object > {
493+ 'reasonText' : 'the Android feature is not enabled' ,
494+ 'fixText' : 'Run "flutter config --enable-android"' ,
495+ 'fixCode' : _ReasonCode .config.name,
496+ });
497+ }
498+ if (! supportedPlatforms.contains (SupportedPlatform .android)) {
499+ reasons.add (< String , Object > {
500+ 'reasonText' : 'the Android platform is not enabled for this project' ,
501+ 'fixText' : 'Run "flutter create --platforms=android ." in your application directory' ,
502+ 'fixCode' : _ReasonCode .create.name,
503+ });
504+ }
505+ case PlatformType .web:
506+ if (! featureFlags.isWebEnabled) {
507+ reasons.add (< String , Object > {
508+ 'reasonText' : 'the Web feature is not enabled' ,
509+ 'fixText' : 'Run "flutter config --enable-web"' ,
510+ 'fixCode' : _ReasonCode .config.name,
511+ });
512+ }
513+ if (! supportedPlatforms.contains (SupportedPlatform .web)) {
514+ reasons.add (< String , Object > {
515+ 'reasonText' : 'the Web platform is not enabled for this project' ,
516+ 'fixText' : 'Run "flutter create --platforms=web ." in your application directory' ,
517+ 'fixCode' : _ReasonCode .create.name,
518+ });
519+ }
520+ case PlatformType .fuchsia:
521+ if (! featureFlags.isFuchsiaEnabled) {
522+ reasons.add (< String , Object > {
523+ 'reasonText' : 'the Fuchsia feature is not enabled' ,
524+ 'fixText' : 'Run "flutter config --enable-fuchsia"' ,
525+ 'fixCode' : _ReasonCode .config.name,
526+ });
527+ }
528+ if (! supportedPlatforms.contains (SupportedPlatform .fuchsia)) {
529+ reasons.add (< String , Object > {
530+ 'reasonText' : 'the Fuchsia platform is not enabled for this project' ,
531+ 'fixText' : 'Run "flutter create --platforms=fuchsia ." in your application directory' ,
532+ 'fixCode' : _ReasonCode .create.name,
533+ });
534+ }
535+ case PlatformType .custom:
536+ if (! featureFlags.areCustomDevicesEnabled) {
537+ reasons.add (< String , Object > {
538+ 'reasonText' : 'the custom devices feature is not enabled' ,
539+ 'fixText' : 'Run "flutter config --enable-custom-devices"' ,
540+ 'fixCode' : _ReasonCode .config.name,
541+ });
542+ }
543+ case PlatformType .windowsPreview:
544+ // TODO(fujino): detect if there any plugins with native code
545+ if (! featureFlags.isPreviewDeviceEnabled) {
546+ reasons.add (< String , Object > {
547+ 'reasonText' : 'the Preview Device feature is not enabled' ,
548+ 'fixText' : 'Run "flutter config --enable-flutter-preview' ,
549+ 'fixCode' : _ReasonCode .config.name,
550+ });
551+ }
552+ if (! supportedPlatforms.contains (SupportedPlatform .windows)) {
553+ reasons.add (< String , Object > {
554+ 'reasonText' : 'the Windows platform is not enabled for this project' ,
555+ 'fixText' : 'Run "flutter create --platforms=windows ." in your application directory' ,
556+ 'fixCode' : _ReasonCode .create.name,
557+ });
558+ }
559+ }
560+
561+ if (reasons.isEmpty) {
562+ platformTypes.add (platform.name);
563+ platformTypesMap[platform.name] = const < String , Object > {
564+ 'isSupported' : true ,
565+ };
566+ } else {
567+ platformTypesMap[platform.name] = < String , Object > {
568+ 'isSupported' : false ,
569+ 'reasons' : reasons,
570+ };
571+ }
446572 }
573+
574+ PlatformType .values.forEach (handlePlatformType);
575+
447576 return < String , Object > {
448- 'platforms' : result,
577+ // TODO(fujino): delete this key https://github.com/flutter/flutter/issues/140473
578+ 'platforms' : platformTypes,
579+ 'platformTypes' : platformTypesMap,
449580 };
450581 } on Exception catch (err, stackTrace) {
451582 sendEvent ('log' , < String , Object ? > {
@@ -454,12 +585,16 @@ class DaemonDomain extends Domain {
454585 'error' : true ,
455586 });
456587 // On any sort of failure, fall back to Android and iOS for backwards
457- // comparability .
458- return < String , Object > {
588+ // compatibility .
589+ return const < String , Object > {
459590 'platforms' : < String > [
460591 'android' ,
461592 'ios' ,
462593 ],
594+ 'platformTypes' : < String , Object > {
595+ 'android' : < String , Object > {'isSupported' : true },
596+ 'ios' : < String , Object > {'isSupported' : true },
597+ },
463598 };
464599 }
465600 }
@@ -470,6 +605,14 @@ class DaemonDomain extends Domain {
470605 }
471606}
472607
608+ /// The reason a [PlatformType] is not currently supported.
609+ ///
610+ /// The [name] of this value will be sent as a response to daemon client.
611+ enum _ReasonCode {
612+ create,
613+ config,
614+ }
615+
473616typedef RunOrAttach = Future <void > Function ({
474617 Completer <DebugConnectionInfo >? connectionInfoCompleter,
475618 Completer <void >? appStartedCompleter,
0 commit comments