android graphic(9)—开发者选项关闭HW overlays

来源:互联网 发布:连锁店收银软件 编辑:程序博客网 时间:2024/05/17 08:28

http://blog.csdn.net/lewif/article/details/50717571

目录(?)[+]

  • setting相关代码
  • surface flinger处理1008 code

在开发者选项中,有许多关于图形的debug选项,今天研究之下,加深了对binder的使用。下面以关闭HW oveylays为例,也就是强制使用GLES去对图层进行合成,而不使用oveylays

setting相关代码

首先分析上层setting中的代码,在packages\apps\Settings\src\com\Android\settings\DevelopmentSettings.Java中,设置了触发函数,

   publicbooleanonPreferenceTreeClick(PreferenceScreenpreferenceScreen, Preference preference) {

   elseif (preference ==mDisableOverlays) {

           writeDisableOverlaysOption();

        }

   }

进而去调用writeDisableOverlaysOption()

    privatevoidwriteDisableOverlaysOption() {

        try {

            //获取SurfaceFlinger对应的BpBinder

            IBinderflinger = ServiceManager.getService("SurfaceFlinger");

            if (flinger !=null) {

               Parcel data = Parcel.obtain();

               data.writeInterfaceToken("android.ui.ISurfaceComposer");

                //选择了就是关闭overlays

                finalint disableOverlays= mDisableOverlays.isChecked() ?1 : 0;

               data.writeInt(disableOverlays);

                // BpBinder传的code1008,肯定server端要实现这个1008对应的函数吧

               flinger.transact(1008, data,null, 0);

               data.recycle();

        //

               updateFlingerOptions();

            }

        } catch(RemoteException ex) {

        }

    }

在前面的文章androidgraphic(3)—surfaceflinger的启动流程》 中介绍过,虽然surfaceflingerservice manager注册的时候用的是SurfaceFlinger的名字,但是一般都是通过ComposerService这个Singleton单例去使用,SurfaceFlinger继承自BnSurfaceComposer 
上面writeDisableOverlaysOption()函数主要包括2部分(虽然在java层,没有native中的BpBinder,BBinder等,但是和c++中的思路是一致的,下面用带引号的BpBinder去表示java中的代理对象) 
1.
获取SurfaceFlinger服务对应的“BpBinder” 
2.
直接使用“BpBinder”transact 
前面在介绍service时,一般使用“BpBinder”时,都会先将“BpBinder”interface_cast成对应的“BpXXX”,然后调用“BpXXX”的接口,但其接口一般都是调用remote()->transact,而remote返回的也就是“BpBinder”,所以完全能直接使用BpBinderremote函数去传输数据。在updateFlingerOptions()函数的注释中有一句“magic communication with surface flinger”,和surface flinger的神奇通信,其实就是使用了非常规方法。

surface flinger处理1008 code

下面我们看看server端是如何处理这个1008code的,首先会执行server端的onTransact函数,本来是要去执行BnSurfaceComposeronTransact函数,但是SurfaceFlinger重写了onTransact函数,因此会去执行SurfaceFlingeronTransact函数,

status_t SurfaceFlinger::onTransact(

    uint32_t code, const Parcel&data, Parcel* reply, uint32_t flags)

{

    //首先根据一些code,检查权限

    switch (code) {

        caseCREATE_CONNECTION:

        case CREATE_DISPLAY:

        caseSET_TRANSACTION_STATE:

        case BOOT_FINISHED:

        case BLANK:

        case UNBLANK:

        {

            // codes that require permission check

           IPCThreadState* ipc = IPCThreadState::self();

            constint pid =ipc->getCallingPid();

            constint uid =ipc->getCallingUid();

            if ((uid !=AID_GRAPHICS) &&

                   !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {

               ALOGE("PermissionDenial: "

                       "can't access SurfaceFlinger pid=%d,uid=%d", pid, uid);

                returnPERMISSION_DENIED;

            }

            break;

        }

        case CAPTURE_SCREEN:

        {

            // codes that require permission check

           IPCThreadState* ipc = IPCThreadState::self();

            constint pid =ipc->getCallingPid();

            constint uid =ipc->getCallingUid();

            if ((uid !=AID_GRAPHICS) &&

                   !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {

               ALOGE("PermissionDenial: "

                       "can't readframebuffer pid=%d, uid=%d", pid, uid);

                returnPERMISSION_DENIED;

            }

            break;

        }

    }

    //首先调用BnSurfaceComposeronTransact,里面都是ISurfaceComposer接口中函数

    //的实现

    status_t err =BnSurfaceComposer::onTransact(code, data, reply, flags);

    //如果返回UNKNOWN_TRANSACTION,或者PERMISSION_DENIED,执行下面的特殊code

    //对于1008这种code,肯定是返回UNKNOWN_TRANSACTION,这里SurfaceFlinger做了特殊处理

    if (err ==UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {

       CHECK_INTERFACE(ISurfaceComposer, data, reply);

        if

        int n;

        switch (code) {

            case1008// toggle use of hw composer

                n =data.readInt32();

                //binder读出来是否关闭,设置mDebugDisableHWC

               mDebugDisableHWC = n ?1 : 0;

               invalidateHwcGeometry();

               repaintEverything();

                return NO_ERROR;

}

1.对于一些code,需要去检查权限; 
2.
首先调用BnSurfaceComposeronTransact,里面都是ISurfaceComposer接口中函数的实现; 
3.
如果onTransact()返回UNKNOWN_TRANSACTION,或者PERMISSION_DENIED,执行下面的特殊code,对于1008这种code,肯定是返回UNKNOWN_TRANSACTION,这里SurfaceFlinger做了特殊处理。而真正的处理只是设置了mDebugDisableHWC这个关闭overlays的开关。 
开发者选项中还有很多类似1008这种code的使用情景,对SurfaceFlinger的调试提供了更多的手段。

 

0 0
原创粉丝点击