summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt3
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/ProtoLogCallVisitor.kt8
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt8
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt3
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt2
-rw-r--r--tools/protologtool/tests/com/android/protolog/tool/ProtoLogCallProcessorImplTest.kt3
-rw-r--r--tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt16
-rw-r--r--tools/protologtool/tests/com/android/protolog/tool/ViewerConfigJsonBuilderTest.kt12
-rw-r--r--tools/protologtool/tests/com/android/protolog/tool/ViewerConfigProtoBuilderTest.kt22
-rw-r--r--tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt80
-rw-r--r--tools/systemfeatures/tests/src/ArraySet.java34
11 files changed, 143 insertions, 48 deletions
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
index c3595b7ac288..272d8bb1793d 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
@@ -119,7 +119,8 @@ class ProtoLogCallProcessorImpl(
}
logCallVisitor?.processCall(call, messageString, getLevelForMethodName(
- call.name.toString(), call, context), groupMap.getValue(groupName))
+ call.name.toString(), call, context), groupMap.getValue(groupName),
+ context.lineNumber)
} else if (call.name.id == "init") {
// No processing
} else {
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallVisitor.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallVisitor.kt
index 8cd927a7cd0e..216241ac5a47 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallVisitor.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallVisitor.kt
@@ -20,5 +20,11 @@ import com.android.internal.protolog.common.LogLevel
import com.github.javaparser.ast.expr.MethodCallExpr
interface ProtoLogCallVisitor {
- fun processCall(call: MethodCallExpr, messageString: String, level: LogLevel, group: LogGroup)
+ fun processCall(
+ call: MethodCallExpr,
+ messageString: String,
+ level: LogLevel,
+ group: LogGroup,
+ lineNumber: Int
+ )
}
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 9222ff4bf52c..d8a2954545bb 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -69,7 +69,8 @@ object ProtoLogTool {
val messageString: String,
val logLevel: LogLevel,
val logGroup: LogGroup,
- val position: String
+ val position: String,
+ val lineNumber: Int,
)
private fun showHelpAndExit() {
@@ -435,9 +436,10 @@ object ProtoLogTool {
call: MethodCallExpr,
messageString: String,
level: LogLevel,
- group: LogGroup
+ group: LogGroup,
+ lineNumber: Int,
) {
- val logCall = LogCall(messageString, level, group, packagePath)
+ val logCall = LogCall(messageString, level, group, packagePath, lineNumber)
calls.add(logCall)
}
}
diff --git a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
index c478f5844de6..76df0674df65 100644
--- a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
@@ -91,7 +91,8 @@ class SourceTransformer(
call: MethodCallExpr,
messageString: String,
level: LogLevel,
- group: LogGroup
+ group: LogGroup,
+ lineNumber: Int,
) {
validateCall(call)
val processedCallStatement =
diff --git a/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt b/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt
index de85411e4ffc..5af2d9440533 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt
@@ -59,7 +59,7 @@ class ViewerConfigProtoBuilder : ProtoLogTool.ProtologViewerConfigBuilder {
.setLevel(
ProtoLogLevel.forNumber(log.logLevel.id))
.setGroupId(groupId)
- .setLocation(log.position)
+ .setLocation("${log.position}:${log.lineNumber}")
)
}
diff --git a/tools/protologtool/tests/com/android/protolog/tool/ProtoLogCallProcessorImplTest.kt b/tools/protologtool/tests/com/android/protolog/tool/ProtoLogCallProcessorImplTest.kt
index 5e50f71d75cc..004d97babbad 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/ProtoLogCallProcessorImplTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/ProtoLogCallProcessorImplTest.kt
@@ -42,7 +42,8 @@ class ProtoLogCallProcessorImplTest {
call: MethodCallExpr,
messageString: String,
level: LogLevel,
- group: LogGroup
+ group: LogGroup,
+ lineNumber: Int,
) {
calls.add(LogCall(call, messageString, level, group))
}
diff --git a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
index 6cde7a72db53..674a907d68d9 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
@@ -158,7 +158,7 @@ class SourceTransformerTest {
val visitor = invocation.arguments[1] as ProtoLogCallVisitor
visitor.processCall(code.findAll(MethodCallExpr::class.java)[0], "test %d %f",
- LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"))
+ LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"), 123)
invocation.arguments[0] as CompilationUnit
}
@@ -195,11 +195,11 @@ class SourceTransformerTest {
val calls = code.findAll(MethodCallExpr::class.java)
visitor.processCall(calls[0], "test %d %f",
- LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"))
+ LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"), 456)
visitor.processCall(calls[1], "test %d %f",
- LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"))
+ LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"), 789)
visitor.processCall(calls[2], "test %d %f",
- LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"))
+ LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"), 123)
invocation.arguments[0] as CompilationUnit
}
@@ -236,7 +236,7 @@ class SourceTransformerTest {
visitor.processCall(code.findAll(MethodCallExpr::class.java)[0],
"test %d %f abc %s\n test", LogLevel.WARN, LogGroup("TEST_GROUP",
- true, true, "WM_TEST"))
+ true, true, "WM_TEST"), 123)
invocation.arguments[0] as CompilationUnit
}
@@ -273,7 +273,7 @@ class SourceTransformerTest {
val visitor = invocation.arguments[1] as ProtoLogCallVisitor
visitor.processCall(code.findAll(MethodCallExpr::class.java)[0], "test",
- LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"))
+ LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"), 456)
invocation.arguments[0] as CompilationUnit
}
@@ -307,7 +307,7 @@ class SourceTransformerTest {
val visitor = invocation.arguments[1] as ProtoLogCallVisitor
visitor.processCall(code.findAll(MethodCallExpr::class.java)[0], "test %d %f",
- LogLevel.WARN, LogGroup("TEST_GROUP", true, false, "WM_TEST"))
+ LogLevel.WARN, LogGroup("TEST_GROUP", true, false, "WM_TEST"), 789)
invocation.arguments[0] as CompilationUnit
}
@@ -344,7 +344,7 @@ class SourceTransformerTest {
visitor.processCall(code.findAll(MethodCallExpr::class.java)[0],
"test %d %f abc %s\n test", LogLevel.WARN, LogGroup("TEST_GROUP",
- true, false, "WM_TEST"))
+ true, false, "WM_TEST"), 123)
invocation.arguments[0] as CompilationUnit
}
diff --git a/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigJsonBuilderTest.kt b/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigJsonBuilderTest.kt
index 1a20d4c5bad6..bcbc8790e170 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigJsonBuilderTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigJsonBuilderTest.kt
@@ -50,9 +50,9 @@ class ViewerConfigJsonBuilderTest {
fun processClass() {
val logCallRegistry = ProtoLogTool.LogCallRegistry()
logCallRegistry.addLogCalls(listOf(
- LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
- LogCall(TEST2.messageString, LogLevel.DEBUG, GROUP2, PATH),
- LogCall(TEST3.messageString, LogLevel.ERROR, GROUP3, PATH)))
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 123),
+ LogCall(TEST2.messageString, LogLevel.DEBUG, GROUP2, PATH, 456),
+ LogCall(TEST3.messageString, LogLevel.ERROR, GROUP3, PATH, 789)))
val parsedConfig = parseConfig(
configBuilder.build(GROUPS, logCallRegistry.getStatements()).toString(Charsets.UTF_8))
@@ -69,9 +69,9 @@ class ViewerConfigJsonBuilderTest {
fun processClass_nonUnique() {
val logCallRegistry = ProtoLogTool.LogCallRegistry()
logCallRegistry.addLogCalls(listOf(
- LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
- LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
- LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH)))
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 123),
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 456),
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 789)))
val parsedConfig = parseConfig(
configBuilder.build(GROUPS, logCallRegistry.getStatements()).toString(Charsets.UTF_8))
diff --git a/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigProtoBuilderTest.kt b/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigProtoBuilderTest.kt
index 74a8de7f70c0..dfc66405eec9 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigProtoBuilderTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigProtoBuilderTest.kt
@@ -55,8 +55,8 @@ class ViewerConfigProtoBuilderTest {
val logCallRegistry = ProtoLogTool.LogCallRegistry()
logCallRegistry.addLogCalls(listOf(
- LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
- LogCall(TEST2.messageString, LogLevel.INFO, GROUP2, PATH),
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 123),
+ LogCall(TEST2.messageString, LogLevel.INFO, GROUP2, PATH, 456),
))
val rawProto = configBuilder.build(GROUPS, logCallRegistry.getStatements())
@@ -65,4 +65,22 @@ class ViewerConfigProtoBuilderTest {
Truth.assertThat(viewerConfig.groupsCount).isEqualTo(GROUPS.size)
Truth.assertThat(viewerConfig.messagesCount).isLessThan(GROUPS.size)
}
+
+ @Test
+ fun includesLineNumberInLocation() {
+ val configBuilder = ViewerConfigProtoBuilder()
+
+ val logCallRegistry = ProtoLogTool.LogCallRegistry()
+ logCallRegistry.addLogCalls(listOf(
+ LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 123),
+ LogCall(TEST2.messageString, LogLevel.INFO, GROUP2, PATH, 456),
+ ))
+
+ val rawProto = configBuilder.build(GROUPS, logCallRegistry.getStatements())
+
+ val viewerConfig = ProtoLogViewerConfig.parseFrom(rawProto)
+
+ Truth.assertThat(viewerConfig.messagesList[0].location).isEqualTo("$PATH:123")
+ Truth.assertThat(viewerConfig.messagesList[1].location).isEqualTo("$PATH:456")
+ }
} \ No newline at end of file
diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
index 4a6d4b1f49ef..c51c6d661314 100644
--- a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
+++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
@@ -18,9 +18,11 @@ package com.android.systemfeatures
import android.annotation.SdkConstant
import com.squareup.javapoet.ClassName
+import com.squareup.javapoet.CodeBlock
import com.squareup.javapoet.FieldSpec
import com.squareup.javapoet.JavaFile
import com.squareup.javapoet.MethodSpec
+import com.squareup.javapoet.ParameterizedTypeName
import com.squareup.javapoet.TypeSpec
import java.io.IOException
import javax.annotation.processing.AbstractProcessor
@@ -101,8 +103,8 @@ class SystemFeaturesMetadataProcessor : AbstractProcessor() {
TypeSpec.classBuilder("SystemFeaturesMetadata")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addJavadoc("@hide")
- .addField(buildFeatureCount(featureVarNames))
- .addMethod(buildFeatureIndexLookup(featureVarNames))
+ .addFeatureCount(featureVarNames)
+ .addFeatureIndexLookup(featureVarNames)
.build()
try {
@@ -120,19 +122,55 @@ class SystemFeaturesMetadataProcessor : AbstractProcessor() {
return true
}
- private fun buildFeatureCount(featureVarNames: Collection<String>): FieldSpec {
- return FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
- .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
- .addJavadoc(
- "# of {@link android.annotation.SdkConstant}` features defined in PackageManager."
- )
- .addJavadoc("\n\n@hide")
- .initializer("\$L", featureVarNames.size)
- .build()
+ private fun TypeSpec.Builder.addFeatureCount(
+ featureVarNames: Collection<String>
+ ): TypeSpec.Builder {
+ return addField(
+ FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
+ .addJavadoc(
+ "# of {@link android.annotation.SdkConstant}` features in PackageManager."
+ )
+ .addJavadoc("\n\n@hide")
+ .initializer("\$L", featureVarNames.size)
+ .build()
+ )
}
- private fun buildFeatureIndexLookup(featureVarNames: Collection<String>): MethodSpec {
- val methodBuilder =
+ private fun TypeSpec.Builder.addFeatureIndexLookup(
+ featureVarNames: Collection<String>
+ ): TypeSpec.Builder {
+ // NOTE: This was initially implemented in terms of a single, long switch() statement.
+ // However, this resulted in:
+ // 1) relatively large compiled code size for the lookup method (~20KB)
+ // 2) worse runtime lookup performance than a simple ArraySet
+ // The ArraySet approach adds just ~1KB to the code/image and is 2x faster at runtime.
+
+ // Provide the initial capacity of the ArraySet for efficiency.
+ addField(
+ FieldSpec.builder(
+ ParameterizedTypeName.get(ARRAYSET_CLASS, ClassName.get(String::class.java)),
+ "sFeatures",
+ )
+ .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
+ .initializer("new ArraySet<>(\$L)", featureVarNames.size)
+ .build()
+ )
+
+ // Use a temp array + Collections.addAll() to minimizes the generated code size.
+ addStaticBlock(
+ CodeBlock.builder()
+ .add("final \$T[] features = {\n", String::class.java)
+ .indent()
+ .apply { featureVarNames.forEach { add("\$T.\$N,\n", PACKAGEMANAGER_CLASS, it) } }
+ .unindent()
+ .addStatement("}")
+ .addStatement("\$T.addAll(sFeatures, features)", COLLECTIONS_CLASS)
+ .build()
+ )
+
+ // Use ArraySet.indexOf to provide the implicit feature index mapping.
+ return addMethod(
MethodSpec.methodBuilder("maybeGetSdkFeatureIndex")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addJavadoc("@return an index in [0, SDK_FEATURE_COUNT) for features defined ")
@@ -140,21 +178,15 @@ class SystemFeaturesMetadataProcessor : AbstractProcessor() {
.addJavadoc("\n\n@hide")
.returns(Int::class.java)
.addParameter(String::class.java, "featureName")
- methodBuilder.beginControlFlow("switch (featureName)")
- featureVarNames.forEachIndexed { index, featureVarName ->
- methodBuilder
- .addCode("case \$T.\$N: ", PACKAGEMANAGER_CLASS, featureVarName)
- .addStatement("return \$L", index)
- }
- methodBuilder
- .addCode("default: ")
- .addStatement("return -1")
- .endControlFlow()
- return methodBuilder.build()
+ .addStatement("return sFeatures.indexOf(featureName)")
+ .build()
+ )
}
companion object {
private val SDK_CONSTANT_ANNOTATION_NAME = SdkConstant::class.qualifiedName
private val PACKAGEMANAGER_CLASS = ClassName.get("android.content.pm", "PackageManager")
+ private val ARRAYSET_CLASS = ClassName.get("android.util", "ArraySet")
+ private val COLLECTIONS_CLASS = ClassName.get("java.util", "Collections")
}
}
diff --git a/tools/systemfeatures/tests/src/ArraySet.java b/tools/systemfeatures/tests/src/ArraySet.java
new file mode 100644
index 000000000000..0eb8f298bd89
--- /dev/null
+++ b/tools/systemfeatures/tests/src/ArraySet.java
@@ -0,0 +1,34 @@
+/*
+ * 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 android.util;
+
+import java.util.ArrayList;
+
+/** Stub for testing, we extend ArrayList to get indexOf() for free. */
+public final class ArraySet<K> extends ArrayList<K> {
+ public ArraySet(int capacity) {
+ super(capacity);
+ }
+
+ @Override
+ public boolean add(K k) {
+ if (!contains(k)) {
+ return super.add(k);
+ }
+ return false;
+ }
+}