Add linter to restrict direct usage of registerContentObserver() API.
Forbid direct usage of register/unregister content observer APIs from the ContentResolver class.
Instead direct the caller to use wrapper APIs in SettingsProxy and its sub-classes.
Bug: 353191254
Test: atest RegisterContentObserverViaContentResolverDetectorTest
Flag: NONE new linter check
Change-Id: I50db306d5dc7c2ac6a146586f7d336c32765b462
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/RegisterContentObserverViaContentResolverDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/RegisterContentObserverViaContentResolverDetector.kt
new file mode 100644
index 0000000..8f5cdbf
--- /dev/null
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/RegisterContentObserverViaContentResolverDetector.kt
@@ -0,0 +1,105 @@
+/*
+ * 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 com.android.internal.systemui.lint
+
+import com.android.tools.lint.detector.api.Category
+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.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UClass
+import org.jetbrains.uast.getParentOfType
+
+/**
+ * Checks if registerContentObserver/registerContentObserverAsUser/unregisterContentObserver is
+ * called on a ContentResolver (or subclasses), and directs the caller to using
+ * com.android.systemui.util.settings.SettingsProxy or its sub-classes.
+ */
+@Suppress("UnstableApiUsage")
+class RegisterContentObserverViaContentResolverDetector : Detector(), SourceCodeScanner {
+
+ override fun getApplicableMethodNames(): List<String> {
+ return CONTENT_RESOLVER_METHOD_LIST
+ }
+
+ override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+ val classQualifiedName = node.getParentOfType(UClass::class.java)?.qualifiedName
+ if (classQualifiedName in CLASSNAME_ALLOWLIST) {
+ // Don't warn for class we want the developers to use.
+ return
+ }
+
+ val evaluator = context.evaluator
+ if (evaluator.isMemberInSubClassOf(method, "android.content.ContentResolver")) {
+ context.report(
+ issue = CONTENT_RESOLVER_ERROR,
+ location = context.getNameLocation(node),
+ message =
+ "`ContentResolver.${method.name}()` should be replaced with " +
+ "an appropriate interface API call, for eg. " +
+ "`<SettingsProxy>/<UserSettingsProxy>.${method.name}()`"
+ )
+ }
+ }
+
+ companion object {
+ @JvmField
+ val CONTENT_RESOLVER_ERROR: Issue =
+ Issue.create(
+ id = "RegisterContentObserverViaContentResolver",
+ briefDescription =
+ "Content observer registration done via `ContentResolver`" +
+ "instead of `SettingsProxy or child interfaces.`",
+ // lint trims indents and converts \ to line continuations
+ explanation =
+ """
+ Use registerContentObserver/unregisterContentObserver methods in \
+ `SettingsProxy`, `UserSettingsProxy` or `GlobalSettings` class instead of \
+ using `ContentResolver.registerContentObserver` or \
+ `ContentResolver.unregisterContentObserver`.""",
+ category = Category.PERFORMANCE,
+ priority = 10,
+ severity = Severity.ERROR,
+ implementation =
+ Implementation(
+ RegisterContentObserverViaContentResolverDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+ )
+
+ private val CLASSNAME_ALLOWLIST =
+ listOf(
+ "com.android.systemui.util.settings.SettingsProxy",
+ "com.android.systemui.util.settings.UserSettingsProxy",
+ "com.android.systemui.util.settings.GlobalSettings",
+ "com.android.systemui.util.settings.SecureSettings",
+ "com.android.systemui.util.settings.SystemSettings"
+ )
+
+ private val CONTENT_RESOLVER_METHOD_LIST =
+ listOf(
+ "registerContentObserver",
+ "registerContentObserverAsUser",
+ "unregisterContentObserver"
+ )
+ }
+}
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
index 5206b05..a1f4f55 100644
--- a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
@@ -46,7 +46,8 @@
DemotingTestWithoutBugDetector.ISSUE,
TestFunctionNameViolationDetector.ISSUE,
MissingApacheLicenseDetector.ISSUE,
- RegisterContentObserverSyncViaSettingsProxyDetector.SYNC_WARNING
+ RegisterContentObserverSyncViaSettingsProxyDetector.SYNC_WARNING,
+ RegisterContentObserverViaContentResolverDetector.CONTENT_RESOLVER_ERROR
)
override val api: Int
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/RegisterContentObserverViaContentResolverDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/RegisterContentObserverViaContentResolverDetectorTest.kt
new file mode 100644
index 0000000..1d33bce
--- /dev/null
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/RegisterContentObserverViaContentResolverDetectorTest.kt
@@ -0,0 +1,207 @@
+/*
+ * 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 com.android.internal.systemui.lint
+
+import com.android.tools.lint.checks.infrastructure.TestFiles
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+
+class RegisterContentObserverViaContentResolverDetectorTest : SystemUILintDetectorTest() {
+
+ override fun getDetector(): Detector = RegisterContentObserverViaContentResolverDetector()
+
+ override fun getIssues(): List<Issue> =
+ listOf(RegisterContentObserverViaContentResolverDetector.CONTENT_RESOLVER_ERROR)
+
+ @Test
+ fun testRegisterContentObserver_throwError() {
+ lint()
+ .files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.content.Context;
+
+ public class TestClass {
+ public void register(Context context) {
+ context.getContentResolver().
+ registerContentObserver(Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+ false, mSettingObserver);
+ }
+ }
+ """
+ )
+ .indented(),
+ *androidStubs
+ )
+ .issues(RegisterContentObserverViaContentResolverDetector.CONTENT_RESOLVER_ERROR)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:7: Error: ContentResolver.registerContentObserver() should be replaced with an appropriate interface API call, for eg. <SettingsProxy>/<UserSettingsProxy>.registerContentObserver() [RegisterContentObserverViaContentResolver]
+ registerContentObserver(Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ 1 errors, 0 warnings
+ """
+ .trimIndent()
+ )
+ }
+
+ @Test
+ fun testRegisterContentObserverForUser_throwError() {
+ lint()
+ .files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.content.Context;
+
+ public class TestClass {
+ public void register(Context context) {
+ context.getContentResolver().
+ registerContentObserverAsUser(Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+ false, mSettingObserver);
+ }
+ }
+ """
+ )
+ .indented(),
+ *androidStubs
+ )
+ .issues(RegisterContentObserverViaContentResolverDetector.CONTENT_RESOLVER_ERROR)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:7: Error: ContentResolver.registerContentObserverAsUser() should be replaced with an appropriate interface API call, for eg. <SettingsProxy>/<UserSettingsProxy>.registerContentObserverAsUser() [RegisterContentObserverViaContentResolver]
+ registerContentObserverAsUser(Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+1 errors, 0 warnings
+ """
+ .trimIndent()
+ )
+ }
+
+ @Test
+ fun testSuppressRegisterContentObserver() {
+ lint()
+ .files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.content.Context;
+
+ public class TestClass {
+ @SuppressWarnings("RegisterContentObserverViaContentResolver")
+ public void register(Context context) {
+ context.getContentResolver().
+ registerContentObserver(Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+ false, mSettingObserver);
+ }
+ }
+ """
+ )
+ .indented(),
+ *androidStubs
+ )
+ .issues(RegisterContentObserverViaContentResolverDetector.CONTENT_RESOLVER_ERROR)
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun testRegisterContentObserverInSettingsProxy_allowed() {
+ lint()
+ .files(
+ TestFiles.java(
+ """
+ package com.android.systemui.util.settings;
+ import android.content.Context;
+
+ public class SettingsProxy {
+ public void register(Context context) {
+ context.getContentResolver().
+ registerContentObserver(Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+ false, mSettingObserver);
+ }
+ }
+ """
+ )
+ .indented(),
+ *androidStubs
+ )
+ .issues(RegisterContentObserverViaContentResolverDetector.CONTENT_RESOLVER_ERROR)
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun testNoopIfNoCall() {
+ lint()
+ .files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.content.Context;
+
+ public class SettingsProxy {
+ public void register(Context context) {
+ }
+ }
+ """
+ )
+ .indented(),
+ *androidStubs
+ )
+ .issues(RegisterContentObserverViaContentResolverDetector.CONTENT_RESOLVER_ERROR)
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun testUnRegisterContentObserver_throwError() {
+ lint()
+ .files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.content.Context;
+
+ public class TestClass {
+ public void register(Context context) {
+ context.getContentResolver().
+ unregisterContentObserver(mSettingObserver);
+ }
+ }
+ """
+ )
+ .indented(),
+ *androidStubs
+ )
+ .issues(RegisterContentObserverViaContentResolverDetector.CONTENT_RESOLVER_ERROR)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:7: Error: ContentResolver.unregisterContentObserver() should be replaced with an appropriate interface API call, for eg. <SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver() [RegisterContentObserverViaContentResolver]
+ unregisterContentObserver(mSettingObserver);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ 1 errors, 0 warnings
+ """
+ .trimIndent()
+ )
+ }
+}
diff --git a/packages/SystemUI/lint-baseline.xml b/packages/SystemUI/lint-baseline.xml
index b4c839f..7577147 100644
--- a/packages/SystemUI/lint-baseline.xml
+++ b/packages/SystemUI/lint-baseline.xml
@@ -32157,4 +32157,631 @@
column="6"/>
</issue>
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" contentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt"
+ line="154"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" resolver.registerContentObserver(ALWAYS_ON_DISPLAY_CONSTANTS_URI,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java"
+ line="164"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" resolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/util/animation/data/repository/AnimationStatusRepository.kt"
+ line="61"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" awaitClose { resolver.unregisterContentObserver(observer) }"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/util/animation/data/repository/AnimationStatusRepository.kt"
+ line="67"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContentResolver.unregisterContentObserver(mSettingObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java"
+ line="123"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContentResolver.unregisterContentObserver(mSettingObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java"
+ line="180"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java"
+ line="211"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java"
+ line="219"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" resolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt"
+ line="46"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" resolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt"
+ line="48"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" resolver.unregisterContentObserver(allowedObserver)"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt"
+ line="54"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" resolver.unregisterContentObserver(onObserver)"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt"
+ line="55"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" resolver.registerContentObserver(mQuickPickupGesture, false, this,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java"
+ line="511"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" resolver.registerContentObserver(mPickupGesture, false, this, UserHandle.USER_ALL);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java"
+ line="513"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" resolver.registerContentObserver(mAlwaysOnEnabled, false, this,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java"
+ line="514"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContext.getContentResolver().registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java"
+ line="2470"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContext.getContentResolver().registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java"
+ line="3077"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java"
+ line="3168"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java"
+ line="3957"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContext.getContentResolver().unregisterContentObserver(mTimeFormatChangeObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java"
+ line="3961"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" contentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt"
+ line="486"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" contentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt"
+ line="492"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" contentResolver.unregisterContentObserver(settingsObserver)"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt"
+ line="543"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" contentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenTargetFilter.kt"
+ line="82"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" contentResolver.unregisterContentObserver(settingsObserver)"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenTargetFilter.kt"
+ line="100"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContext.getContentResolver().unregisterContentObserver(mMenuTargetFeaturesContentObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java"
+ line="275"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContext.getContentResolver().unregisterContentObserver(mMenuSizeContentObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java"
+ line="276"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContext.getContentResolver().unregisterContentObserver(mMenuFadeOutContentObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java"
+ line="277"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContext.getContentResolver().registerContentObserver(Global.getUriFor(Global.MOBILE_DATA),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java"
+ line="200"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContext.getContentResolver().registerContentObserver(Global.getUriFor("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java"
+ line="202"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContext.getContentResolver().unregisterContentObserver(mObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java"
+ line="212"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" context.contentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NaturalScrollingSettingObserver.kt"
+ line="54"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java"
+ line="253"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java"
+ line="256"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java"
+ line="259"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java"
+ line="262"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContentResolver.unregisterContentObserver(mAssistContentObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java"
+ line="295"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContext.getContentResolver().registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java"
+ line="395"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContext.getContentResolver().registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java"
+ line="400"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java"
+ line="3675"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContentResolver.unregisterContentObserver(mSettingsChangeObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java"
+ line="4705"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" resolver.registerContentObserver(Settings.Global.getUriFor("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerUI.java"
+ line="191"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" resolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerUI.java"
+ line="205"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" resolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerUI.java"
+ line="216"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContext.getContentResolver().registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java"
+ line="178"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContext.getContentResolver().unregisterContentObserver(mDeveloperSettingsObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java"
+ line="186"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContentResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/accessibility/SecureSettingsContentObserver.java"
+ line="83"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContentResolver.unregisterContentObserver(mContentObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/accessibility/SecureSettingsContentObserver.java"
+ line="100"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContentResolver.registerContentObserver(uri, false, mObserver, mCurrentUser);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java"
+ line="219"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContentResolver.unregisterContentObserver(mObserver);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java"
+ line="241"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContentResolver.registerContentObserver(uri, false, mObserver, mCurrentUser);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java"
+ line="243"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContext.getContentResolver().registerContentObserver(ZEN_MODE_URI, false, this);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java"
+ line="1235"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mContext.getContentResolver().registerContentObserver(ZEN_MODE_CONFIG_URI, false, this);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java"
+ line="1236"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mContext.getContentResolver().unregisterContentObserver(this);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java"
+ line="1240"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.unregisterContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.unregisterContentObserver()`"
+ errorLine1=" mResolver.unregisterContentObserver(this);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java"
+ line="377"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java"
+ line="379"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="RegisterContentObserverViaContentResolver"
+ message="`ContentResolver.registerContentObserver()` should be replaced with an appropriate interface API call, for eg.`<SettingsProxy>/<UserSettingsProxy>.registerContentObserver()`"
+ errorLine1=" mResolver.registerContentObserver("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java"
+ line="381"
+ column="23"/>
+ </issue>
+
</issues>