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

Commit 7d4d88d6 authored by Jernej Virag's avatar Jernej Virag
Browse files

Allow LogBuffers to be cleared

Especially for memory tests (which run ~100 iterations without restart of SysUI), it would be great to be able to flush the LogBuffers - right now the size of logbuffers increases through iterations which ends up as false positive leaks.
This CL adds an ADB command to clear the log buffers to be executed by the test runner for performance tests.

Bug: 437098294
Flag: EXEMPT logging only
Test: built SysUI, ran tests
Change-Id: I3097883b52b74dcd33dabd7ad0e81d023348e7ab
parent 0c169477
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -95,6 +95,12 @@ class RingBuffer<T>(private val maxSize: Int, private val factory: () -> T) : It
        return buffer[indexOf(start + index)]!!
    }

    /** Clears contents of the buffer. */
    fun clear() {
        omega = 0
        buffer.fill(null)
    }

    override fun iterator(): Iterator<T> {
        return object : Iterator<T> {
            private var position: Int = 0
+6 −0
Original line number Diff line number Diff line
@@ -244,6 +244,12 @@ constructor(
        }
    }

    /** Clears the data from this buffer and frees its memory. */
    @Synchronized
    fun clear() {
        buffer.clear()
    }

    private fun echoToSystrace(level: LogLevel, tag: String, strMessage: String) {
        if (!Trace.isEnabled()) return
        Trace.instantForTrack(
+8 −0
Original line number Diff line number Diff line
@@ -159,6 +159,14 @@ open class DumpManager @Inject constructor() {
        }
    }

    /** Clears contents of all log buffers. */
    @Synchronized
    fun clearBuffers() {
        for (buffer in buffers.values) {
            buffer.buffer.clear()
        }
    }

    private fun canAssignToNameLocked(name: String, newDumpable: Any): Boolean {
        val existingDumpable =
            dumpables[name]?.dumpable ?: buffers[name]?.buffer ?: tableLogBuffers[name]?.table
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.systemui.log

import android.util.Log
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import java.io.PrintWriter
import javax.inject.Inject

/**
 * Used to clear all LogBuffers in SystemUI. Useful for testing where we want to reset SysUI state
 * and memory use without restarting it.
 */
@SysUISingleton
class ClearLogBuffersCommand
@Inject
constructor(private val dumpManager: DumpManager, private val commandRegistry: CommandRegistry) :
    Command, CoreStartable {

    override fun start() {
        commandRegistry.registerCommand("clear-log-buffers") { this }
    }

    override fun execute(pw: PrintWriter, args: List<String>) {
        Log.i("ClearLogBuffers", "Clearing all LogBuffers")
        dumpManager.clearBuffers()
    }

    override fun help(pw: PrintWriter) {
        pw.print("Clears all LogBuffers in SystemUI")
        pw.println()
    }
}
+14 −1
Original line number Diff line number Diff line
@@ -18,9 +18,11 @@ package com.android.systemui.log.dagger;

import android.os.Build;

import com.android.systemui.CoreStartable;
import com.android.systemui.common.data.repository.PackageChangeRepository;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.deviceentry.data.repository.DeviceEntryFaceAuthRepositoryImpl;
import com.android.systemui.log.ClearLogBuffersCommand;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.LogBufferFactory;
import com.android.systemui.log.LogcatEchoTracker;
@@ -34,9 +36,12 @@ import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository;
import com.android.systemui.qs.pipeline.shared.TileSpec;
import com.android.systemui.util.wakelock.WakeLockLog;

import dagger.Binds;
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;

import java.util.HashMap;
import java.util.Map;
@@ -45,7 +50,7 @@ import java.util.Map;
 * Dagger module for providing instances of {@link LogBuffer}.
 */
@Module
public class LogModule {
public abstract class LogModule {
    /** Provides a logging buffer for doze-related logs. */
    @Provides
    @SysUISingleton
@@ -664,4 +669,12 @@ public class LogModule {
    public static LogBuffer providesRearDisplayLog(LogBufferFactory factory) {
        return factory.create("RearDisplayLog", 50);
    }

    /**
     * Registers the clear log buffers ADB command.
     */
    @Binds
    @IntoMap
    @ClassKey(ClearLogBuffersCommand.class)
    public abstract CoreStartable bindsClearLogBuffersCommand(ClearLogBuffersCommand command);
}