Set the application-id in the Linux shell (#60053)

diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart
index 6739f6e..76aeb17 100644
--- a/packages/flutter_tools/lib/src/commands/create.dart
+++ b/packages/flutter_tools/lib/src/commands/create.dart
@@ -747,13 +747,18 @@
     final String pluginClassSnakeCase = snakeCase(pluginClass);
     final String pluginClassCapitalSnakeCase = pluginClassSnakeCase.toUpperCase();
     final String appleIdentifier = _createUTIIdentifier(organization, projectName);
+    final String androidIdentifier = _createAndroidIdentifier(organization, projectName);
+    // Linux uses the same scheme as the Android identifier.
+    // https://developer.gnome.org/gio/stable/GApplication.html#g-application-id-is-valid
+    final String linuxIdentifier = androidIdentifier;
 
     return <String, dynamic>{
       'organization': organization,
       'projectName': projectName,
-      'androidIdentifier': _createAndroidIdentifier(organization, projectName),
+      'androidIdentifier': androidIdentifier,
       'iosIdentifier': appleIdentifier,
       'macosIdentifier': appleIdentifier,
+      'linuxIdentifier': linuxIdentifier,
       'description': projectDescription,
       'dartSdk': '$flutterRoot/bin/cache/dart-sdk',
       'androidMinApiLevel': android_common.minApiLevel,
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart
index 045b1e6..5bffb2f 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -1039,6 +1039,8 @@
   @override
   String get pluginConfigKey => LinuxPlugin.kConfigKey;
 
+  static final RegExp _applicationIdPattern = RegExp(r'''^\s*set\s*\(\s*APPLICATION_ID\s*"(.*)"\s*\)\s*$''');
+
   Directory get _editableDirectory => parent.directory.childDirectory('linux');
 
   /// The directory in the project that is managed by Flutter. As much as
@@ -1067,6 +1069,10 @@
   Directory get pluginSymlinkDirectory => ephemeralDirectory.childDirectory('.plugin_symlinks');
 
   Future<void> ensureReadyForPlatformSpecificTooling() async {}
+
+  String get applicationId {
+    return _firstMatchInFile(cmakeFile, _applicationIdPattern)?.group(1);
+  }
 }
 
 /// The Fuchsia sub project
diff --git a/packages/flutter_tools/templates/app/linux.tmpl/CMakeLists.txt.tmpl b/packages/flutter_tools/templates/app/linux.tmpl/CMakeLists.txt.tmpl
index a1f3142..7f785aa 100644
--- a/packages/flutter_tools/templates/app/linux.tmpl/CMakeLists.txt.tmpl
+++ b/packages/flutter_tools/templates/app/linux.tmpl/CMakeLists.txt.tmpl
@@ -2,6 +2,7 @@
 project(runner LANGUAGES CXX)
 
 set(BINARY_NAME "{{projectName}}")
+set(APPLICATION_ID "{{linuxIdentifier}}")
 
 cmake_policy(SET CMP0063 NEW)
 
@@ -32,6 +33,8 @@
 find_package(PkgConfig REQUIRED)
 pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
 
+add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
+
 # Application build
 add_executable(${BINARY_NAME}
   "main.cc"
diff --git a/packages/flutter_tools/templates/app/linux.tmpl/my_application.cc.tmpl b/packages/flutter_tools/templates/app/linux.tmpl/my_application.cc.tmpl
index 6fe3050..5097955 100644
--- a/packages/flutter_tools/templates/app/linux.tmpl/my_application.cc.tmpl
+++ b/packages/flutter_tools/templates/app/linux.tmpl/my_application.cc.tmpl
@@ -40,5 +40,7 @@
 static void my_application_init(MyApplication* self) {}
 
 MyApplication* my_application_new() {
-  return MY_APPLICATION(g_object_new(my_application_get_type(), nullptr));
+  return MY_APPLICATION(g_object_new(my_application_get_type(),
+                                     "application-id", APPLICATION_ID,
+                                     nullptr));
 }
diff --git a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart
index 05d3051..9c83481 100644
--- a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart
+++ b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart
@@ -1037,7 +1037,7 @@
     Platform: _kNoColorTerminalPlatform,
   });
 
-  testUsingContext('has correct application id for android and bundle id for ios', () async {
+  testUsingContext('has correct application id for android, bundle id for ios and application id for Linux', () async {
     Cache.flutterRoot = '../..';
     when(mockFlutterVersion.frameworkRevision).thenReturn(frameworkRevision);
     when(mockFlutterVersion.channel).thenReturn(frameworkChannel);
@@ -1068,6 +1068,10 @@
         project.android.applicationId,
         'com.example.hello_flutter',
     );
+    expect(
+        project.linux.applicationId,
+        'com.example.hello_flutter',
+    );
 
     tmpProjectDir = globals.fs.path.join(tempDir.path, 'test_abc');
     await runner.run(<String>['create', '--template=app', '--no-pub', '--org', 'abc^*.1#@', tmpProjectDir]);
@@ -1092,9 +1096,14 @@
         project.android.applicationId,
         'flutter_project.untitled',
     );
+    expect(
+        project.linux.applicationId,
+        'flutter_project.untitled',
+    );
   }, overrides: <Type, Generator>{
     FlutterVersion: () => mockFlutterVersion,
     Platform: _kNoColorTerminalPlatform,
+    FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
   });
 
   testUsingContext('can re-gen default template over existing project', () async {