乐于分享
好东西不私藏

安卓16王炸更新!四角圆角终于能“各玩各的”

安卓16王炸更新!四角圆角终于能“各玩各的”

背景

在马哥讲解三分屏实战适配aosp 16时候,最后三分屏运行效果如下:

学员疑问如下:简单说我们原来设置的圆角,其实都是整个Task四个角都进行设置圆角,这里明显看到Task的左边没有任何圆角,但是右边都是圆角。

那么大家是否有思考过这个是如何实现的么?如果让你去实现你会去如何设计呢?

新api接口讲解:

老版本aosp14上设置圆角接口只有一个

/**
         * Sets the corner radius of a {@link SurfaceControl}.
         * @param sc SurfaceControl
         * @param cornerRadius Corner radius in pixels.
         * @return Itself.
         * @hide
         */

        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public Transaction setCornerRadius(SurfaceControl sc, float cornerRadius){
            checkPreconditions(sc);
            nativeSetCornerRadius(mNativeObject, sc.mNativeObject, cornerRadius);

returnthis;
        }

传递参数也只要核心的一个cornerRadius参数既可以。

但是经过调查发现新版本aosp16上发现一个新的

aosp16版本上 frameworks/base/core/java/android/view/SurfaceControl.java

/**
         * Sets the corner radius of a {@link SurfaceControl}. This corner radius is applied to the
         * SurfaceControl and its children. The API expects a crop to be set on the SurfaceControl
         * to ensure that the corner radius is applied to the correct region. If the crop does not
         * intersect with the SurfaceControl's visible content, the corner radius will not be
         * applied.
         *
         * @param sc SurfaceControl
         * @param cornerRadius Corner radius in pixels.
         * @return Itself.
         * @hide
         */

        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public Transaction setCornerRadius(SurfaceControl sc, float cornerRadius){
            checkPreconditions(sc);
if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
                SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
"setCornerRadius"this, sc, "cornerRadius=" + cornerRadius);
            }
            nativeSetCornerRadius(mNativeObject, sc.mNativeObject, cornerRadius);

returnthis;
        }

/**
         * Sets the corner radius for each corner of a {@link SurfaceControl}. This is applied to
         * the SurfaceControl and its children. The API expects a crop to be set on the
         * SurfaceControl to ensure that the corner radius is applied to the correct region. If the
         * crop does not intersect with the SurfaceControl's visible content, the corner radius will
         * not be applied.
         *
         * @param sc SurfaceControl
         * @hide
         */

        @NonNull
public Transaction setCornerRadius(
                SurfaceControl sc, float topLeft, float topRight,
float bottomLeft, float bottomRight)
{
            checkPreconditions(sc);
if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
                SurfaceControlRegistry.getProcessInstance()
                        .checkCallStackDebugging(
"setCornerRadius",
this,
                                sc,
"topLeft=" + topLeft
                                + " , topRight=" + topRight
                                + ", bottomLeft=" + bottomLeft
                                + " , bottomRight=" + bottomRight);
            }

if (!com.android.graphics.surfaceflinger.flags.Flags.setClientDrawnCornerRadii()) {
                Log.w(TAG, "setCornerRadius was called but"
                           + "set_client_drawn_corner_radii flag is disabled");
returnthis;
            }
            nativeSetCornerRadius(mNativeObject, sc.mNativeObject,
                                        topLeft, topRight, bottomLeft, bottomRight);

returnthis;
        }

上面可以看出在aosp16明显就有多出一个setCornerRadius接口,可以设置四个角的圆角弧度:

 setCornerRadius(
                SurfaceControl sc, float topLeft, float topRight,
float bottomLeft, float bottomRight)

这样有了这个接口后,就可以轻易实现对四个圆角轻易控制。

实现源码:

为了简单测试一下这个接口是否生效,看看效果如何,那就对所有的窗口都进行相关的圆角测试:

frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java

    private void showRobustly(SurfaceControl.Transaction t) {

        //省略部分
        //左边的圆角弧度都是50,右边圆角弧度150
        t.setCornerRadius(mSurfaceControl,50,150,50,100);
        t.setWindowCrop(mSurfaceControl,mWin.mRequestedWidth,mWin.mRequestedHeight);
          //省略部分
    }

测试结果如下:

测试结果坐标都是弧度为50,右边弧度为150。

留给各位学员作业:

那么请问在SurfaceFlinger中是如何实现对这四个圆角进行单独的弧度设置的?你这边如果自己去实现这个接口你是否有思路呢?然后再结合源码去对比看看哈。

学习fw课程和性能相关知识有啥疑问,请记得联系马哥本人或者在马哥vip群中进行讨论

更多vip干货独享知识,及面试定制指导上岸fw工程师服务,课程优惠购买成为vip学员进入vip群,积极讨论各种行业难点痛点疑难问题,答疑服务等。

请联系马哥微信:

Android Framework开发rom实战合集课表/车载车机手机高级系统开发工程必会技能
重大消息:Hal+perfetto-systrace+SurfaceFlinger合集新专题发布
重大消息:ShellTransition项目实战专题aosp15版本首发优惠获取
开学第一课:安卓音频框架Audio子系统实战专题--首发优惠活动
2026第一课:安卓14-1车机手机三分屏实战专题--首发优惠活动