summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Giulio Fiscella <fiscella@google.com> 2022-04-06 10:17:31 +0000
committer Giulio Fiscella <fiscella@google.com> 2022-04-07 00:10:48 +0000
commit17bdb43b6d79e7550bcfff7eba0f0dc1d947702a (patch)
tree9742fd953e895bed4452d0f363c6c43ba90dbdbf
parent9fc61018e915e3474a860585dcac290fafd262bc (diff)
Add schema validation to custom lint check
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: Ia778bb86b33e0aeabc3c0949aa51d7c418df4024
-rw-r--r--SafetyCenter/ConfigLintChecker/Android.bp1
-rw-r--r--SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigLintCheckerIssueRegistry.kt1
-rw-r--r--SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigSchemaDetector.kt86
-rw-r--r--SafetyCenter/ConfigLintChecker/tests/java/android/safetycenter/lint/test/ConfigSchemaDetectorTest.kt79
-rw-r--r--framework-s/Android.bp7
-rw-r--r--framework-s/java/android/safetycenter/config/safety_center_config.xsd (renamed from SafetyCenter/Config/safety_center_config.xsd)16
6 files changed, 182 insertions, 8 deletions
diff --git a/SafetyCenter/ConfigLintChecker/Android.bp b/SafetyCenter/ConfigLintChecker/Android.bp
index 4b5053f19..0206af797 100644
--- a/SafetyCenter/ConfigLintChecker/Android.bp
+++ b/SafetyCenter/ConfigLintChecker/Android.bp
@@ -33,6 +33,7 @@ java_library_host {
"layoutlib_api-prebuilt", // For com.android.resources.ResourceFolderType
"lint_api",
],
+ java_resources: [":safetycenter-config-schema"],
jarjar_rules: "jarjar-rules.txt",
}
diff --git a/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigLintCheckerIssueRegistry.kt b/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigLintCheckerIssueRegistry.kt
index 536769160..8b9148dfb 100644
--- a/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigLintCheckerIssueRegistry.kt
+++ b/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigLintCheckerIssueRegistry.kt
@@ -25,6 +25,7 @@ import com.google.auto.service.AutoService
@Suppress("UnstableApiUsage")
class ConfigLintCheckerIssueRegistry : IssueRegistry() {
override val issues = listOf(
+ ConfigSchemaDetector.ISSUE,
ParserExceptionDetector.ISSUE
)
diff --git a/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigSchemaDetector.kt b/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigSchemaDetector.kt
new file mode 100644
index 000000000..ed58e5341
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/java/android/safetycenter/lint/ConfigSchemaDetector.kt
@@ -0,0 +1,86 @@
+/*
+ * 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.resources.ResourceFolderType
+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
+import java.io.IOException
+import javax.xml.XMLConstants
+import javax.xml.transform.stream.StreamSource
+import javax.xml.validation.SchemaFactory
+import org.xml.sax.SAXException
+
+/** Lint check for detecting invalid Safety Center configs */
+class ConfigSchemaDetector : Detector(), OtherFileScanner {
+
+ companion object {
+ val ISSUE = Issue.create(
+ id = "InvalidSafetyCenterConfigSchema",
+ briefDescription = "The Safety Center config does not meet the schema requirements",
+ explanation = """The Safety Center config must follow all constraints defined in \
+ safety_center_config.xsd. Either the config is invalid or the schema is not up to
+ date.""",
+ category = Category.CORRECTNESS,
+ severity = Severity.ERROR,
+ implementation = Implementation(
+ ConfigSchemaDetector::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
+ }
+ val xsd = StreamSource(
+ ConfigSchemaDetector::class.java.getResourceAsStream("/safety_center_config.xsd")
+ )
+ val xml = StreamSource(context.file.inputStream())
+ val schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
+ try {
+ val schema = schemaFactory.newSchema(xsd)
+ val validator = schema.newValidator()
+ validator.validate(xml)
+ } catch (e: SAXException) {
+ context.report(
+ ISSUE,
+ Location.create(context.file),
+ e.message!!
+ )
+ } catch (e: IOException) {
+ context.report(
+ ISSUE,
+ Location.create(context.file),
+ e.message!!
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/SafetyCenter/ConfigLintChecker/tests/java/android/safetycenter/lint/test/ConfigSchemaDetectorTest.kt b/SafetyCenter/ConfigLintChecker/tests/java/android/safetycenter/lint/test/ConfigSchemaDetectorTest.kt
new file mode 100644
index 000000000..0dd4afbd2
--- /dev/null
+++ b/SafetyCenter/ConfigLintChecker/tests/java/android/safetycenter/lint/test/ConfigSchemaDetectorTest.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.ConfigSchemaDetector
+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 ConfigSchemaDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector = ConfigSchemaDetector()
+
+ override fun getIssues(): List<Issue> = listOf(ConfigSchemaDetector.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: cvc-elt.1.a: Cannot find the " +
+ "declaration of element 'invalid-root'. [InvalidSafetyCenterConfigSchema]\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/framework-s/Android.bp b/framework-s/Android.bp
index 6be71d416..ec33f13ee 100644
--- a/framework-s/Android.bp
+++ b/framework-s/Android.bp
@@ -33,6 +33,13 @@ filegroup {
visibility: ["//packages/modules/Permission/SafetyCenter/ConfigLintChecker"],
}
+filegroup {
+ name: "safetycenter-config-schema",
+ srcs: ["java/android/safetycenter/config/safety_center_config.xsd"],
+ path: "java/android/safetycenter/config/",
+ visibility: ["//packages/modules/Permission/SafetyCenter/ConfigLintChecker"],
+}
+
java_library {
name: "framework-permission-s-shared",
srcs: [":framework-permission-s-shared-srcs"],
diff --git a/SafetyCenter/Config/safety_center_config.xsd b/framework-s/java/android/safetycenter/config/safety_center_config.xsd
index 5a3576dd5..1c5590c58 100644
--- a/SafetyCenter/Config/safety_center_config.xsd
+++ b/framework-s/java/android/safetycenter/config/safety_center_config.xsd
@@ -54,13 +54,13 @@
<xsd:attribute name="packageName" type="xsd:string" use="required"/>
<!-- title is required if initialDisplayState is not set to hidden -->
<!-- title is prohibited if initialDisplayState is set to hidden -->
- <xsd:attribute name="title" type="xsd:string"/>
+ <xsd:attribute name="title" type="stringResourceName"/>
<!-- titleForWork is required if profile is set to all_profiles and initialDisplayState is not set to hidden -->
<!-- titleForWork is prohibited if profile is set to primary_profile_only or initialDisplayState is set to hidden -->
- <xsd:attribute name="titleForWork" type="xsd:string"/>
+ <xsd:attribute name="titleForWork" type="stringResourceName"/>
<!-- summary is required if initialDisplayState is not set to hidden -->
<!-- summary is prohibited if initialDisplayState is set to hidden -->
- <xsd:attribute name="summary" type="xsd:string"/>
+ <xsd:attribute name="summary" type="stringResourceName"/>
<!-- intentAction is required if initialDisplayState is set to enabled -->
<!-- intentAction is optional if initialDisplayState is set to disabled -->
<!-- intentAction is prohibited if initialDisplayState is set to hidden -->
@@ -68,7 +68,7 @@
<xsd:attribute name="profile" type="profile" use="required"/>
<xsd:attribute name="initialDisplayState" type="initialDisplayState" default="enabled"/>
<xsd:attribute name="maxSeverityLevel" type="xsd:int" default="2147483647"/>
- <xsd:attribute name="searchTerms" type="xsd:string"/>
+ <xsd:attribute name="searchTerms" type="stringResourceName"/>
<xsd:attribute name="loggingAllowed" type="xsd:boolean" default="true"/>
<xsd:attribute name="refreshOnPageOpenAllowed" type="xsd:boolean" default="false"/>
</xsd:complexType>
@@ -86,14 +86,14 @@
<xsd:complexType name="static-safety-source">
<!-- id must be unique among safety sources -->
<xsd:attribute name="id" type="xsd:string" use="required"/>
- <xsd:attribute name="title" type="xsd:string" use="required"/>
+ <xsd:attribute name="title" type="stringResourceName" use="required"/>
<!-- titleForWork is required if profile is set to all_profiles -->
<!-- titleForWork is prohibited if profile is set to primary_profile_only -->
- <xsd:attribute name="titleForWork" type="xsd:string"/>
- <xsd:attribute name="summary" type="xsd:string" use="required"/>
+ <xsd:attribute name="titleForWork" type="stringResourceName"/>
+ <xsd:attribute name="summary" type="stringResourceName" use="required"/>
<xsd:attribute name="intentAction" type="xsd:string" use="required"/>
<xsd:attribute name="profile" type="profile" use="required"/>
- <xsd:attribute name="searchTerms" type="xsd:string"/>
+ <xsd:attribute name="searchTerms" type="stringResourceName"/>
</xsd:complexType>
<xsd:simpleType name="statelessIconType">