Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ef32e9b authored by Pablo Gamito's avatar Pablo Gamito
Browse files

Wrap ProtoInputStream in autoclosable class

This is to ensure that we always properly close the input file we are using to read the proto data from.

Bug: 348142756
Flag: EXEMPT minor refactor
Test: atest TracingTests
Change-Id: I6a247b3bbbd0b9e97cc726a67a16a78cfd853385
parent e67c19f3
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.protolog;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.proto.ProtoInputStream;

import java.io.FileInputStream;
import java.io.IOException;

public final class AutoClosableProtoInputStream implements AutoCloseable {
    @NonNull
    private final ProtoInputStream mProtoInputStream;
    @Nullable
    private final FileInputStream mFileInputStream;

    public AutoClosableProtoInputStream(@NonNull FileInputStream fileInputStream) {
        mProtoInputStream = new ProtoInputStream(fileInputStream);
        mFileInputStream = fileInputStream;
    }

    public AutoClosableProtoInputStream(@NonNull byte[] input) {
        mProtoInputStream = new ProtoInputStream(input);
        mFileInputStream = null;
    }

    /**
     * @return the ProtoInputStream this class is wrapping
     */
    @NonNull
    public ProtoInputStream get() {
        return mProtoInputStream;
    }

    @Override
    public void close() throws IOException {
        if (mFileInputStream != null) {
            mFileInputStream.close();
        }
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.ServiceManager;
import android.util.Log;
import android.util.proto.ProtoInputStream;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLogConfigurationServiceImpl.RegisterClientArgs;
@@ -47,11 +46,13 @@ public class ProcessedPerfettoProtoLogImpl extends PerfettoProtoLogImpl {
            @NonNull Runnable cacheUpdater,
            @NonNull IProtoLogGroup[] groups) throws ServiceManager.ServiceNotFoundException {
        this(viewerConfigFilePath, new ViewerConfigInputStreamProvider() {
                    @androidx.annotation.NonNull
                    @NonNull
                    @Override
                    public ProtoInputStream getInputStream() {
                    public AutoClosableProtoInputStream getInputStream() {
                        try {
                            return new ProtoInputStream(new FileInputStream(viewerConfigFilePath));
                            final var protoFileInputStream =
                                    new FileInputStream(viewerConfigFilePath);
                            return new AutoClosableProtoInputStream(protoFileInputStream);
                        } catch (FileNotFoundException e) {
                            throw new RuntimeException(
                                    "Failed to load viewer config file " + viewerConfigFilePath, e);
+1 −1
Original line number Diff line number Diff line
@@ -379,7 +379,7 @@ public class ProtoLogConfigurationServiceImpl extends IProtoLogConfigurationServ
            @NonNull String viewerConfigFilePath) {
        Utils.dumpViewerConfig(dataSource, () -> {
            try {
                return new ProtoInputStream(new FileInputStream(viewerConfigFilePath));
                return new AutoClosableProtoInputStream(new FileInputStream(viewerConfigFilePath));
            } catch (FileNotFoundException e) {
                throw new RuntimeException(
                        "Failed to load viewer config file " + viewerConfigFilePath, e);
+58 −55
Original line number Diff line number Diff line
@@ -106,8 +106,8 @@ public class ProtoLogViewerConfigReader {
        long targetGroupId = loadGroupId(group);

        final Map<Long, String> hashesForGroup = new TreeMap<>();
        final ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream();

        try (var pisWrapper = mViewerConfigInputStreamProvider.getInputStream()) {
            final var pis = pisWrapper.get();
            while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
                if (pis.getFieldNumber() == (int) MESSAGES) {
                    final long inMessageToken = pis.start(MESSAGES);
@@ -148,12 +148,14 @@ public class ProtoLogViewerConfigReader {
                    pis.end(inMessageToken);
                }
            }
        }

        return hashesForGroup;
    }

    private long loadGroupId(@NonNull String group) throws IOException {
        final ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream();
        try (var pisWrapper = mViewerConfigInputStreamProvider.getInputStream()) {
            final var pis = pisWrapper.get();

            while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
                if (pis.getFieldNumber() == (int) GROUPS) {
@@ -179,6 +181,7 @@ public class ProtoLogViewerConfigReader {
                    pis.end(inMessageToken);
                }
            }
        }

        throw new RuntimeException("Group " + group + " not found in viewer config");
    }
+2 −2
Original line number Diff line number Diff line
@@ -48,8 +48,8 @@ public class Utils {
    public static void dumpViewerConfig(@NonNull ProtoLogDataSource dataSource,
            @NonNull ViewerConfigInputStreamProvider viewerConfigInputStreamProvider) {
        dataSource.trace(ctx -> {
            try {
                ProtoInputStream pis = viewerConfigInputStreamProvider.getInputStream();
            try (var pisWrapper = viewerConfigInputStreamProvider.getInputStream()) {
                final var pis = pisWrapper.get();

                final ProtoOutputStream os = ctx.newTracePacket();

Loading