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

Commit 37953fc9 authored by Matthew DeVore's avatar Matthew DeVore Committed by Android (Google) Code Review
Browse files

Merge changes Ice7e80e7,I975d1241 into main

* changes:
  Cleanup to follow Kotlin member variable naming and ktfmt
  Add flag to add and arrange mirroring display in a stack
parents 092ae344 79c07d9d
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -38,3 +38,10 @@ flag {
  description: "Allow changing display size of the connected display."
  bug: "392853666"
}

flag {
  name: "show_stacked_mirroring_display_connected_display_setting"
  namespace: "lse_desktop_experience"
  description: "Stack mirroring displays on the display topology pane."
  bug: "401059862"
}
+10 −0
Original line number Diff line number Diff line
@@ -51,4 +51,14 @@ class DesktopExperienceFlags(private val featureFlagsImpl: FeatureFlags) : Featu

    override fun resolutionAndEnableConnectedDisplaySetting(): Boolean =
        resolutionAndEnableConnectedDisplaySettingFlag.isTrue

    private val showStackedMirroringDisplayConnectedDisplaySettingFlag =
        DesktopExperienceFlag(
            featureFlagsImpl::showStackedMirroringDisplayConnectedDisplaySetting,
            /* shouldOverrideByDevOption= */ false,
            Flags.FLAG_SHOW_STACKED_MIRRORING_DISPLAY_CONNECTED_DISPLAY_SETTING,
        )

    override fun showStackedMirroringDisplayConnectedDisplaySetting(): Boolean =
        showStackedMirroringDisplayConnectedDisplaySettingFlag.isTrue
}
 No newline at end of file
+69 −61
Original line number Diff line number Diff line
@@ -31,66 +31,74 @@ import com.android.settings.R
/** Represents a draggable block in the topology pane. */
class DisplayBlock(val injector: ConnectedDisplayInjector) : FrameLayout(injector.context!!) {
    @VisibleForTesting
    val mHighlightPx = context.resources.getDimensionPixelSize(
            R.dimen.display_block_highlight_width)
    val cornerRadiusPx = context.resources.getDimensionPixelSize(
        R.dimen.display_block_corner_radius)
    val highlightPx = context.resources.getDimensionPixelSize(R.dimen.display_block_highlight_width)
    val cornerRadiusPx =
        context.resources.getDimensionPixelSize(R.dimen.display_block_corner_radius)

    private var mDisplayId: Int? = null
    private var _displayId: Int? = null

    /** Scale of the mirrored wallpaper to the actual wallpaper size. */
    private var mSurfaceScale: Float? = null
    private var surfaceScale: Float? = null

    val displayId: Int?
        get() = mDisplayId
        get() = _displayId

    // These are surfaces which must be removed from the display block hierarchy and released once
    // the new surface is put in place. This list can have more than one item because we may get
    // two reset calls before we get a single surfaceChange callback.
    private val mOldSurfaces = mutableListOf<SurfaceControl>()
    private var mWallpaperSurface: SurfaceControl? = null
    private val oldSurfaces = mutableListOf<SurfaceControl>()
    private var wallpaperSurface: SurfaceControl? = null

    private val mUpdateSurfaceView = Runnable { updateSurfaceView() }
    private val updateSurfaceView = Runnable { updateSurfaceView() }

    @VisibleForTesting fun updateSurfaceView() {
        val displayId = mDisplayId ?: return
    @VisibleForTesting
    fun updateSurfaceView() {
        val displayId = _displayId ?: return

        if (parent == null) {
            Log.i(TAG, "View for display $displayId has no parent - cancelling update")
            return
        }

        var surface = mWallpaperSurface
        var surface = wallpaperSurface
        if (surface == null) {
            surface = injector.wallpaper(displayId)
            if (surface == null) {
                injector.handler.postDelayed(mUpdateSurfaceView, /* delayMillis= */ 500)
                injector.handler.postDelayed(updateSurfaceView, /* delayMillis= */ 500)
                return
            }
            mWallpaperSurface = surface
            wallpaperSurface = surface
        }

        val surfaceScale = mSurfaceScale ?: return
        injector.updateSurfaceView(mOldSurfaces, surface, mWallpaperView, surfaceScale)
        mOldSurfaces.clear()
        val surfaceScale = surfaceScale ?: return
        injector.updateSurfaceView(oldSurfaces, surface, wallpaperView, surfaceScale)
        oldSurfaces.clear()
    }

    private val mHolderCallback = object : SurfaceHolder.Callback {
    private val holderCallback =
        object : SurfaceHolder.Callback {
            override fun surfaceCreated(h: SurfaceHolder) {}

        override fun surfaceChanged(h: SurfaceHolder, format: Int, newWidth: Int, newHeight: Int) {
            override fun surfaceChanged(
                h: SurfaceHolder,
                format: Int,
                newWidth: Int,
                newHeight: Int,
            ) {
                updateSurfaceView()
            }

            override fun surfaceDestroyed(h: SurfaceHolder) {}
        }

    val mWallpaperView = SurfaceView(context)
    private val mBackgroundView = View(context).apply {
    val wallpaperView = SurfaceView(context)
    private val backgroundView =
        View(context).apply {
            background = context.getDrawable(R.drawable.display_block_background)
        }
    @VisibleForTesting
    val mSelectionMarkerView = View(context).apply {
    val selectionMarkerView =
        View(context).apply {
            background = context.getDrawable(R.drawable.display_block_selection_marker_background)
        }

@@ -102,11 +110,11 @@ class DisplayBlock(val injector: ConnectedDisplayInjector) : FrameLayout(injecto
        // Prevents shadow from appearing around edge of button.
        stateListAnimator = null

        addView(mWallpaperView)
        addView(mBackgroundView)
        addView(mSelectionMarkerView)
        addView(wallpaperView)
        addView(backgroundView)
        addView(selectionMarkerView)

        mWallpaperView.holder.addCallback(mHolderCallback)
        wallpaperView.holder.addCallback(holderCallback)
    }

    /**
@@ -114,14 +122,14 @@ class DisplayBlock(val injector: ConnectedDisplayInjector) : FrameLayout(injecto
     * highlight border.
     */
    var positionInPane: PointF
        get() = PointF(x + mHighlightPx, y + mHighlightPx)
        get() = PointF(x + highlightPx, y + highlightPx)
        set(value: PointF) {
            x = value.x - mHighlightPx
            y = value.y - mHighlightPx
            x = value.x - highlightPx
            y = value.y - highlightPx
        }

    fun setHighlighted(value: Boolean) {
        mSelectionMarkerView.visibility = if (value) View.VISIBLE else View.INVISIBLE
        selectionMarkerView.visibility = if (value) VISIBLE else INVISIBLE

        // The highlighted block must be draw last so that its highlight shows over the borders of
        // other displays.
@@ -136,24 +144,23 @@ class DisplayBlock(val injector: ConnectedDisplayInjector) : FrameLayout(injecto
     * @param bottomRight coordinates of bottom right corner of the block, not including highlight
     *   border
     * @param surfaceScale scale in pixels of the size of the wallpaper mirror to the actual
     *                     wallpaper on the screen - should be less than one to indicate scaling to
     *                     smaller size
     *   wallpaper on the screen - should be less than one to indicate scaling to smaller size
     */
    fun reset(displayId: Int, topLeft: PointF, bottomRight: PointF, surfaceScale: Float) {
        mWallpaperSurface?.let { mOldSurfaces.add(it) }
        injector.handler.removeCallbacks(mUpdateSurfaceView)
        mWallpaperSurface = null
        wallpaperSurface?.let { oldSurfaces.add(it) }
        injector.handler.removeCallbacks(updateSurfaceView)
        wallpaperSurface = null
        setHighlighted(false)
        positionInPane = topLeft

        mDisplayId = displayId
        mSurfaceScale = surfaceScale
        _displayId = displayId
        this.surfaceScale = surfaceScale

        val newWidth = (bottomRight.x - topLeft.x).toInt()
        val newHeight = (bottomRight.y - topLeft.y).toInt()

        val paddedWidth = newWidth + 2*mHighlightPx
        val paddedHeight = newHeight + 2*mHighlightPx
        val paddedWidth = newWidth + 2 * highlightPx
        val paddedHeight = newHeight + 2 * highlightPx

        if (width == paddedWidth && height == paddedHeight) {
            // Will not receive a surfaceChanged callback, so in case the wallpaper is different,
@@ -170,24 +177,25 @@ class DisplayBlock(val injector: ConnectedDisplayInjector) : FrameLayout(injecto

        // The highlight is the outermost border. The highlight is shown outside of the parent
        // FrameLayout so that it consumes the padding between the blocks.
        mWallpaperView.layoutParams.let {
        wallpaperView.layoutParams.let {
            it.width = newWidth
            it.height = newHeight
            if (it is MarginLayoutParams) {
                it.leftMargin = mHighlightPx
                it.topMargin = mHighlightPx
                it.bottomMargin = mHighlightPx
                it.topMargin = mHighlightPx
                it.leftMargin = highlightPx
                it.topMargin = highlightPx
                it.bottomMargin = highlightPx
                it.topMargin = highlightPx
            }
            mWallpaperView.layoutParams = it
            wallpaperView.layoutParams = it
        }

        mWallpaperView.outlineProvider = object : ViewOutlineProvider() {
        wallpaperView.outlineProvider =
            object : ViewOutlineProvider() {
                override fun getOutline(view: View, outline: Outline) {
                    outline.setRoundRect(0, 0, view.width, view.height, cornerRadiusPx.toFloat())
                }
            }
        mWallpaperView.clipToOutline = true
        wallpaperView.clipToOutline = true

        // The other two child views are MATCH_PARENT by default so will resize to fill up the
        // FrameLayout.
Loading