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

Commit 68811761 authored by Pablo Gamito's avatar Pablo Gamito Committed by Android (Google) Code Review
Browse files

Merge changes from topic...

Merge changes from topic "revert-28207894-revert-28147757-no-processing-protolog-IJZXUZOQGO-UHPYLFFIMU" into main

* changes:
  Move REQUIRE_PROTOLOG check into LogcatOnlyProtoLogImpl
  Fix NPE in LegacyProtoLogImpl
  Revert^2 "Handle null object params"
  Revert "Revert "Handle potentially null strings passed as ProtoL..."
  Revert^2 "Refactor"
  Revert "Revert "Collect the stacktrace before entering the backg..."
  Revert "Revert "Ensure we wait for all messages to be traced bef..."
  Revert^2 "Update ProtoLog tests"
  Revert^2 "Remove expensive trace call in ProtoLog log call"
  Revert^2 "Use registerGroups API"
  Revert^2 "Initialize ProtoLog instances statically"
  Revert^2 "Add register groups API"
  Revert^2 "Add logcat only ProtoLog impl"
  Revert^2 "Handle null args list"
  Revert "Revert "Always remove message string argument from proce..."
  Revert "Revert "Clearly distinguish ProtoLog hash vs message int..."
  Revert "Revert "Improve performance of computing if a group is e..."
  Revert "Revert "Add support for ProtoLogging without any source ..."
parents c18cb7f0 71d6737b
Loading
Loading
Loading
Loading
+27 −13
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

@@ -65,7 +66,7 @@ public class LegacyProtoLogImpl implements IProtoLog {
    private final String mLegacyViewerConfigFilename;
    private final TraceBuffer mBuffer;
    private final LegacyProtoLogViewerConfigReader mViewerConfig;
    private final TreeMap<String, IProtoLogGroup> mLogGroups;
    private final Map<String, IProtoLogGroup> mLogGroups = new TreeMap<>();
    private final Runnable mCacheUpdater;
    private final int mPerChunkSize;

@@ -74,20 +75,19 @@ public class LegacyProtoLogImpl implements IProtoLog {
    private final Object mProtoLogEnabledLock = new Object();

    public LegacyProtoLogImpl(String outputFile, String viewerConfigFilename,
            TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
            Runnable cacheUpdater) {
        this(new File(outputFile), viewerConfigFilename, BUFFER_CAPACITY,
                new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, logGroups, cacheUpdater);
                new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, cacheUpdater);
    }

    public LegacyProtoLogImpl(File file, String viewerConfigFilename, int bufferCapacity,
            LegacyProtoLogViewerConfigReader viewerConfig, int perChunkSize,
            TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
            Runnable cacheUpdater) {
        mLogFile = file;
        mBuffer = new TraceBuffer(bufferCapacity);
        mLegacyViewerConfigFilename = viewerConfigFilename;
        mViewerConfig = viewerConfig;
        mPerChunkSize = perChunkSize;
        mLogGroups = logGroups;
        mCacheUpdater = cacheUpdater;
    }

@@ -97,21 +97,26 @@ public class LegacyProtoLogImpl implements IProtoLog {
    @VisibleForTesting
    @Override
    public void log(LogLevel level, IProtoLogGroup group, long messageHash, int paramsMask,
            @Nullable String messageString, Object[] args) {
            @Nullable Object[] args) {
        if (group.isLogToProto()) {
            logToProto(messageHash, paramsMask, args);
        }
        if (group.isLogToLogcat()) {
            logToLogcat(group.getTag(), level, messageHash, messageString, args);
            logToLogcat(group.getTag(), level, messageHash, args);
        }
    }

    @Override
    public void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object... args) {
        // This will be removed very soon so no point implementing it here.
        throw new IllegalStateException(
                "Not implemented. Only implemented for PerfettoProtoLogImpl.");
    }

    private void logToLogcat(String tag, LogLevel level, long messageHash,
            @Nullable String messageString, Object[] args) {
            @Nullable Object[] args) {
        String message = null;
        if (messageString == null) {
            messageString = mViewerConfig.getViewerString(messageHash);
        }
        final String messageString = mViewerConfig.getViewerString(messageHash);
        if (messageString != null) {
            if (args != null) {
                try {
@@ -125,9 +130,11 @@ public class LegacyProtoLogImpl implements IProtoLog {
        }
        if (message == null) {
            StringBuilder builder = new StringBuilder("UNKNOWN MESSAGE (" + messageHash + ")");
            if (args != null) {
                for (Object o : args) {
                    builder.append(" ").append(o);
                }
            }
            message = builder.toString();
        }
        passToLogcat(tag, level, message);
@@ -410,5 +417,12 @@ public class LegacyProtoLogImpl implements IProtoLog {
        // so we ignore the level argument to this function.
        return group.isLogToLogcat() || (group.isLogToProto() && isProtoEnabled());
    }

    @Override
    public void registerGroups(IProtoLogGroup... protoLogGroups) {
        for (IProtoLogGroup group : protoLogGroups) {
            mLogGroups.put(group.name(), group);
        }
    }
}
+87 −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 static com.android.internal.protolog.ProtoLog.REQUIRE_PROTOLOGTOOL;

import android.text.TextUtils;
import android.util.Log;

import com.android.internal.protolog.common.ILogger;
import com.android.internal.protolog.common.IProtoLog;
import com.android.internal.protolog.common.IProtoLogGroup;
import com.android.internal.protolog.common.LogLevel;

/**
 * Class only create and used to server temporarily for when there is source code pre-processing by
 * the ProtoLog tool, when the tracing to Perfetto flag is off, and the static REQUIRE_PROTOLOGTOOL
 * boolean is false. In which case we simply want to log protolog message to logcat. Note, that this
 * means that in such cases there is no real advantage of using protolog over logcat.
 *
 * @deprecated Should not be used. This is just a temporary class to support a legacy behavior.
 */
@Deprecated
public class LogcatOnlyProtoLogImpl implements IProtoLog {
    @Override
    public void log(LogLevel logLevel, IProtoLogGroup group, long messageHash, int paramsMask,
            Object[] args) {
        throw new RuntimeException("Not supported when using LogcatOnlyProtoLogImpl");
    }

    @Override
    public void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object[] args) {
        if (REQUIRE_PROTOLOGTOOL) {
            throw new RuntimeException(
                    "REQUIRE_PROTOLOGTOOL not set to false before the first log call.");
        }

        String formattedString = TextUtils.formatSimple(messageString, args);
        switch (logLevel) {
            case VERBOSE -> Log.v(group.getTag(), formattedString);
            case INFO -> Log.i(group.getTag(), formattedString);
            case DEBUG -> Log.d(group.getTag(), formattedString);
            case WARN -> Log.w(group.getTag(), formattedString);
            case ERROR -> Log.e(group.getTag(), formattedString);
            case WTF -> Log.wtf(group.getTag(), formattedString);
        }
    }

    @Override
    public boolean isProtoEnabled() {
        return false;
    }

    @Override
    public int startLoggingToLogcat(String[] groups, ILogger logger) {
        return 0;
    }

    @Override
    public int stopLoggingToLogcat(String[] groups, ILogger logger) {
        return 0;
    }

    @Override
    public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
        return true;
    }

    @Override
    public void registerGroups(IProtoLogGroup... protoLogGroups) {
        // Does nothing
    }
}
+304 −105

File changed.

Preview size limit exceeded, changes collapsed.

+58 −39
Original line number Diff line number Diff line
@@ -44,21 +44,23 @@ public class ProtoLog {
// LINT.ThenChange(frameworks/base/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt)

    // Needs to be set directly otherwise the protologtool tries to transform the method call
    @Deprecated
    public static boolean REQUIRE_PROTOLOGTOOL = true;

    private static IProtoLog sProtoLogInstance;

    /**
     * DEBUG level log.
     *
     * @param group         {@code IProtoLogGroup} controlling this log call.
     * @param messageString constant format string for the logged message.
     * @param args          parameters to be used with the format string.
     *
     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
     *       executed. Check generated code for actual call.
     */
    public static void d(IProtoLogGroup group, String messageString, Object... args) {
        // Stub, replaced by the ProtoLogTool.
        if (REQUIRE_PROTOLOGTOOL) {
            throw new UnsupportedOperationException(
                    "ProtoLog calls MUST be processed with ProtoLogTool");
        }
        logStringMessage(LogLevel.DEBUG, group, messageString, args);
    }

    /**
@@ -67,13 +69,12 @@ public class ProtoLog {
     * @param group         {@code IProtoLogGroup} controlling this log call.
     * @param messageString constant format string for the logged message.
     * @param args          parameters to be used with the format string.
     *
     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
     *       executed. Check generated code for actual call.
     */
    public static void v(IProtoLogGroup group, String messageString, Object... args) {
        // Stub, replaced by the ProtoLogTool.
        if (REQUIRE_PROTOLOGTOOL) {
            throw new UnsupportedOperationException(
                    "ProtoLog calls MUST be processed with ProtoLogTool");
        }
        logStringMessage(LogLevel.VERBOSE, group, messageString, args);
    }

    /**
@@ -82,13 +83,12 @@ public class ProtoLog {
     * @param group         {@code IProtoLogGroup} controlling this log call.
     * @param messageString constant format string for the logged message.
     * @param args          parameters to be used with the format string.
     *
     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
     *       executed. Check generated code for actual call.
     */
    public static void i(IProtoLogGroup group, String messageString, Object... args) {
        // Stub, replaced by the ProtoLogTool.
        if (REQUIRE_PROTOLOGTOOL) {
            throw new UnsupportedOperationException(
                    "ProtoLog calls MUST be processed with ProtoLogTool");
        }
        logStringMessage(LogLevel.INFO, group, messageString, args);
    }

    /**
@@ -97,13 +97,12 @@ public class ProtoLog {
     * @param group         {@code IProtoLogGroup} controlling this log call.
     * @param messageString constant format string for the logged message.
     * @param args          parameters to be used with the format string.
     *
     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
     *       executed. Check generated code for actual call.
     */
    public static void w(IProtoLogGroup group, String messageString, Object... args) {
        // Stub, replaced by the ProtoLogTool.
        if (REQUIRE_PROTOLOGTOOL) {
            throw new UnsupportedOperationException(
                    "ProtoLog calls MUST be processed with ProtoLogTool");
        }
        logStringMessage(LogLevel.WARN, group, messageString, args);
    }

    /**
@@ -112,13 +111,12 @@ public class ProtoLog {
     * @param group         {@code IProtoLogGroup} controlling this log call.
     * @param messageString constant format string for the logged message.
     * @param args          parameters to be used with the format string.
     *
     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
     *       executed. Check generated code for actual call.
     */
    public static void e(IProtoLogGroup group, String messageString, Object... args) {
        // Stub, replaced by the ProtoLogTool.
        if (REQUIRE_PROTOLOGTOOL) {
            throw new UnsupportedOperationException(
                    "ProtoLog calls MUST be processed with ProtoLogTool");
        }
        logStringMessage(LogLevel.ERROR, group, messageString, args);
    }

    /**
@@ -127,13 +125,12 @@ public class ProtoLog {
     * @param group         {@code IProtoLogGroup} controlling this log call.
     * @param messageString constant format string for the logged message.
     * @param args          parameters to be used with the format string.
     *
     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
     *       executed. Check generated code for actual call.
     */
    public static void wtf(IProtoLogGroup group, String messageString, Object... args) {
        // Stub, replaced by the ProtoLogTool.
        if (REQUIRE_PROTOLOGTOOL) {
            throw new UnsupportedOperationException(
                    "ProtoLog calls MUST be processed with ProtoLogTool");
        }
        logStringMessage(LogLevel.WTF, group, messageString, args);
    }

    /**
@@ -142,11 +139,7 @@ public class ProtoLog {
     * @return true iff this is being logged.
     */
    public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
        if (REQUIRE_PROTOLOGTOOL) {
            throw new UnsupportedOperationException(
                    "ProtoLog calls MUST be processed with ProtoLogTool");
        }
        return false;
        return sProtoLogInstance.isEnabled(group, level);
    }

    /**
@@ -154,10 +147,36 @@ public class ProtoLog {
     * @return A singleton instance of ProtoLog.
     */
    public static IProtoLog getSingleInstance() {
        if (REQUIRE_PROTOLOGTOOL) {
            throw new UnsupportedOperationException(
                    "ProtoLog calls MUST be processed with ProtoLogTool");
        return sProtoLogInstance;
    }

    /**
     * Registers available protolog groups. A group must be registered before it can be used.
     * @param protoLogGroups The groups to register for use in protolog.
     */
    public static void registerGroups(IProtoLogGroup... protoLogGroups) {
        sProtoLogInstance.registerGroups(protoLogGroups);
    }

    private static void logStringMessage(LogLevel logLevel, IProtoLogGroup group,
            String stringMessage, Object... args) {
        if (sProtoLogInstance == null) {
            throw new IllegalStateException(
                    "Trying to use ProtoLog before it is initialized in this process.");
        }

        if (sProtoLogInstance.isEnabled(group, logLevel)) {
            sProtoLogInstance.log(logLevel, group, stringMessage, args);
        }
    }

    static {
        if (android.tracing.Flags.perfettoProtologTracing()) {
            sProtoLogInstance = new PerfettoProtoLogImpl();
        } else {
            // The first call to ProtoLog is likely to flip REQUIRE_PROTOLOGTOOL, which is when this
            // static block will be executed before REQUIRE_PROTOLOGTOOL is actually set.
            sProtoLogInstance = new LogcatOnlyProtoLogImpl();
        }
        return null;
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.internal.protolog.common.LogLevel;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
@@ -138,6 +139,8 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
    }

    public static class IncrementalState {
        public final Set<Integer> protologGroupInterningSet = new HashSet<>();
        public final Set<Long> protologMessageInterningSet = new HashSet<>();
        public final Map<String, Integer> argumentInterningMap = new HashMap<>();
        public final Map<String, Integer> stacktraceInterningMap = new HashMap<>();
        public boolean clearReported = false;
Loading