Merge "Support lint suppression" into tm-qpr-dev am: a006b9f853

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20498075

Change-Id: I7bf72b7ba82832670dbce6cfe4642263a31c53f5
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Peter Kalauskas
2022-11-17 16:27:56 +00:00
committed by Automerger Merge Worker
16 changed files with 255 additions and 44 deletions

View File

@@ -59,9 +59,9 @@ class BindServiceOnMainThreadDetector : Detector(), SourceCodeScanner {
!hasWorkerThreadAnnotation(context, node.getParentOfType(UClass::class.java)) !hasWorkerThreadAnnotation(context, node.getParentOfType(UClass::class.java))
) { ) {
context.report( context.report(
ISSUE, issue = ISSUE,
method, location = context.getLocation(node),
context.getLocation(node), message =
"This method should be annotated with `@WorkerThread` because " + "This method should be annotated with `@WorkerThread` because " +
"it calls ${method.name}", "it calls ${method.name}",
) )

View File

@@ -52,10 +52,9 @@ class BroadcastSentViaContextDetector : Detector(), SourceCodeScanner {
val evaluator = context.evaluator val evaluator = context.evaluator
if (evaluator.isMemberInSubClassOf(method, CLASS_CONTEXT)) { if (evaluator.isMemberInSubClassOf(method, CLASS_CONTEXT)) {
context.report( context.report(
ISSUE, issue = ISSUE,
method, location = context.getNameLocation(node),
context.getNameLocation(node), message = "`Context.${method.name}()` should be replaced with " +
"`Context.${method.name}()` should be replaced with " +
"`BroadcastSender.${method.name}()`" "`BroadcastSender.${method.name}()`"
) )
} }

View File

@@ -38,10 +38,9 @@ class NonInjectedMainThreadDetector : Detector(), SourceCodeScanner {
override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) { override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
if (context.evaluator.isMemberInSubClassOf(method, CLASS_CONTEXT)) { if (context.evaluator.isMemberInSubClassOf(method, CLASS_CONTEXT)) {
context.report( context.report(
ISSUE, issue = ISSUE,
method, location = context.getNameLocation(node),
context.getNameLocation(node), message = "Replace with injected `@Main Executor`."
"Replace with injected `@Main Executor`."
) )
} }
} }

View File

@@ -44,9 +44,9 @@ class NonInjectedServiceDetector : Detector(), SourceCodeScanner {
method.containingClass?.qualifiedName == CLASS_CONTEXT method.containingClass?.qualifiedName == CLASS_CONTEXT
) { ) {
context.report( context.report(
ISSUE, issue = ISSUE,
method, location = context.getNameLocation(node),
context.getNameLocation(node), message =
"Use `@Inject` to get system-level service handles instead of " + "Use `@Inject` to get system-level service handles instead of " +
"`Context.getSystemService()`" "`Context.getSystemService()`"
) )
@@ -56,9 +56,9 @@ class NonInjectedServiceDetector : Detector(), SourceCodeScanner {
method.containingClass?.qualifiedName == "android.accounts.AccountManager" method.containingClass?.qualifiedName == "android.accounts.AccountManager"
) { ) {
context.report( context.report(
ISSUE, issue = ISSUE,
method, location = context.getNameLocation(node),
context.getNameLocation(node), message =
"Replace `AccountManager.get()` with an injected instance of `AccountManager`" "Replace `AccountManager.get()` with an injected instance of `AccountManager`"
) )
} }

View File

@@ -38,10 +38,10 @@ class RegisterReceiverViaContextDetector : Detector(), SourceCodeScanner {
override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) { override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
if (context.evaluator.isMemberInSubClassOf(method, CLASS_CONTEXT)) { if (context.evaluator.isMemberInSubClassOf(method, CLASS_CONTEXT)) {
context.report( context.report(
ISSUE, issue = ISSUE,
method, location = context.getNameLocation(node),
context.getNameLocation(node), message = "Register `BroadcastReceiver` using `BroadcastDispatcher` instead " +
"Register `BroadcastReceiver` using `BroadcastDispatcher` instead of `Context`" "of `Context`"
) )
} }
} }

View File

@@ -46,9 +46,9 @@ class SlowUserQueryDetector : Detector(), SourceCodeScanner {
method.containingClass?.qualifiedName == "android.app.ActivityManager" method.containingClass?.qualifiedName == "android.app.ActivityManager"
) { ) {
context.report( context.report(
ISSUE_SLOW_USER_ID_QUERY, issue = ISSUE_SLOW_USER_ID_QUERY,
method, location = context.getNameLocation(node),
context.getNameLocation(node), message =
"Use `UserTracker.getUserId()` instead of `ActivityManager.getCurrentUser()`" "Use `UserTracker.getUserId()` instead of `ActivityManager.getCurrentUser()`"
) )
} }
@@ -58,10 +58,9 @@ class SlowUserQueryDetector : Detector(), SourceCodeScanner {
method.containingClass?.qualifiedName == "android.os.UserManager" method.containingClass?.qualifiedName == "android.os.UserManager"
) { ) {
context.report( context.report(
ISSUE_SLOW_USER_INFO_QUERY, issue = ISSUE_SLOW_USER_INFO_QUERY,
method, location = context.getNameLocation(node),
context.getNameLocation(node), message = "Use `UserTracker.getUserInfo()` instead of `UserManager.getUserInfo()`"
"Use `UserTracker.getUserInfo()` instead of `UserManager.getUserInfo()`"
) )
} }
} }

View File

@@ -44,10 +44,9 @@ class SoftwareBitmapDetector : Detector(), SourceCodeScanner {
val evaluator = context.evaluator val evaluator = context.evaluator
if (evaluator.isMemberInClass(referenced as? PsiField, "android.graphics.Bitmap.Config")) { if (evaluator.isMemberInClass(referenced as? PsiField, "android.graphics.Bitmap.Config")) {
context.report( context.report(
ISSUE, issue = ISSUE,
referenced, location = context.getNameLocation(reference),
context.getNameLocation(reference), message = "Replace software bitmap with `Config.HARDWARE`"
"Replace software bitmap with `Config.HARDWARE`"
) )
} }
} }

View File

@@ -66,10 +66,9 @@ class StaticSettingsProviderDetector : Detector(), SourceCodeScanner {
val subclassName = className.substring(CLASS_SETTINGS.length + 1) val subclassName = className.substring(CLASS_SETTINGS.length + 1)
context.report( context.report(
ISSUE, issue = ISSUE,
method, location = context.getNameLocation(node),
context.getNameLocation(node), message = "`@Inject` a ${subclassName}Settings instead"
"`@Inject` a ${subclassName}Settings instead"
) )
} }

View File

@@ -125,6 +125,32 @@ class BindServiceOnMainThreadDetectorTest : SystemUILintDetectorTest() {
) )
} }
@Test
fun testSuppressUnbindService() {
lint()
.files(
TestFiles.java(
"""
package test.pkg;
import android.content.Context;
import android.content.ServiceConnection;
@SuppressLint("BindServiceOnMainThread")
public class TestClass {
public void unbind(Context context, ServiceConnection connection) {
context.unbindService(connection);
}
}
"""
)
.indented(),
*stubs
)
.issues(BindServiceOnMainThreadDetector.ISSUE)
.run()
.expectClean()
}
@Test @Test
fun testWorkerMethod() { fun testWorkerMethod() {
lint() lint()

View File

@@ -128,6 +128,34 @@ class BroadcastSentViaContextDetectorTest : SystemUILintDetectorTest() {
) )
} }
@Test
fun testSuppressSendBroadcastInActivity() {
lint()
.files(
TestFiles.java(
"""
package test.pkg;
import android.app.Activity;
import android.os.UserHandle;
public class TestClass {
@SuppressWarnings("BroadcastSentViaContext")
public void send(Activity activity) {
Intent intent = new Intent(Intent.ACTION_VIEW);
activity.sendBroadcastAsUser(intent, UserHandle.ALL, "permission");
}
}
"""
)
.indented(),
*stubs
)
.issues(BroadcastSentViaContextDetector.ISSUE)
.run()
.expectClean()
}
@Test @Test
fun testSendBroadcastInBroadcastSender() { fun testSendBroadcastInBroadcastSender() {
lint() lint()

View File

@@ -60,6 +60,32 @@ class NonInjectedMainThreadDetectorTest : SystemUILintDetectorTest() {
) )
} }
@Test
fun testSuppressGetMainThreadHandler() {
lint()
.files(
TestFiles.java(
"""
package test.pkg;
import android.content.Context;
import android.os.Handler;
@SuppressWarnings("NonInjectedMainThread")
public class TestClass {
public void test(Context context) {
Handler mainThreadHandler = context.getMainThreadHandler();
}
}
"""
)
.indented(),
*stubs
)
.issues(NonInjectedMainThreadDetector.ISSUE)
.run()
.expectClean()
}
@Test @Test
fun testGetMainLooper() { fun testGetMainLooper() {
lint() lint()

View File

@@ -90,6 +90,32 @@ class NonInjectedServiceDetectorTest : SystemUILintDetectorTest() {
) )
} }
@Test
fun testSuppressGetServiceWithClass() {
lint()
.files(
TestFiles.java(
"""
package test.pkg;
import android.content.Context;
import android.os.UserManager;
public class TestClass {
@SuppressLint("NonInjectedService")
public void getSystemServiceWithoutDagger(Context context) {
context.getSystemService(UserManager.class);
}
}
"""
)
.indented(),
*stubs
)
.issues(NonInjectedServiceDetector.ISSUE)
.run()
.expectClean()
}
@Test @Test
fun testGetAccountManager() { fun testGetAccountManager() {
lint() lint()

View File

@@ -62,6 +62,34 @@ class RegisterReceiverViaContextDetectorTest : SystemUILintDetectorTest() {
) )
} }
@Test
fun testSuppressRegisterReceiver() {
lint()
.files(
TestFiles.java(
"""
package test.pkg;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
@SuppressWarnings("RegisterReceiverViaContext")
public class TestClass {
public void bind(Context context, BroadcastReceiver receiver,
IntentFilter filter) {
context.registerReceiver(receiver, filter, 0);
}
}
"""
)
.indented(),
*stubs
)
.issues(RegisterReceiverViaContextDetector.ISSUE)
.run()
.expectClean()
}
@Test @Test
fun testRegisterReceiverAsUser() { fun testRegisterReceiverAsUser() {
lint() lint()

View File

@@ -76,7 +76,7 @@ class SlowUserQueryDetectorTest : SystemUILintDetectorTest() {
import android.os.UserManager; import android.os.UserManager;
public class TestClass { public class TestClass {
public void slewlyGetUserInfo(UserManager userManager) { public void slowlyGetUserInfo(UserManager userManager) {
userManager.getUserInfo(); userManager.getUserInfo();
} }
} }
@@ -100,6 +100,34 @@ class SlowUserQueryDetectorTest : SystemUILintDetectorTest() {
) )
} }
@Test
fun testSuppressGetUserInfo() {
lint()
.files(
TestFiles.java(
"""
package test.pkg;
import android.os.UserManager;
public class TestClass {
@SuppressWarnings("SlowUserInfoQuery")
public void slowlyGetUserInfo(UserManager userManager) {
userManager.getUserInfo();
}
}
"""
)
.indented(),
*stubs
)
.issues(
SlowUserQueryDetector.ISSUE_SLOW_USER_ID_QUERY,
SlowUserQueryDetector.ISSUE_SLOW_USER_INFO_QUERY
)
.run()
.expectClean()
}
@Test @Test
fun testUserTrackerGetUserId() { fun testUserTrackerGetUserId() {
lint() lint()

View File

@@ -62,6 +62,31 @@ class SoftwareBitmapDetectorTest : SystemUILintDetectorTest() {
) )
} }
@Test
fun testSuppressSoftwareBitmap() {
lint()
.files(
TestFiles.java(
"""
import android.graphics.Bitmap;
@SuppressWarnings("SoftwareBitmap")
public class TestClass {
public void test() {
Bitmap.createBitmap(300, 300, Bitmap.Config.RGB_565);
Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
}
}
"""
)
.indented(),
*stubs
)
.issues(SoftwareBitmapDetector.ISSUE)
.run()
.expectClean()
}
@Test @Test
fun testHardwareBitmap() { fun testHardwareBitmap() {
lint() lint()

View File

@@ -28,7 +28,7 @@ class StaticSettingsProviderDetectorTest : SystemUILintDetectorTest() {
override fun getIssues(): List<Issue> = listOf(StaticSettingsProviderDetector.ISSUE) override fun getIssues(): List<Issue> = listOf(StaticSettingsProviderDetector.ISSUE)
@Test @Test
fun testGetServiceWithString() { fun testSuppressGetServiceWithString() {
lint() lint()
.files( .files(
TestFiles.java( TestFiles.java(
@@ -204,5 +204,34 @@ class StaticSettingsProviderDetectorTest : SystemUILintDetectorTest() {
) )
} }
@Test
fun testGetServiceWithString() {
lint()
.files(
TestFiles.java(
"""
package test.pkg;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
public class TestClass {
@SuppressWarnings("StaticSettingsProvider")
public void getSystemServiceWithoutDagger(Context context) {
final ContentResolver cr = mContext.getContentResolver();
Global.getFloat(cr, Settings.Global.UNLOCK_SOUND);
}
}
"""
)
.indented(),
*stubs
)
.issues(StaticSettingsProviderDetector.ISSUE)
.run()
.expectClean()
}
private val stubs = androidStubs private val stubs = androidStubs
} }