summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Giulio Fiscella <fiscella@google.com> 2022-02-20 12:51:03 +0000
committer Giulio Fiscella <fiscella@google.com> 2022-04-06 23:53:01 +0000
commit9fc61018e915e3474a860585dcac290fafd262bc (patch)
tree67e374bbc39096240b71b56d7d70bcaf11047e37
parent92713f8afeecf4dd2ce7f68733b26c24eef91ce8 (diff)
Add custom lint check for Safety Center config
Test: atest ConfigLintCheckerTest --host Test: m out/soong/.intermediates/packages/modules/Permission/SafetyCenter/Resources/SafetyCenterResources/android_common/lint/lint-report.html Bug: 220722371 Change-Id: Ibbfc71f1e681bfa140e0f21c54dded59a41dd94a
-rw-r--r--SafetyCenter/Config/Android.bp9
-rw-r--r--SafetyCenter/ConfigLintChecker/Android.bp53
-rw-r--r--SafetyCenter/ConfigLintChecker/jarjar-rules.txt10
-rw-r--r--SafetyCenter/ConfigLintChecker/java/android/content/res/Resources.java31
-rw-r--r--SafetyCenter/ConfigLintChecker/java/android/os/Build.java28
-rw-r--r--SafetyCenter/ConfigLintChecker/java/android/os/Parcel.java41
-rw-r--r--SafetyCenter/ConfigLintChecker/java/android/os/Parcelable.java37
-rw-r--r--SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigLintCheckerIssueRegistry.kt42
-rw-r--r--SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ParserExceptionDetector.kt71
-rw-r--r--SafetyCenter/ConfigLintChecker/tests/java/android/safetycenter/lint/test/ParserExceptionDetectorTest.kt79
-rw-r--r--SafetyCenter/Resources/Android.bp3
-rw-r--r--framework-s/Android.bp7
12 files changed, 410 insertions, 1 deletions
diff --git a/SafetyCenter/Config/Android.bp b/SafetyCenter/Config/Android.bp
index afe7c380a..2b20cea0f 100644
--- a/SafetyCenter/Config/Android.bp
+++ b/SafetyCenter/Config/Android.bp
@@ -17,13 +17,20 @@ package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
+filegroup {
+ name: "safetycenter-config-parser-sources",
+ srcs: ["java/**/*.java"],
+ path: "java",
+ visibility: ["//packages/modules/Permission/SafetyCenter/ConfigLintChecker"],
+}
+
java_library {
name: "safety-center-config",
sdk_version: "module_current",
min_sdk_version: "30",
target_sdk_version: "32",
srcs: [
- "java/**/*.java",
+ ":safetycenter-config-parser-sources",
],
libs: [
"androidx.annotation_annotation",
diff --git a/SafetyCenter/ConfigLintChecker/Android.bp b/SafetyCenter/ConfigLintChecker/Android.bp
new file mode 100644
index 000000000..4b5053f19
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/Android.bp
@@ -0,0 +1,53 @@
+// Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library_host {
+ name: "ConfigLintChecker",
+ srcs: [
+ "java/**/*.java",
+ "java/**/*.kt",
+ ":safetycenter-config-api-sources",
+ ":safetycenter-config-parser-sources",
+ ],
+ plugins: ["auto_service_plugin"],
+ libs: [
+ "androidx.annotation_annotation", // For androidx.annotation.RequiresApi
+ "auto_service_annotations",
+ "core-xml-for-host", // For org.xmlpull.v1.*
+ "framework-annotations-lib", // For com.android.annotation.*
+ "layoutlib_api-prebuilt", // For com.android.resources.ResourceFolderType
+ "lint_api",
+ ],
+ jarjar_rules: "jarjar-rules.txt",
+}
+
+java_test_host {
+ name: "ConfigLintCheckerTest",
+ srcs: [
+ "tests/java/**/*.kt",
+ ],
+ static_libs: [
+ "ConfigLintChecker",
+ "junit",
+ "lint",
+ "lint_tests",
+ ],
+ test_options: {
+ unit_test: true,
+ },
+}
diff --git a/SafetyCenter/ConfigLintChecker/jarjar-rules.txt b/SafetyCenter/ConfigLintChecker/jarjar-rules.txt
new file mode 100644
index 000000000..c4a25fe33
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/jarjar-rules.txt
@@ -0,0 +1,10 @@
+# Android Lint has its own API versioning and API release process.
+# To check that a custom linter can be plugged into the linter execution, Android Lint inspects the
+# library and makes sure that all *relevant* references can be resolved, even if they are not used
+# at runtime. The assumption is that if a *relevant* reference is missing, then it must mean that
+# the custom linter is using either unreleased or abandoned versions of the Android Lint APIs.
+# At the time of writing, almost anything that starts with `com.android` is considered a *relevant*
+# reference by `LintJarVerifier`. To work around this, preserve the dynamically linked Android Lint
+# API references and rename any other `com.android` reference.
+rule com.android.tools.lint.** @0
+rule com.android.** android.safetycenter.lint.jarjar.@0
diff --git a/SafetyCenter/ConfigLintChecker/java/android/content/res/Resources.java b/SafetyCenter/ConfigLintChecker/java/android/content/res/Resources.java
new file mode 100644
index 000000000..8dff0a4ae
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/java/android/content/res/Resources.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 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.content.res;
+
+/** Stub class to compile the linter for host execution. */
+public final class Resources {
+ /** Constant used in the Safety Center config parser. */
+ public static final int ID_NULL = 0;
+
+ /** Class used in the Safety Center config parser. */
+ public Resources() {}
+
+ /** Method used in the Safety Center config parser. */
+ public int getIdentifier(String name, String defType, String defPackage) {
+ return ID_NULL + 1;
+ }
+}
diff --git a/SafetyCenter/ConfigLintChecker/java/android/os/Build.java b/SafetyCenter/ConfigLintChecker/java/android/os/Build.java
new file mode 100644
index 000000000..abe5d49d3
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/java/android/os/Build.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 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.os;
+
+/** Stub class to compile the linter for host execution. */
+public final class Build {
+ private Build() {}
+
+ /** Stub class to used in the Safety Center config files. */
+ public static final class VERSION_CODES {
+ /** Constant used in the Safety Center config files. */
+ public static final int TIRAMISU = 10000;
+ }
+}
diff --git a/SafetyCenter/ConfigLintChecker/java/android/os/Parcel.java b/SafetyCenter/ConfigLintChecker/java/android/os/Parcel.java
new file mode 100644
index 000000000..e1300de32
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/java/android/os/Parcel.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 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.os;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Stub interface to compile the linter for host execution. */
+public interface Parcel {
+ /** Method used in the Safety Center config data structures. */
+ <T> ArrayList<T> createTypedArrayList(Parcelable.Creator<T> creator);
+ /** Method used in the Safety Center config data structures. */
+ boolean readBoolean();
+ /** Method used in the Safety Center config data structures. */
+ int readInt();
+ /** Method used in the Safety Center config data structures. */
+ String readString();
+
+ /** Method used in the Safety Center config data structures. */
+ void writeBoolean(boolean value);
+ /** Method used in the Safety Center config data structures. */
+ void writeInt(int value);
+ /** Method used in the Safety Center config data structures. */
+ void writeString(String value);
+ /** Method used in the Safety Center config data structures. */
+ <T extends Parcelable> void writeTypedList(List<T> value);
+}
diff --git a/SafetyCenter/ConfigLintChecker/java/android/os/Parcelable.java b/SafetyCenter/ConfigLintChecker/java/android/os/Parcelable.java
new file mode 100644
index 000000000..3c0cd3e70
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/java/android/os/Parcelable.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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.os;
+
+/** Stub interface to compile the linter for host execution. */
+public interface Parcelable {
+ /** Method used in the Safety Center config data structures. */
+ int describeContents();
+ /** Method used in the Safety Center config data structures. */
+ void writeToParcel(Parcel dest, int flags);
+
+ /**
+ * Interface implemented in the Safety Center config data structures.
+ *
+ * @param <T> Generic object, should be Parcelable.
+ */
+ interface Creator<T> {
+ /** Method used in the Safety Center config data structures. */
+ T createFromParcel(Parcel source);
+ /** Method used in the Safety Center config data structures. */
+ T[] newArray(int size);
+ }
+}
diff --git a/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigLintCheckerIssueRegistry.kt b/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigLintCheckerIssueRegistry.kt
new file mode 100644
index 000000000..536769160
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigLintCheckerIssueRegistry.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 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.safetycenter.lint
+
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+import com.google.auto.service.AutoService
+
+@AutoService(IssueRegistry::class)
+@Suppress("UnstableApiUsage")
+class ConfigLintCheckerIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ ParserExceptionDetector.ISSUE
+ )
+
+ override val api: Int
+ get() = CURRENT_API
+
+ override val minApi: Int
+ get() = 11
+
+ override val vendor = Vendor(
+ vendorName = "Android",
+ feedbackUrl = "http://b/issues/new?component=1026964",
+ contact = "fiscella@google.com"
+ )
+}
diff --git a/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ParserExceptionDetector.kt b/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ParserExceptionDetector.kt
new file mode 100644
index 000000000..f9cb62a8f
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ParserExceptionDetector.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 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.safetycenter.lint
+
+import android.content.res.Resources
+import com.android.resources.ResourceFolderType
+import com.android.safetycenter.config.ParseException
+import com.android.safetycenter.config.SafetyCenterConfigParser
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Context
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.Location
+import com.android.tools.lint.detector.api.OtherFileScanner
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+
+/** Lint check for detecting invalid Safety Center configs */
+class ParserExceptionDetector : Detector(), OtherFileScanner {
+
+ companion object {
+ val ISSUE = Issue.create(
+ id = "InvalidSafetyCenterConfig",
+ briefDescription = "The Safety Center config parser detected an error",
+ explanation = """The Safety Center config must follow all constraints defined in \
+ safety_center_config.xsd. Check the error message to find out the specific \
+ constraint not met by the current config.""",
+ category = Category.CORRECTNESS,
+ severity = Severity.ERROR,
+ implementation = Implementation(
+ ParserExceptionDetector::class.java,
+ Scope.OTHER_SCOPE
+ ),
+ androidSpecific = true
+ )
+ }
+
+ override fun appliesTo(folderType: ResourceFolderType): Boolean {
+ return folderType == ResourceFolderType.RAW
+ }
+
+ override fun run(context: Context) {
+ if (context.file.name != "safety_center_config.xml") {
+ return
+ }
+ try {
+ SafetyCenterConfigParser.parseXmlResource(context.file.inputStream(), Resources())
+ } catch (e: ParseException) {
+ context.report(
+ ISSUE,
+ Location.create(context.file),
+ "Parser exception: \"${e.message}\", cause: \"${e.cause?.message}\""
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/SafetyCenter/ConfigLintChecker/tests/java/android/safetycenter/lint/test/ParserExceptionDetectorTest.kt b/SafetyCenter/ConfigLintChecker/tests/java/android/safetycenter/lint/test/ParserExceptionDetectorTest.kt
new file mode 100644
index 000000000..8c859ae1d
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/tests/java/android/safetycenter/lint/test/ParserExceptionDetectorTest.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 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.safetycenter.lint.test
+
+import android.safetycenter.lint.ParserExceptionDetector
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@Suppress("UnstableApiUsage")
+@RunWith(JUnit4::class)
+class ParserExceptionDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector = ParserExceptionDetector()
+
+ override fun getIssues(): List<Issue> = listOf(ParserExceptionDetector.ISSUE)
+
+ override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
+
+ @Test
+ fun validConfig_doesNotThrow() {
+ lint().files((
+ xml("res/raw/safety_center_config.xml",
+ """
+<safety-center-config>
+ <safety-sources-config>
+ <safety-sources-group
+ id="group"
+ title="@package:string/reference"
+ summary="@package:string/reference">
+ <static-safety-source
+ id="source"
+ title="@package:string/reference"
+ summary="@package:string/reference"
+ intentAction="intent"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
+ </safety-sources-config>
+</safety-center-config>
+ """))).run().expectClean()
+ }
+
+ @Test
+ fun invalidConfig_throws() {
+ lint().files((xml("res/raw/safety_center_config.xml", "<invalid-root/>")))
+ .run().expect("res/raw/safety_center_config.xml: Error: Parser exception: " +
+ "\"Element safety-center-config missing\", cause: \"null\" " +
+ "[InvalidSafetyCenterConfig]\n1 errors, 0 warnings")
+ }
+
+ @Test
+ fun unrelatedFile_doesNotThrow() {
+ lint().files((xml("res/raw/some_other_config.xml", "<some-other-root/>")))
+ .run().expectClean()
+ }
+
+ @Test
+ fun unrelatedFolder_doesNotThrow() {
+ lint().files((xml("res/values/strings.xml", "<some-other-root/>")))
+ .run().expectClean()
+ }
+}
diff --git a/SafetyCenter/Resources/Android.bp b/SafetyCenter/Resources/Android.bp
index de6a2cab0..05f9f4c37 100644
--- a/SafetyCenter/Resources/Android.bp
+++ b/SafetyCenter/Resources/Android.bp
@@ -27,6 +27,9 @@ android_app {
target_sdk_version: "32",
apex_available: ["com.android.permission"],
certificate: ":com.android.safetycenter.resources.certificate",
+ lint: {
+ extra_check_modules: ["ConfigLintChecker"],
+ },
}
android_app_certificate {
diff --git a/framework-s/Android.bp b/framework-s/Android.bp
index 9d93799a2..6be71d416 100644
--- a/framework-s/Android.bp
+++ b/framework-s/Android.bp
@@ -26,6 +26,13 @@ filegroup {
visibility: ["//frameworks/base"],
}
+filegroup {
+ name: "safetycenter-config-api-sources",
+ srcs: ["java/android/safetycenter/config/*.java"],
+ path: "java",
+ visibility: ["//packages/modules/Permission/SafetyCenter/ConfigLintChecker"],
+}
+
java_library {
name: "framework-permission-s-shared",
srcs: [":framework-permission-s-shared-srcs"],