Improve the intergrity checking for "gradle wrapper". (#26069)

diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart
index a0c268f..a8b0cb4 100644
--- a/packages/flutter_tools/lib/src/cache.dart
+++ b/packages/flutter_tools/lib/src/cache.dart
@@ -576,6 +576,10 @@
 class GradleWrapper extends CachedArtifact {
   GradleWrapper(Cache cache): super('gradle_wrapper', cache);
 
+  List<String> get _gradleScripts => <String>['gradlew', 'gradlew.bat'];
+
+  String get _gradleWrapper => fs.path.join('gradle', 'wrapper', 'gradle-wrapper.jar');
+
   @override
   Future<void> updateInner() {
     final Uri archiveUri = _toStorageUri(version);
@@ -586,6 +590,22 @@
       fs.file(fs.path.join(location.path, 'NOTICE')).deleteSync();
     });
   }
+
+  @override
+  bool isUpToDateInner() {
+    final Directory wrapperDir = cache.getCacheDir(fs.path.join('artifacts', 'gradle_wrapper'));
+    if (!fs.directory(wrapperDir).existsSync())
+      return false;
+    for (String scriptName in _gradleScripts) {
+      final File scriptFile = fs.file(fs.path.join(wrapperDir.path, scriptName));
+      if (!scriptFile.existsSync())
+        return false;
+    }
+    final File gradleWrapperJar = fs.file(fs.path.join(wrapperDir.path, _gradleWrapper));
+    if (!gradleWrapperJar.existsSync())
+      return false;
+    return true;
+  }
 }
 
 // Many characters are problematic in filenames, especially on Windows.
diff --git a/packages/flutter_tools/test/cache_test.dart b/packages/flutter_tools/test/cache_test.dart
index 36bf2ce..03912cb 100644
--- a/packages/flutter_tools/test/cache_test.dart
+++ b/packages/flutter_tools/test/cache_test.dart
@@ -51,6 +51,36 @@
   });
 
   group('Cache', () {
+    final MockCache mockCache = MockCache();
+    final MemoryFileSystem fs = MemoryFileSystem();
+
+    testUsingContext('Gradle wrapper should not be up to date, if some cached artifact is not available', () {
+      final GradleWrapper gradleWrapper = GradleWrapper(mockCache);
+      final Directory directory = fs.directory('/Applications/flutter/bin/cache');
+      directory.createSync(recursive: true);
+      fs.file(fs.path.join(directory.path, 'artifacts', 'gradle_wrapper', 'gradle', 'wrapper', 'gradle-wrapper.jar')).createSync(recursive: true);
+      when(mockCache.getCacheDir(fs.path.join('artifacts', 'gradle_wrapper'))).thenReturn(fs.directory(fs.path.join(directory.path, 'artifacts', 'gradle_wrapper')));
+      expect(gradleWrapper.isUpToDateInner(), false);
+    }, overrides: <Type, Generator>{
+      Cache: ()=> mockCache,
+      FileSystem: () => fs
+    });
+
+    testUsingContext('Gradle wrapper should be up to date, only if all cached artifact are available', () {
+      final GradleWrapper gradleWrapper = GradleWrapper(mockCache);
+      final Directory directory = fs.directory('/Applications/flutter/bin/cache');
+      directory.createSync(recursive: true);
+      fs.file(fs.path.join(directory.path, 'artifacts', 'gradle_wrapper', 'gradle', 'wrapper', 'gradle-wrapper.jar')).createSync(recursive: true);
+      fs.file(fs.path.join(directory.path, 'artifacts', 'gradle_wrapper', 'gradlew')).createSync(recursive: true);
+      fs.file(fs.path.join(directory.path, 'artifacts', 'gradle_wrapper', 'gradlew.bat')).createSync(recursive: true);
+
+      when(mockCache.getCacheDir(fs.path.join('artifacts', 'gradle_wrapper'))).thenReturn(fs.directory(fs.path.join(directory.path, 'artifacts', 'gradle_wrapper')));
+      expect(gradleWrapper.isUpToDateInner(), true);
+    }, overrides: <Type, Generator>{
+      Cache: ()=> mockCache,
+      FileSystem: () => fs
+    });
+
     test('should not be up to date, if some cached artifact is not', () {
       final CachedArtifact artifact1 = MockCachedArtifact();
       final CachedArtifact artifact2 = MockCachedArtifact();
@@ -132,3 +162,4 @@
 class MockRandomAccessFile extends Mock implements RandomAccessFile {}
 class MockCachedArtifact extends Mock implements CachedArtifact {}
 class MockInternetAddress extends Mock implements InternetAddress {}
+class MockCache extends Mock implements Cache {}
\ No newline at end of file