summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/protolog/LegacyProtoLogImpl.java19
-rw-r--r--core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java104
-rw-r--r--core/java/com/android/internal/protolog/ProtoLogDataSource.java31
-rw-r--r--core/java/com/android/internal/protolog/ProtoLogImpl.java20
-rw-r--r--core/java/com/android/internal/protolog/common/IProtoLog.java8
-rw-r--r--core/java/com/android/internal/protolog/common/IProtoLogGroup.java2
-rw-r--r--core/java/com/android/internal/protolog/common/ProtoLog.java2
-rw-r--r--core/java/com/android/internal/protolog/common/ProtoLogToolInjected.java6
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java6
-rw-r--r--services/core/java/com/android/server/wm/RemoteAnimationController.java3
-rw-r--r--services/core/java/com/android/server/wm/SurfaceAnimator.java3
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java1
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java3
-rw-r--r--tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java2
-rw-r--r--tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java4
-rw-r--r--tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java147
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt72
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt16
-rw-r--r--tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt14
21 files changed, 413 insertions, 56 deletions
diff --git a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
index 2096ba42080f..d24487412313 100644
--- a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
@@ -66,6 +66,7 @@ public class LegacyProtoLogImpl implements IProtoLog {
private final TraceBuffer mBuffer;
private final LegacyProtoLogViewerConfigReader mViewerConfig;
private final TreeMap<String, IProtoLogGroup> mLogGroups;
+ private final Runnable mCacheUpdater;
private final int mPerChunkSize;
private boolean mProtoLogEnabled;
@@ -73,20 +74,21 @@ public class LegacyProtoLogImpl implements IProtoLog {
private final Object mProtoLogEnabledLock = new Object();
public LegacyProtoLogImpl(String outputFile, String viewerConfigFilename,
- TreeMap<String, IProtoLogGroup> logGroups) {
+ TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
this(new File(outputFile), viewerConfigFilename, BUFFER_CAPACITY,
- new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, logGroups);
+ new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, logGroups, cacheUpdater);
}
public LegacyProtoLogImpl(File file, String viewerConfigFilename, int bufferCapacity,
LegacyProtoLogViewerConfigReader viewerConfig, int perChunkSize,
- TreeMap<String, IProtoLogGroup> logGroups) {
+ TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
mLogFile = file;
mBuffer = new TraceBuffer(bufferCapacity);
mLegacyViewerConfigFilename = viewerConfigFilename;
mViewerConfig = viewerConfig;
mPerChunkSize = perChunkSize;
- this.mLogGroups = logGroups;
+ mLogGroups = logGroups;
+ mCacheUpdater = cacheUpdater;
}
/**
@@ -285,6 +287,8 @@ public class LegacyProtoLogImpl implements IProtoLog {
return -1;
}
}
+
+ mCacheUpdater.run();
return 0;
}
@@ -399,5 +403,12 @@ public class LegacyProtoLogImpl implements IProtoLog {
public int stopLoggingToLogcat(String[] groups, ILogger logger) {
return setLogging(true /* setTextLogging */, false, logger, groups);
}
+
+ @Override
+ public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+ // In legacy logging we just enable an entire group at a time without more granular control,
+ // so we ignore the level argument to this function.
+ return group.isLogToLogcat() || (group.isLogToProto() && isProtoEnabled());
+ }
}
diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
index 561ca2178966..9f3ce8163bf3 100644
--- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
@@ -52,6 +52,7 @@ import android.tracing.perfetto.DataSourceParams;
import android.tracing.perfetto.InitArguments;
import android.tracing.perfetto.Producer;
import android.tracing.perfetto.TracingContext;
+import android.util.ArrayMap;
import android.util.LongArray;
import android.util.Slog;
import android.util.proto.ProtoInputStream;
@@ -70,6 +71,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Map;
+import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -83,18 +85,22 @@ public class PerfettoProtoLogImpl implements IProtoLog {
private final AtomicInteger mTracingInstances = new AtomicInteger();
private final ProtoLogDataSource mDataSource = new ProtoLogDataSource(
- this.mTracingInstances::incrementAndGet,
+ this::onTracingInstanceStart,
this::dumpTransitionTraceConfig,
- this.mTracingInstances::decrementAndGet
+ this::onTracingInstanceStop
);
private final ProtoLogViewerConfigReader mViewerConfigReader;
private final ViewerConfigInputStreamProvider mViewerConfigInputStreamProvider;
private final TreeMap<String, IProtoLogGroup> mLogGroups;
+ private final Runnable mCacheUpdater;
+
+ private final Map<LogLevel, Integer> mDefaultLogLevelCounts = new ArrayMap<>();
+ private final Map<IProtoLogGroup, Map<LogLevel, Integer>> mLogLevelCounts = new ArrayMap<>();
private final ExecutorService mBackgroundLoggingService = Executors.newCachedThreadPool();
public PerfettoProtoLogImpl(String viewerConfigFilePath,
- TreeMap<String, IProtoLogGroup> logGroups) {
+ TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
this(() -> {
try {
return new ProtoInputStream(new FileInputStream(viewerConfigFilePath));
@@ -102,28 +108,32 @@ public class PerfettoProtoLogImpl implements IProtoLog {
Slog.w(LOG_TAG, "Failed to load viewer config file " + viewerConfigFilePath, e);
return null;
}
- }, logGroups);
+ }, logGroups, cacheUpdater);
}
public PerfettoProtoLogImpl(
ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
- TreeMap<String, IProtoLogGroup> logGroups
+ TreeMap<String, IProtoLogGroup> logGroups,
+ Runnable cacheUpdater
) {
this(viewerConfigInputStreamProvider,
- new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider), logGroups);
+ new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider), logGroups,
+ cacheUpdater);
}
@VisibleForTesting
public PerfettoProtoLogImpl(
ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
ProtoLogViewerConfigReader viewerConfigReader,
- TreeMap<String, IProtoLogGroup> logGroups
+ TreeMap<String, IProtoLogGroup> logGroups,
+ Runnable cacheUpdater
) {
Producer.init(InitArguments.DEFAULTS);
mDataSource.register(DataSourceParams.DEFAULTS);
this.mViewerConfigInputStreamProvider = viewerConfigInputStreamProvider;
this.mViewerConfigReader = viewerConfigReader;
this.mLogGroups = logGroups;
+ this.mCacheUpdater = cacheUpdater;
}
/**
@@ -494,6 +504,29 @@ public class PerfettoProtoLogImpl implements IProtoLog {
return setTextLogging(false, logger, groups);
}
+ @Override
+ public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+ return group.isLogToLogcat() || getLogFromLevel(group).ordinal() <= level.ordinal();
+ }
+
+ private LogLevel getLogFromLevel(IProtoLogGroup group) {
+ if (mLogLevelCounts.containsKey(group)) {
+ for (LogLevel logLevel : LogLevel.values()) {
+ if (mLogLevelCounts.get(group).getOrDefault(logLevel, 0) > 0) {
+ return logLevel;
+ }
+ }
+ } else {
+ for (LogLevel logLevel : LogLevel.values()) {
+ if (mDefaultLogLevelCounts.getOrDefault(logLevel, 0) > 0) {
+ return logLevel;
+ }
+ }
+ }
+
+ return LogLevel.WTF;
+ }
+
/**
* Start logging the stack trace of the when the log message happened for target groups
* @return status code
@@ -521,6 +554,8 @@ public class PerfettoProtoLogImpl implements IProtoLog {
return -1;
}
}
+
+ mCacheUpdater.run();
return 0;
}
@@ -567,6 +602,61 @@ public class PerfettoProtoLogImpl implements IProtoLog {
return -1;
}
+ private synchronized void onTracingInstanceStart(ProtoLogDataSource.ProtoLogConfig config) {
+ this.mTracingInstances.incrementAndGet();
+
+ final LogLevel defaultLogFrom = config.getDefaultGroupConfig().logFrom;
+ mDefaultLogLevelCounts.put(defaultLogFrom,
+ mDefaultLogLevelCounts.getOrDefault(defaultLogFrom, 0) + 1);
+
+ final Set<String> overriddenGroupTags = config.getGroupTagsWithOverriddenConfigs();
+
+ for (String overriddenGroupTag : overriddenGroupTags) {
+ IProtoLogGroup group = mLogGroups.get(overriddenGroupTag);
+
+ mLogLevelCounts.putIfAbsent(group, new ArrayMap<>());
+ final Map<LogLevel, Integer> logLevelsCountsForGroup = mLogLevelCounts.get(group);
+
+ final LogLevel logFromLevel = config.getConfigFor(overriddenGroupTag).logFrom;
+ logLevelsCountsForGroup.put(logFromLevel,
+ logLevelsCountsForGroup.getOrDefault(logFromLevel, 0) + 1);
+ }
+
+ mCacheUpdater.run();
+ }
+
+ private synchronized void onTracingInstanceStop(ProtoLogDataSource.ProtoLogConfig config) {
+ this.mTracingInstances.decrementAndGet();
+
+ final LogLevel defaultLogFrom = config.getDefaultGroupConfig().logFrom;
+ mDefaultLogLevelCounts.put(defaultLogFrom,
+ mDefaultLogLevelCounts.get(defaultLogFrom) - 1);
+ if (mDefaultLogLevelCounts.get(defaultLogFrom) <= 0) {
+ mDefaultLogLevelCounts.remove(defaultLogFrom);
+ }
+
+ final Set<String> overriddenGroupTags = config.getGroupTagsWithOverriddenConfigs();
+
+ for (String overriddenGroupTag : overriddenGroupTags) {
+ IProtoLogGroup group = mLogGroups.get(overriddenGroupTag);
+
+ mLogLevelCounts.putIfAbsent(group, new ArrayMap<>());
+ final Map<LogLevel, Integer> logLevelsCountsForGroup = mLogLevelCounts.get(group);
+
+ final LogLevel logFromLevel = config.getConfigFor(overriddenGroupTag).logFrom;
+ logLevelsCountsForGroup.put(logFromLevel,
+ logLevelsCountsForGroup.get(logFromLevel) - 1);
+ if (logLevelsCountsForGroup.get(logFromLevel) <= 0) {
+ logLevelsCountsForGroup.remove(logFromLevel);
+ }
+ if (logLevelsCountsForGroup.isEmpty()) {
+ mLogLevelCounts.remove(group);
+ }
+ }
+
+ mCacheUpdater.run();
+ }
+
static void logAndPrintln(@Nullable PrintWriter pw, String msg) {
Slog.i(LOG_TAG, msg);
if (pw != null) {
diff --git a/core/java/com/android/internal/protolog/ProtoLogDataSource.java b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
index a2d5e70ee412..e79bf36343db 100644
--- a/core/java/com/android/internal/protolog/ProtoLogDataSource.java
+++ b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
@@ -39,16 +39,19 @@ import com.android.internal.protolog.common.LogLevel;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
ProtoLogDataSource.TlsState,
ProtoLogDataSource.IncrementalState> {
- private final Runnable mOnStart;
+ private final Consumer<ProtoLogConfig> mOnStart;
private final Runnable mOnFlush;
- private final Runnable mOnStop;
+ private final Consumer<ProtoLogConfig> mOnStop;
- public ProtoLogDataSource(Runnable onStart, Runnable onFlush, Runnable onStop) {
+ public ProtoLogDataSource(Consumer<ProtoLogConfig> onStart, Runnable onFlush,
+ Consumer<ProtoLogConfig> onStop) {
super("android.protolog");
this.mOnStart = onStart;
this.mOnFlush = onFlush;
@@ -138,7 +141,7 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
public boolean clearReported = false;
}
- private static class ProtoLogConfig {
+ public static class ProtoLogConfig {
private final LogLevel mDefaultLogFromLevel;
private final Map<String, GroupConfig> mGroupConfigs;
@@ -151,13 +154,17 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
this.mGroupConfigs = groupConfigs;
}
- private GroupConfig getConfigFor(String groupTag) {
+ public GroupConfig getConfigFor(String groupTag) {
return mGroupConfigs.getOrDefault(groupTag, getDefaultGroupConfig());
}
- private GroupConfig getDefaultGroupConfig() {
+ public GroupConfig getDefaultGroupConfig() {
return new GroupConfig(mDefaultLogFromLevel, false);
}
+
+ public Set<String> getGroupTagsWithOverriddenConfigs() {
+ return mGroupConfigs.keySet();
+ }
}
public static class GroupConfig {
@@ -255,18 +262,18 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
public static class Instance extends DataSourceInstance {
- private final Runnable mOnStart;
+ private final Consumer<ProtoLogConfig> mOnStart;
private final Runnable mOnFlush;
- private final Runnable mOnStop;
+ private final Consumer<ProtoLogConfig> mOnStop;
private final ProtoLogConfig mConfig;
public Instance(
DataSource<Instance, TlsState, IncrementalState> dataSource,
int instanceIdx,
ProtoLogConfig config,
- Runnable onStart,
+ Consumer<ProtoLogConfig> onStart,
Runnable onFlush,
- Runnable onStop
+ Consumer<ProtoLogConfig> onStop
) {
super(dataSource, instanceIdx);
this.mOnStart = onStart;
@@ -277,7 +284,7 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
@Override
public void onStart(StartCallbackArguments args) {
- this.mOnStart.run();
+ this.mOnStart.accept(this.mConfig);
}
@Override
@@ -287,7 +294,7 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
@Override
public void onStop(StopCallbackArguments args) {
- this.mOnStop.run();
+ this.mOnStop.accept(this.mConfig);
}
}
}
diff --git a/core/java/com/android/internal/protolog/ProtoLogImpl.java b/core/java/com/android/internal/protolog/ProtoLogImpl.java
index 487ae8145546..6d142afce626 100644
--- a/core/java/com/android/internal/protolog/ProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogImpl.java
@@ -16,6 +16,7 @@
package com.android.internal.protolog;
+import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.CACHE_UPDATER;
import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.LEGACY_OUTPUT_FILE_PATH;
import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.LEGACY_VIEWER_CONFIG_PATH;
import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.LOG_GROUPS;
@@ -49,6 +50,9 @@ public class ProtoLogImpl {
@ProtoLogToolInjected(LOG_GROUPS)
private static TreeMap<String, IProtoLogGroup> sLogGroups;
+ @ProtoLogToolInjected(CACHE_UPDATER)
+ private static Runnable sCacheUpdater;
+
/** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
public static void d(IProtoLogGroup group, long messageHash, int paramsMask,
@Nullable String messageString,
@@ -94,9 +98,12 @@ public class ProtoLogImpl {
getSingleInstance().log(LogLevel.WTF, group, messageHash, paramsMask, messageString, args);
}
- public static boolean isEnabled(IProtoLogGroup group) {
- // TODO: Implement for performance reasons, with optional level parameter?
- return true;
+ /**
+ * Should return true iff we should be logging to either protolog or logcat for this group
+ * and log level.
+ */
+ public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+ return getSingleInstance().isEnabled(group, level);
}
/**
@@ -105,11 +112,14 @@ public class ProtoLogImpl {
public static synchronized IProtoLog getSingleInstance() {
if (sServiceInstance == null) {
if (android.tracing.Flags.perfettoProtologTracing()) {
- sServiceInstance = new PerfettoProtoLogImpl(sViewerConfigPath, sLogGroups);
+ sServiceInstance = new PerfettoProtoLogImpl(
+ sViewerConfigPath, sLogGroups, sCacheUpdater);
} else {
sServiceInstance = new LegacyProtoLogImpl(
- sLegacyOutputFilePath, sLegacyViewerConfigPath, sLogGroups);
+ sLegacyOutputFilePath, sLegacyViewerConfigPath, sLogGroups, sCacheUpdater);
}
+
+ sCacheUpdater.run();
}
return sServiceInstance;
}
diff --git a/core/java/com/android/internal/protolog/common/IProtoLog.java b/core/java/com/android/internal/protolog/common/IProtoLog.java
index c06d14b2075e..f72d9f79958d 100644
--- a/core/java/com/android/internal/protolog/common/IProtoLog.java
+++ b/core/java/com/android/internal/protolog/common/IProtoLog.java
@@ -52,4 +52,12 @@ public interface IProtoLog {
* @return status code
*/
int stopLoggingToLogcat(String[] groups, ILogger logger);
+
+ /**
+ * Should return true iff logging is enabled to ProtoLog or to Logcat for this group and level.
+ * @param group ProtoLog group to check for.
+ * @param level ProtoLog level to check for.
+ * @return If we need to log this group and level to either ProtoLog or Logcat.
+ */
+ boolean isEnabled(IProtoLogGroup group, LogLevel level);
}
diff --git a/core/java/com/android/internal/protolog/common/IProtoLogGroup.java b/core/java/com/android/internal/protolog/common/IProtoLogGroup.java
index 4e9686f99f4b..149aa7aa7170 100644
--- a/core/java/com/android/internal/protolog/common/IProtoLogGroup.java
+++ b/core/java/com/android/internal/protolog/common/IProtoLogGroup.java
@@ -38,6 +38,7 @@ public interface IProtoLogGroup {
/**
* returns true is any logging is enabled for this group.
+ * @deprecated TODO(b/324128613) remove once we migrate fully to Perfetto
*/
default boolean isLogToAny() {
return isLogToLogcat() || isLogToProto();
@@ -50,6 +51,7 @@ public interface IProtoLogGroup {
/**
* set binary logging for this group.
+ * @deprecated TODO(b/324128613) remove once we migrate fully to Perfetto
*/
void setLogToProto(boolean logToProto);
diff --git a/core/java/com/android/internal/protolog/common/ProtoLog.java b/core/java/com/android/internal/protolog/common/ProtoLog.java
index 18e3f66c4795..8149cd5bbd3b 100644
--- a/core/java/com/android/internal/protolog/common/ProtoLog.java
+++ b/core/java/com/android/internal/protolog/common/ProtoLog.java
@@ -135,7 +135,7 @@ public class ProtoLog {
* @param group Group to check enable status of.
* @return true iff this is being logged.
*/
- public static boolean isEnabled(IProtoLogGroup group) {
+ public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
if (REQUIRE_PROTOLOGTOOL) {
throw new UnsupportedOperationException(
"ProtoLog calls MUST be processed with ProtoLogTool");
diff --git a/core/java/com/android/internal/protolog/common/ProtoLogToolInjected.java b/core/java/com/android/internal/protolog/common/ProtoLogToolInjected.java
index 17c82d76408e..2d39f3b4e152 100644
--- a/core/java/com/android/internal/protolog/common/ProtoLogToolInjected.java
+++ b/core/java/com/android/internal/protolog/common/ProtoLogToolInjected.java
@@ -23,7 +23,11 @@ import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.PARAMETER})
public @interface ProtoLogToolInjected {
enum Value {
- VIEWER_CONFIG_PATH, LEGACY_OUTPUT_FILE_PATH, LEGACY_VIEWER_CONFIG_PATH, LOG_GROUPS
+ VIEWER_CONFIG_PATH,
+ LEGACY_OUTPUT_FILE_PATH,
+ LEGACY_VIEWER_CONFIG_PATH,
+ LOG_GROUPS,
+ CACHE_UPDATER
}
Value value();
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 5184e49385b2..c2b9128daac5 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -96,7 +96,6 @@ import static com.android.server.wm.AppTransitionProto.LAST_USED_APP_TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
-import static com.android.server.wm.WindowManagerInternal.KeyguardExitAnimationStartListener;
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_AFTER_ANIM;
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_NONE;
@@ -105,7 +104,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
-import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -117,7 +115,6 @@ import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.Pair;
import android.util.Slog;
@@ -137,6 +134,7 @@ import android.view.animation.TranslateAnimation;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.TransitionAnimation;
+import com.android.internal.protolog.common.LogLevel;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.DumpUtils.Dump;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -244,7 +242,7 @@ public class AppTransition implements Dump {
mHandler = new Handler(service.mH.getLooper());
mDisplayContent = displayContent;
mTransitionAnimation = new TransitionAnimation(
- context, ProtoLog.isEnabled(WM_DEBUG_ANIM), TAG);
+ context, ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.DEBUG), TAG);
final TypedArray windowStyle = mContext.getTheme().obtainStyledAttributes(
com.android.internal.R.styleable.Window);
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 3ef6eeb2ecf3..63bbb3140bfb 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -44,6 +44,7 @@ import android.view.SurfaceControl.Transaction;
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.LogLevel;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.FastPrintWriter;
import com.android.server.wm.SurfaceAnimator.AnimationType;
@@ -209,7 +210,7 @@ class RemoteAnimationController implements DeathRecipient {
Slog.e(TAG, "Failed to start remote animation", e);
onAnimationFinished();
}
- if (ProtoLog.isEnabled(WM_DEBUG_REMOTE_ANIMATIONS)) {
+ if (ProtoLog.isEnabled(WM_DEBUG_REMOTE_ANIMATIONS, LogLevel.DEBUG)) {
ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation(): Notify animation start:");
writeStartDebugStatement();
}
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index d67684c7038e..c632714bd8ce 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -32,6 +32,7 @@ import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.LogLevel;
import com.android.internal.protolog.common.ProtoLog;
import java.io.PrintWriter;
@@ -192,7 +193,7 @@ public class SurfaceAnimator {
return;
}
mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
- if (ProtoLog.isEnabled(WM_DEBUG_ANIM)) {
+ if (ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.DEBUG)) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
mAnimation.dump(pw, "");
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index a2f6fb4c08ad..c8cb934783ef 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -22,7 +22,6 @@ import static android.app.WallpaperManager.COMMAND_UNFREEZE;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WALLPAPER;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 80889d1ac972..90ac57613cff 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -113,6 +113,7 @@ import android.window.WindowContainerToken;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
+import com.android.internal.protolog.common.LogLevel;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.wm.SurfaceAnimator.Animatable;
@@ -3405,7 +3406,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// ActivityOption#makeCustomAnimation or WindowManager#overridePendingTransition.
a.restrictDuration(MAX_APP_TRANSITION_DURATION);
}
- if (ProtoLog.isEnabled(WM_DEBUG_ANIM)) {
+ if (ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.DEBUG)) {
ProtoLog.i(WM_DEBUG_ANIM, "Loaded animation %s for %s, duration: %d, stack=%s",
a, this, ((a != null) ? a.getDuration() : 0), Debug.getCallers(20));
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index b716dc67f1a3..7a0245bc1acc 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -247,6 +247,7 @@ import android.window.OnBackInvokedCallbackInfo;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.KeyInterceptionInfo;
+import com.android.internal.protolog.common.LogLevel;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.ToBooleanFunction;
@@ -4739,7 +4740,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
void onExitAnimationDone() {
- if (ProtoLog.isEnabled(WM_DEBUG_ANIM)) {
+ if (ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.VERBOSE)) {
final AnimationAdapter animationAdapter = mSurfaceAnimator.getAnimation();
StringWriter sw = new StringWriter();
if (animationAdapter != null) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index a242d4242388..6fd7aa0e4a78 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -61,6 +61,7 @@ import android.view.WindowManager.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import com.android.internal.protolog.common.LogLevel;
import com.android.internal.protolog.common.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;
@@ -586,7 +587,7 @@ class WindowStateAnimator {
mWin.mAttrs, attr, TRANSIT_OLD_NONE);
}
}
- if (ProtoLog.isEnabled(WM_DEBUG_ANIM)) {
+ if (ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.VERBOSE)) {
ProtoLog.v(WM_DEBUG_ANIM, "applyAnimation: win=%s"
+ " anim=%d attr=0x%x a=%s transit=%d type=%d isEntrance=%b Callers %s",
this, anim, attr, a, transit, mAttrType, isEntrance, Debug.getCallers(20));
diff --git a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
index d9a4c261ee15..5cdfb2858b33 100644
--- a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
@@ -90,7 +90,7 @@ public class LegacyProtoLogImplTest {
//noinspection ResultOfMethodCallIgnored
mFile.delete();
mProtoLog = new LegacyProtoLogImpl(mFile, mViewerConfigFilename,
- 1024 * 1024, mReader, 1024, new TreeMap<>());
+ 1024 * 1024, mReader, 1024, new TreeMap<>(), () -> {});
}
@After
diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java
index a96389046d6a..001a09a0225a 100644
--- a/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java
@@ -67,7 +67,7 @@ public class PerfettoDataSourceTest {
@Test
public void allEnabledTraceMode() {
- final ProtoLogDataSource ds = new ProtoLogDataSource(() -> {}, () -> {}, () -> {});
+ final ProtoLogDataSource ds = new ProtoLogDataSource((c) -> {}, () -> {}, (c) -> {});
final ProtoLogDataSource.TlsState tlsState = createTlsState(
DataSourceConfigOuterClass.DataSourceConfig.newBuilder().setProtologConfig(
@@ -154,7 +154,7 @@ public class PerfettoDataSourceTest {
private ProtoLogDataSource.TlsState createTlsState(
DataSourceConfigOuterClass.DataSourceConfig config) {
final ProtoLogDataSource ds =
- Mockito.spy(new ProtoLogDataSource(() -> {}, () -> {}, () -> {}));
+ Mockito.spy(new ProtoLogDataSource((c) -> {}, () -> {}, (c) -> {}));
ProtoInputStream configStream = new ProtoInputStream(config.toByteArray());
final ProtoLogDataSource.Instance dsInstance = Mockito.spy(
diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
index 548adeff07b2..f6ac080ebf73 100644
--- a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
@@ -65,6 +65,7 @@ import java.io.IOException;
import java.util.List;
import java.util.Random;
import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicInteger;
import perfetto.protos.Protolog;
import perfetto.protos.ProtologCommon;
@@ -95,6 +96,7 @@ public class PerfettoProtoLogImplTest {
private PerfettoProtoLogImpl mProtoLog;
private Protolog.ProtoLogViewerConfig.Builder mViewerConfigBuilder;
private File mFile;
+ private Runnable mCacheUpdater;
private ProtoLogViewerConfigReader mReader;
@@ -152,9 +154,11 @@ public class PerfettoProtoLogImplTest {
Mockito.when(viewerConfigInputStreamProvider.getInputStream())
.thenAnswer(it -> new ProtoInputStream(mViewerConfigBuilder.build().toByteArray()));
+ mCacheUpdater = () -> {};
mReader = Mockito.spy(new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider));
- mProtoLog =
- new PerfettoProtoLogImpl(viewerConfigInputStreamProvider, mReader, new TreeMap<>());
+ mProtoLog = new PerfettoProtoLogImpl(
+ viewerConfigInputStreamProvider, mReader, new TreeMap<>(),
+ () -> mCacheUpdater.run());
}
@After
@@ -500,7 +504,8 @@ public class PerfettoProtoLogImplTest {
PerfettoTraceMonitor traceMonitor =
PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
List.of(new PerfettoTraceMonitor.Builder.ProtoLogGroupOverride(
- TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.DEBUG, true)))
+ TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.DEBUG,
+ true)))
.build();
try {
traceMonitor.start();
@@ -526,6 +531,142 @@ public class PerfettoProtoLogImplTest {
Truth.assertThat(stacktrace).contains("stackTraceTrimmed");
}
+ @Test
+ public void cacheIsUpdatedWhenTracesStartAndStop() {
+ final AtomicInteger cacheUpdateCallCount = new AtomicInteger(0);
+ mCacheUpdater = cacheUpdateCallCount::incrementAndGet;
+
+ PerfettoTraceMonitor traceMonitor1 =
+ PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
+ List.of(new PerfettoTraceMonitor.Builder.ProtoLogGroupOverride(
+ TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.WARN,
+ false)))
+ .build();
+
+ PerfettoTraceMonitor traceMonitor2 =
+ PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
+ List.of(new PerfettoTraceMonitor.Builder.ProtoLogGroupOverride(
+ TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.DEBUG,
+ false)))
+ .build();
+
+ Truth.assertThat(cacheUpdateCallCount.get()).isEqualTo(0);
+
+ try {
+ traceMonitor1.start();
+
+ Truth.assertThat(cacheUpdateCallCount.get()).isEqualTo(1);
+
+ try {
+ traceMonitor2.start();
+
+ Truth.assertThat(cacheUpdateCallCount.get()).isEqualTo(2);
+ } finally {
+ traceMonitor2.stop(mWriter);
+ }
+
+ Truth.assertThat(cacheUpdateCallCount.get()).isEqualTo(3);
+
+ } finally {
+ traceMonitor1.stop(mWriter);
+ }
+
+ Truth.assertThat(cacheUpdateCallCount.get()).isEqualTo(4);
+ }
+
+ @Test
+ public void isEnabledUpdatesBasedOnRunningTraces() {
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.DEBUG))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.VERBOSE))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.INFO))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WARN))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF)).isTrue();
+
+ PerfettoTraceMonitor traceMonitor1 =
+ PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
+ List.of(new PerfettoTraceMonitor.Builder.ProtoLogGroupOverride(
+ TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.WARN,
+ false)))
+ .build();
+
+ PerfettoTraceMonitor traceMonitor2 =
+ PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
+ List.of(new PerfettoTraceMonitor.Builder.ProtoLogGroupOverride(
+ TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.DEBUG,
+ false)))
+ .build();
+
+ try {
+ traceMonitor1.start();
+
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.DEBUG))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.VERBOSE))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.INFO))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WARN))
+ .isTrue();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
+ .isTrue();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF))
+ .isTrue();
+
+ try {
+ traceMonitor2.start();
+
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.DEBUG))
+ .isTrue();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP,
+ LogLevel.VERBOSE)).isTrue();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.INFO))
+ .isTrue();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WARN))
+ .isTrue();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
+ .isTrue();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF))
+ .isTrue();
+ } finally {
+ traceMonitor2.stop(mWriter);
+ }
+
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.DEBUG))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.VERBOSE))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.INFO))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WARN))
+ .isTrue();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
+ .isTrue();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF))
+ .isTrue();
+ } finally {
+ traceMonitor1.stop(mWriter);
+ }
+
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.DEBUG))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.VERBOSE))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.INFO))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WARN))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
+ .isFalse();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF))
+ .isTrue();
+ }
+
private enum TestProtoLogGroup implements IProtoLogGroup {
TEST_GROUP(true, true, false, "TEST_TAG");
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 837dae92b711..0f1373c34ce6 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -24,11 +24,20 @@ import com.github.javaparser.ParseProblemException
import com.github.javaparser.ParserConfiguration
import com.github.javaparser.StaticJavaParser
import com.github.javaparser.ast.CompilationUnit
+import com.github.javaparser.ast.Modifier
import com.github.javaparser.ast.NodeList
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
import com.github.javaparser.ast.body.InitializerDeclaration
+import com.github.javaparser.ast.expr.ArrayAccessExpr
+import com.github.javaparser.ast.expr.ArrayCreationExpr
+import com.github.javaparser.ast.expr.ArrayInitializerExpr
+import com.github.javaparser.ast.expr.AssignExpr
+import com.github.javaparser.ast.expr.BooleanLiteralExpr
+import com.github.javaparser.ast.expr.Expression
import com.github.javaparser.ast.expr.FieldAccessExpr
+import com.github.javaparser.ast.expr.IntegerLiteralExpr
import com.github.javaparser.ast.expr.MethodCallExpr
+import com.github.javaparser.ast.expr.MethodReferenceExpr
import com.github.javaparser.ast.expr.NameExpr
import com.github.javaparser.ast.expr.NullLiteralExpr
import com.github.javaparser.ast.expr.ObjectCreationExpr
@@ -168,6 +177,8 @@ object ProtoLogTool {
val classNameNode = classDeclaration.findFirst(SimpleName::class.java).get()
classNameNode.setId(protoLogImplGenName)
+ injectCacheClass(classDeclaration, groups, protoLogGroupsClassName)
+
injectConstants(classDeclaration,
viewerConfigFilePath, legacyViewerConfigFilePath, legacyOutputFilePath, groups,
protoLogGroupsClassName)
@@ -238,6 +249,12 @@ object ProtoLogTool {
field.setFinal(true)
field.variables.first().setInitializer(treeMapCreation)
}
+ ProtoLogToolInjected.Value.CACHE_UPDATER.name -> {
+ field.setFinal(true)
+ field.variables.first().setInitializer(MethodReferenceExpr()
+ .setScope(NameExpr("Cache"))
+ .setIdentifier("update"))
+ }
else -> error("Unhandled ProtoLogToolInjected value: $valueName.")
}
}
@@ -245,6 +262,61 @@ object ProtoLogTool {
}
}
+ private fun injectCacheClass(
+ classDeclaration: ClassOrInterfaceDeclaration,
+ groups: Map<String, LogGroup>,
+ protoLogGroupsClassName: String,
+ ) {
+ val cacheClass = ClassOrInterfaceDeclaration()
+ .setName("Cache")
+ .setPublic(true)
+ .setStatic(true)
+ for (group in groups) {
+ val nodeList = NodeList<Expression>()
+ val defaultVal = BooleanLiteralExpr(group.value.textEnabled || group.value.enabled)
+ repeat(LogLevel.entries.size) { nodeList.add(defaultVal) }
+ cacheClass.addFieldWithInitializer(
+ "boolean[]",
+ "${group.key}_enabled",
+ ArrayCreationExpr().setElementType("boolean[]").setInitializer(
+ ArrayInitializerExpr().setValues(nodeList)
+ ),
+ Modifier.Keyword.PUBLIC,
+ Modifier.Keyword.STATIC
+ )
+ }
+
+ val updateBlockStmt = BlockStmt()
+ for (group in groups) {
+ for (level in LogLevel.entries) {
+ updateBlockStmt.addStatement(
+ AssignExpr()
+ .setTarget(
+ ArrayAccessExpr()
+ .setName(NameExpr("${group.key}_enabled"))
+ .setIndex(IntegerLiteralExpr(level.ordinal))
+ ).setValue(
+ MethodCallExpr()
+ .setName("isEnabled")
+ .setArguments(NodeList(
+ FieldAccessExpr()
+ .setScope(NameExpr(protoLogGroupsClassName))
+ .setName(group.value.name),
+ FieldAccessExpr()
+ .setScope(NameExpr("LogLevel"))
+ .setName(level.toString()),
+ ))
+ )
+ )
+ }
+ }
+
+ cacheClass.addMethod("update").setPrivate(true).setStatic(true)
+ .setBody(updateBlockStmt)
+
+ classDeclaration.addMember(cacheClass)
+ }
+
private fun tryParse(code: String, fileName: String): CompilationUnit {
try {
return StaticJavaParser.parse(code)
diff --git a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
index 2b7164191dd0..6a8a0717b2f1 100644
--- a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
@@ -22,6 +22,7 @@ import com.github.javaparser.StaticJavaParser
import com.github.javaparser.ast.CompilationUnit
import com.github.javaparser.ast.NodeList
import com.github.javaparser.ast.body.VariableDeclarator
+import com.github.javaparser.ast.expr.ArrayAccessExpr
import com.github.javaparser.ast.expr.CastExpr
import com.github.javaparser.ast.expr.Expression
import com.github.javaparser.ast.expr.FieldAccessExpr
@@ -35,6 +36,8 @@ import com.github.javaparser.ast.expr.TypeExpr
import com.github.javaparser.ast.expr.VariableDeclarationExpr
import com.github.javaparser.ast.stmt.BlockStmt
import com.github.javaparser.ast.stmt.ExpressionStmt
+import com.github.javaparser.ast.stmt.IfStmt
+import com.github.javaparser.ast.stmt.Statement
import com.github.javaparser.ast.type.ArrayType
import com.github.javaparser.ast.type.ClassOrInterfaceType
import com.github.javaparser.ast.type.PrimitiveType
@@ -74,6 +77,8 @@ class SourceTransformer(
private val protoLogImplClassNode =
StaticJavaParser.parseExpression<FieldAccessExpr>(protoLogImplClassName)
+ private val protoLogImplCacheClassNode =
+ StaticJavaParser.parseExpression<FieldAccessExpr>("$protoLogImplClassName.Cache")
private var processedCode: MutableList<String> = mutableListOf()
private var offsets: IntArray = IntArray(0)
/** The path of the file being processed, relative to $ANDROID_BUILD_TOP */
@@ -121,8 +126,9 @@ class SourceTransformer(
group: LogGroup,
level: LogLevel,
messageString: String
- ): BlockStmt {
+ ): Statement {
val hash = CodeUtils.hash(packagePath, messageString, level, group)
+
val newCall = call.clone()
if (!group.textEnabled) {
// Remove message string if text logging is not enabled by default.
@@ -166,11 +172,15 @@ class SourceTransformer(
}
blockStmt.addStatement(ExpressionStmt(newCall))
- return blockStmt
+ val isLogEnabled = ArrayAccessExpr()
+ .setName(NameExpr("$protoLogImplCacheClassNode.${group.name}_enabled"))
+ .setIndex(IntegerLiteralExpr(level.ordinal))
+
+ return IfStmt(isLogEnabled, blockStmt, null)
}
private fun injectProcessedCallStatementInCode(
- processedCallStatement: BlockStmt,
+ processedCallStatement: Statement,
parentStmt: ExpressionStmt
) {
// Inline the new statement.
diff --git a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
index de0b5bae118e..82aa93da613b 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
@@ -76,7 +76,7 @@ class SourceTransformerTest {
class Test {
void test() {
- { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
}
}
""".trimIndent()
@@ -86,7 +86,7 @@ class SourceTransformerTest {
class Test {
void test() {
- { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, "test %d %f " + "abc %s\n test", protoLogParam0, protoLogParam1, protoLogParam2);
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, "test %d %f " + "abc %s\n test", protoLogParam0, protoLogParam1, protoLogParam2);
}
}
@@ -98,8 +98,8 @@ class SourceTransformerTest {
class Test {
void test() {
- { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); } /* ProtoLog.w(TEST_GROUP, "test %d %f", 100, 0.1); */ { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
- { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); } /* ProtoLog.w(TEST_GROUP, "test %d %f", 100, 0.1); */ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
}
}
""".trimIndent()
@@ -109,7 +109,7 @@ class SourceTransformerTest {
class Test {
void test() {
- { org.example.ProtoLogImpl.w(TEST_GROUP, 3218600869538902408L, 0, "test", (Object[]) null); }
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { org.example.ProtoLogImpl.w(TEST_GROUP, 3218600869538902408L, 0, "test", (Object[]) null); }
}
}
""".trimIndent()
@@ -119,7 +119,7 @@ class SourceTransformerTest {
class Test {
void test() {
- { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, null, protoLogParam0, protoLogParam1); }
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, null, protoLogParam0, protoLogParam1); }
}
}
""".trimIndent()
@@ -129,7 +129,7 @@ class SourceTransformerTest {
class Test {
void test() {
- { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, null, protoLogParam0, protoLogParam1, protoLogParam2);
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, null, protoLogParam0, protoLogParam1, protoLogParam2);
}
}