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

Commit 723997f1 authored by Chris Göllner's avatar Chris Göllner Committed by Android (Google) Code Review
Browse files

Merge "Extract loading of camera protection info into a separate class" into main

parents 02e5c2e9 6bc000a9
Loading
Loading
Loading
Loading
+6 −79
Original line number Diff line number Diff line
@@ -17,15 +17,11 @@
package com.android.systemui

import android.content.Context
import android.content.res.Resources
import android.graphics.Path
import android.graphics.Rect
import android.graphics.RectF
import android.hardware.camera2.CameraManager
import android.util.PathParser
import com.android.systemui.res.R
import java.util.concurrent.Executor
import kotlin.math.roundToInt

/**
 * Listens for usage of the Camera and controls the ScreenDecorations transition to show extra
@@ -163,89 +159,20 @@ class CameraAvailabilityListener(
    }

    companion object Factory {
        fun build(context: Context, executor: Executor): CameraAvailabilityListener {
        fun build(
            context: Context,
            executor: Executor,
            cameraProtectionLoader: CameraProtectionLoader
        ): CameraAvailabilityListener {
            val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
            val res = context.resources
            val cameraProtectionInfoList = loadCameraProtectionInfoList(res)
            val cameraProtectionInfoList = cameraProtectionLoader.loadCameraProtectionInfoList()
            val excluded = res.getString(R.string.config_cameraProtectionExcludedPackages)

            return CameraAvailabilityListener(manager, cameraProtectionInfoList, excluded, executor)
        }

        private fun pathFromString(pathString: String): Path {
            val spec = pathString.trim()
            val p: Path
            try {
                p = PathParser.createPathFromPathData(spec)
            } catch (e: Throwable) {
                throw IllegalArgumentException("Invalid protection path", e)
            }

            return p
    }

        private fun loadCameraProtectionInfoList(res: Resources): List<CameraProtectionInfo> {
            val list = mutableListOf<CameraProtectionInfo>()
            val front =
                loadCameraProtectionInfo(
                    res,
                    R.string.config_protectedCameraId,
                    R.string.config_protectedPhysicalCameraId,
                    R.string.config_frontBuiltInDisplayCutoutProtection
                )
            if (front != null) {
                list.add(front)
            }
            val inner =
                loadCameraProtectionInfo(
                    res,
                    R.string.config_protectedInnerCameraId,
                    R.string.config_protectedInnerPhysicalCameraId,
                    R.string.config_innerBuiltInDisplayCutoutProtection
                )
            if (inner != null) {
                list.add(inner)
            }
            return list
        }

        private fun loadCameraProtectionInfo(
            res: Resources,
            cameraIdRes: Int,
            physicalCameraIdRes: Int,
            pathRes: Int
        ): CameraProtectionInfo? {
            val logicalCameraId = res.getString(cameraIdRes)
            if (logicalCameraId.isNullOrEmpty()) {
                return null
            }
            val physicalCameraId = res.getString(physicalCameraIdRes)
            val protectionPath = pathFromString(res.getString(pathRes))
            val computed = RectF()
            protectionPath.computeBounds(computed)
            val protectionBounds =
                Rect(
                    computed.left.roundToInt(),
                    computed.top.roundToInt(),
                    computed.right.roundToInt(),
                    computed.bottom.roundToInt()
                )
            return CameraProtectionInfo(
                logicalCameraId,
                physicalCameraId,
                protectionPath,
                protectionBounds
            )
        }
    }

    data class CameraProtectionInfo(
        val logicalCameraId: String,
        val physicalCameraId: String?,
        val cutoutProtectionPath: Path,
        val cutoutBounds: Rect,
    )

    private data class OpenCameraInfo(
        val logicalCameraId: String,
        val packageId: String,
+27 −0
Original line number Diff line number Diff line
/*
 * 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.systemui

import android.graphics.Path
import android.graphics.Rect

data class CameraProtectionInfo(
    val logicalCameraId: String,
    val physicalCameraId: String?,
    val cutoutProtectionPath: Path,
    val cutoutBounds: Rect,
)
+88 −0
Original line number Diff line number Diff line
/*
 * 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.systemui

import android.content.Context
import android.graphics.Path
import android.graphics.Rect
import android.graphics.RectF
import android.util.PathParser
import com.android.systemui.res.R
import javax.inject.Inject
import kotlin.math.roundToInt

class CameraProtectionLoader @Inject constructor(private val context: Context) {

    fun loadCameraProtectionInfoList(): List<CameraProtectionInfo> {
        val list = mutableListOf<CameraProtectionInfo>()
        val front =
            loadCameraProtectionInfo(
                R.string.config_protectedCameraId,
                R.string.config_protectedPhysicalCameraId,
                R.string.config_frontBuiltInDisplayCutoutProtection
            )
        if (front != null) {
            list.add(front)
        }
        val inner =
            loadCameraProtectionInfo(
                R.string.config_protectedInnerCameraId,
                R.string.config_protectedInnerPhysicalCameraId,
                R.string.config_innerBuiltInDisplayCutoutProtection
            )
        if (inner != null) {
            list.add(inner)
        }
        return list
    }

    private fun loadCameraProtectionInfo(
        cameraIdRes: Int,
        physicalCameraIdRes: Int,
        pathRes: Int
    ): CameraProtectionInfo? {
        val logicalCameraId = context.getString(cameraIdRes)
        if (logicalCameraId.isNullOrEmpty()) {
            return null
        }
        val physicalCameraId = context.getString(physicalCameraIdRes)
        val protectionPath = pathFromString(context.getString(pathRes))
        val computed = RectF()
        protectionPath.computeBounds(computed)
        val protectionBounds =
            Rect(
                computed.left.roundToInt(),
                computed.top.roundToInt(),
                computed.right.roundToInt(),
                computed.bottom.roundToInt()
            )
        return CameraProtectionInfo(
            logicalCameraId,
            physicalCameraId,
            protectionPath,
            protectionBounds
        )
    }

    private fun pathFromString(pathString: String): Path {
        return try {
            PathParser.createPathFromPathData(pathString.trim())
        } catch (e: Throwable) {
            throw IllegalArgumentException("Invalid protection path", e)
        }
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ public class ScreenDecorations implements
    private final ThreadFactory mThreadFactory;
    private final DecorProviderFactory mDotFactory;
    private final FaceScanningProviderFactory mFaceScanningFactory;
    private final CameraProtectionLoader mCameraProtectionLoader;
    public final int mFaceScanningViewId;

    @VisibleForTesting
@@ -333,7 +334,8 @@ public class ScreenDecorations implements
            FaceScanningProviderFactory faceScanningFactory,
            ScreenDecorationsLogger logger,
            FacePropertyRepository facePropertyRepository,
            JavaAdapter javaAdapter) {
            JavaAdapter javaAdapter,
            CameraProtectionLoader cameraProtectionLoader) {
        mContext = context;
        mSecureSettings = secureSettings;
        mCommandRegistry = commandRegistry;
@@ -343,6 +345,7 @@ public class ScreenDecorations implements
        mThreadFactory = threadFactory;
        mDotFactory = dotFactory;
        mFaceScanningFactory = faceScanningFactory;
        mCameraProtectionLoader = cameraProtectionLoader;
        mFaceScanningViewId = com.android.systemui.res.R.id.face_scanning_anim;
        mLogger = logger;
        mFacePropertyRepository = facePropertyRepository;
@@ -981,7 +984,9 @@ public class ScreenDecorations implements
        Resources res = mContext.getResources();
        boolean enabled = res.getBoolean(R.bool.config_enableDisplayCutoutProtection);
        if (enabled) {
            mCameraListener = CameraAvailabilityListener.Factory.build(mContext, mExecutor);
            mCameraListener =
                    CameraAvailabilityListener.Factory.build(
                            mContext, mExecutor, mCameraProtectionLoader);
            mCameraListener.addTransitionCallback(mCameraTransitionCallback);
            mCameraListener.startListening();
        }
+9 −4
Original line number Diff line number Diff line
@@ -344,7 +344,12 @@ class CameraAvailabilityListenerTest : SysuiTestCase() {
    }

    private fun createAndStartSut(): CameraAvailabilityListener {
        return CameraAvailabilityListener.build(context, context.mainExecutor).also {
        return CameraAvailabilityListener.build(
                context,
                context.mainExecutor,
                CameraProtectionLoader((context))
            )
            .also {
                it.addTransitionCallback(cameraTransitionCallback)
                it.startListening()
            }
Loading