From ec5130d3f80fc618778ff03d33236c8c0eafdb19 Mon Sep 17 00:00:00 2001 From: Wen Zhang Date: Mon, 24 Jul 2023 21:23:02 +0800 Subject: [Bugfix]use walkFileTree to calucate apk size When using foreach on the stream of Files.walk, the FileTreeIterator may generate an UncheckedIOException, which can cause a system crash. Bug:292486804 Test: manual 1.statsd_testdrive 524 2.adb install any apk 3.observe apks_size_bytes Change-Id: I0e223fc61184a51a4f5a71df54ba50137376df8e Change-Id: I18852ced54ceeb63785033de3f1ab22a35ba1fc1 --- .../java/com/android/server/pm/PackageMetrics.java | 29 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java index 80d6ebbd90b3..2d58fe5a1678 100644 --- a/services/core/java/com/android/server/pm/PackageMetrics.java +++ b/services/core/java/com/android/server/pm/PackageMetrics.java @@ -34,11 +34,13 @@ import java.io.File; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicLong; -import java.util.stream.Stream; /** * Metrics class for reporting stats to logging infrastructures like statsd @@ -155,10 +157,27 @@ final class PackageMetrics { private long getApksSize(File apkDir) { // TODO(b/249294752): also count apk sizes for failed installs final AtomicLong apksSize = new AtomicLong(); - try (Stream walkStream = Files.walk(apkDir.toPath())) { - walkStream.filter(p -> p.toFile().isFile() - && ApkLiteParseUtils.isApkFile(p.toFile())).forEach( - f -> apksSize.addAndGet(f.toFile().length())); + try { + Files.walkFileTree(apkDir.toPath(), new SimpleFileVisitor<>() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) + throws IOException { + if (dir.equals(apkDir.toPath())) { + return FileVisitResult.CONTINUE; + } else { + return FileVisitResult.SKIP_SUBTREE; + } + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + if (file.toFile().isFile() && ApkLiteParseUtils.isApkFile(file.toFile())) { + apksSize.addAndGet(file.toFile().length()); + } + return FileVisitResult.CONTINUE; + } + }); } catch (IOException e) { // ignore } -- cgit v1.2.3-59-g8ed1b