Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b41b8fd9 authored by Lucas Dupin's avatar Lucas Dupin Committed by Automerger Merge Worker
Browse files

Merge "Hardware bitmap linter" into tm-qpr-dev am: 518b492a am: 8e71e7ed

parents 36a82769 8e71e7ed
Loading
Loading
Loading
Loading
+72 −0
Original line number Original line Diff line number Diff line
/*
 * 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 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.PsiElement
import com.intellij.psi.PsiField
import org.jetbrains.uast.UReferenceExpression

@Suppress("UnstableApiUsage")
class SoftwareBitmapDetector : Detector(), SourceCodeScanner {

    override fun getApplicableReferenceNames(): List<String> {
        return mutableListOf("ALPHA_8", "RGB_565", "ARGB_8888", "RGBA_F16", "RGBA_1010102")
    }

    override fun visitReference(
            context: JavaContext,
            reference: UReferenceExpression,
            referenced: PsiElement
    ) {

        val evaluator = context.evaluator
        if (evaluator.isMemberInClass(referenced as? PsiField, "android.graphics.Bitmap.Config")) {
            context.report(
                    ISSUE,
                    referenced,
                    context.getNameLocation(referenced),
                    "Usage of Config.HARDWARE is highly encouraged."
            )
        }
    }

    companion object {
        @JvmField
        val ISSUE: Issue =
            Issue.create(
                id = "SoftwareBitmapDetector",
                briefDescription = "Software bitmap detected. Please use Config.HARDWARE instead.",
                explanation =
                "Software bitmaps occupy twice as much memory, when compared to Config.HARDWARE. " +
                        "In case you need to manipulate the pixels, please consider to either use" +
                        "a shader (encouraged), or a short lived software bitmap.",
                category = Category.PERFORMANCE,
                priority = 8,
                severity = Severity.WARNING,
                implementation = Implementation(SoftwareBitmapDetector::class.java,
                        Scope.JAVA_FILE_SCOPE)
            )
    }
}
+4 −2
Original line number Original line Diff line number Diff line
@@ -27,10 +27,12 @@ import com.google.auto.service.AutoService
class SystemUIIssueRegistry : IssueRegistry() {
class SystemUIIssueRegistry : IssueRegistry() {


    override val issues: List<Issue>
    override val issues: List<Issue>
        get() = listOf(BindServiceViaContextDetector.ISSUE,
        get() = listOf(
                BindServiceViaContextDetector.ISSUE,
                BroadcastSentViaContextDetector.ISSUE,
                BroadcastSentViaContextDetector.ISSUE,
                GetMainLooperViaContextDetector.ISSUE,
                GetMainLooperViaContextDetector.ISSUE,
                RegisterReceiverViaContextDetector.ISSUE
                RegisterReceiverViaContextDetector.ISSUE,
                SoftwareBitmapDetector.ISSUE,
        )
        )


    override val api: Int
    override val api: Int
+97 −0
Original line number Original line Diff line number Diff line
/*
 * 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 com.android.internal.systemui.lint

import com.android.tools.lint.checks.infrastructure.LintDetectorTest
import com.android.tools.lint.checks.infrastructure.TestFile
import com.android.tools.lint.checks.infrastructure.TestFiles
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

@Suppress("UnstableApiUsage")
class SoftwareBitmapDetectorTest : LintDetectorTest() {

    override fun getDetector(): Detector = SoftwareBitmapDetector()
    override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)

    override fun getIssues(): List<Issue> = listOf(SoftwareBitmapDetector.ISSUE)

    private val explanation = "Usage of Config.HARDWARE is highly encouraged."

    @Test
    fun testSoftwareBitmap() {
        lint().files(
                TestFiles.java(
                        """
                    import android.graphics.Bitmap;

                    public class TestClass1 {
                        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()
                .expectWarningCount(2)
                .expectContains(explanation)
    }

    @Test
    fun testHardwareBitmap() {
        lint().files(
                TestFiles.java(
                        """
                    import android.graphics.Bitmap;

                    public class TestClass1 {
                        public void test() {
                          Bitmap.createBitmap(300, 300, Bitmap.Config.HARDWARE);
                        }
                    }
                """
                ).indented(),
                *stubs)
                .issues(SoftwareBitmapDetector.ISSUE)
                .run()
                .expectWarningCount(0)
    }

    private val bitmapStub: TestFile = java(
            """
        package android.graphics;

        public class Bitmap {
            public enum Config {
                ARGB_8888,
                RGB_565,
                HARDWARE
            }
            public static Bitmap createBitmap(int width, int height, Config config) {
                return null;
            }
        }
        """
    )

    private val stubs = arrayOf(bitmapStub)
}