Is executable doesn't mean a+x (#47359)

diff --git a/packages/flutter_tools/lib/src/android/gradle_utils.dart b/packages/flutter_tools/lib/src/android/gradle_utils.dart
index 7aef19c..7802358 100644
--- a/packages/flutter_tools/lib/src/android/gradle_utils.dart
+++ b/packages/flutter_tools/lib/src/android/gradle_utils.dart
@@ -107,7 +107,7 @@
         return !destinationFile.existsSync();
       },
       onFileCopied: (File sourceFile, File destinationFile) {
-        if (_hasExecutePermission(sourceFile)) {
+        if (_hasAnyExecutableFlagSet(sourceFile)) {
           _giveExecutePermissionIfNeeded(destinationFile);
         }
       },
@@ -153,17 +153,25 @@
 
 const int _kExecPermissionMask = 0x49; // a+x
 
-/// Returns [true] if [executable] has execute permission.
-bool _hasExecutePermission(File executable) {
+/// Returns [true] if [executable] has all executable flag set.
+bool _hasAllExecutableFlagSet(File executable) {
   final FileStat stat = executable.statSync();
   assert(stat.type != FileSystemEntityType.notFound);
   printTrace('${executable.path} mode: ${stat.mode} ${stat.modeString()}.');
   return stat.mode & _kExecPermissionMask == _kExecPermissionMask;
 }
 
+/// Returns [true] if [executable] has any executable flag set.
+bool _hasAnyExecutableFlagSet(File executable) {
+  final FileStat stat = executable.statSync();
+  assert(stat.type != FileSystemEntityType.notFound);
+  printTrace('${executable.path} mode: ${stat.mode} ${stat.modeString()}.');
+  return stat.mode & _kExecPermissionMask != 0;
+}
+
 /// Gives execute permission to [executable] if it doesn't have it already.
 void _giveExecutePermissionIfNeeded(File executable) {
-  if (!_hasExecutePermission(executable)) {
+  if (!_hasAllExecutableFlagSet(executable)) {
     printTrace('Trying to give execute permission to ${executable.path}.');
     os.makeExecutable(executable);
   }
diff --git a/packages/flutter_tools/test/general.shard/android/gradle_utils_test.dart b/packages/flutter_tools/test/general.shard/android/gradle_utils_test.dart
index b5cdc97..d0cca2a 100644
--- a/packages/flutter_tools/test/general.shard/android/gradle_utils_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/gradle_utils_test.dart
@@ -285,6 +285,37 @@
       GradleUtils: () => gradleUtils,
     });
 
+    testUsingContext('gives execute permission to gradle even when not all permission flags are set', () {
+      final FlutterProject flutterProject = MockFlutterProject();
+      final AndroidProject androidProject = MockAndroidProject();
+      when(flutterProject.android).thenReturn(androidProject);
+
+      final FileStat gradleStat = MockFileStat();
+      when(gradleStat.mode).thenReturn(400);
+
+      final File gradlew = MockFile();
+      when(gradlew.path).thenReturn('gradlew');
+      when(gradlew.absolute).thenReturn(gradlew);
+      when(gradlew.statSync()).thenReturn(gradleStat);
+      when(gradlew.existsSync()).thenReturn(true);
+
+      final Directory androidDirectory = MockDirectory();
+      when(androidDirectory.childFile(gradlewFilename)).thenReturn(gradlew);
+      when(androidProject.hostAppGradleRoot).thenReturn(androidDirectory);
+
+      when(gradleUtils.injectGradleWrapperIfNeeded(any)).thenReturn(null);
+      when(gradleUtils.migrateToR8(any)).thenReturn(null);
+
+      GradleUtils().getExecutable(flutterProject);
+
+      verify(operatingSystemUtils.makeExecutable(gradlew)).called(1);
+    }, overrides: <Type, Generator>{
+      FileSystem: () => memoryFileSystem,
+      ProcessManager: () => FakeProcessManager.any(),
+      OperatingSystemUtils: () => operatingSystemUtils,
+      GradleUtils: () => gradleUtils,
+    });
+
     testUsingContext('doesn\'t give execute permission to gradle if not needed', () {
       final FlutterProject flutterProject = MockFlutterProject();
       final AndroidProject androidProject = MockAndroidProject();