一个关于android WindowManangerService layer 异常的bug

来源:互联网 发布:淘宝客采集软件哪个好 编辑:程序博客网 时间:2024/05/16 19:00

          一个关于android WindowManangerService layer 异常的bug

最近在工作中,解决的一个android 原生的问题,分享给大家:


手机在MTBF 测试的时候,有一个简单的case:那就是在信息文件夹视图下,点击左上角列表框,没有弹出含“发件箱”、“草稿箱”等选项的列表,然后选择草稿箱,再退出。

结果在多次测试中,极偶现在信息文件夹视图下,点击左上角列表框,没有弹出含“发件箱”、“草稿箱”等选项的列表。


刚开始这个问题也是没有思路,只能够确认发生问题的时候,窗口的焦点是正常的切换的,但是却没有显示出来。

刚开始怀疑graphic的问题,于是在android framework 里面添加log 复测。


在log中发现这样的现象:从Input focus has changed to popupwindow 到 Input focus has changed to BoxMsgListActivity持续了近一分钟。在这一分钟时间段内应该是popupwindow的显示时间段。11-29 23:07:06.048   565 19274 D WindowManager: Input focus has changed to Window{41dd3170 u0 PopupWindow:41fc51d8}11-29 23:08:00.701   565   879 D WindowManager: Input focus has changed to Window{41ec9e58 u0 com.android.mms/com.sprd.mms.folderview.BoxMsgListActivity}但是在SurfaceFlinger这边加log发现:popupwindow在layer list里面只是持续了从11-29 23:07:06.158到11-29 23:07:06.358的200ms内, 在接下来的时间段内popupwindow便从layer list中消失了。


下面是事发现场的surfaceflinger中的信息:

11-29 23:07:08.410   161   161 D SurfaceFlinger: + Layer 0xb805e618 (PopupWindow:41fc51d8)11-29 23:07:08.410   161   161 D SurfaceFlinger:   Region transparentRegion (this=0xb805e77c, count=1)11-29 23:07:08.410   161   161 D SurfaceFlinger:     [  0,   0,   0,   0]11-29 23:07:08.410   161   161 D SurfaceFlinger:   Region visibleRegion (this=0xb805e620, count=1)11-29 23:07:08.410   161   161 D SurfaceFlinger:     [  0,   0,   0,   0]11-29 23:07:08.410   161   161 D SurfaceFlinger:       layerStack=   0, z=    21055, pos=(0,98), size=( 153, 315), crop=(   0,   0, 153, 315), isOpaque=0, invalidate=0, alpha=0xff, flags=0x00000000, tr=[1.00, 0.00][0.00, 1.00]11-29 23:07:08.410   161   161 D SurfaceFlinger:       client=0xb803b35011-29 23:07:08.410   161   161 D SurfaceFlinger:       format= 1, activeBuffer=[ 153x 315: 154,  1], queued-frames=0, mRefreshPending=011-29 23:07:08.410   161   161 D SurfaceFlinger:             mTexName=2 mCurrentTexture=211-29 23:07:08.410   161   161 D SurfaceFlinger:             mCurrentCrop=[0,0,0,0] mCurrentTransform=011-29 23:07:08.410   161   161 D SurfaceFlinger:             mAbandoned=011-29 23:07:08.410   161   161 D SurfaceFlinger:             -BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[153x315], default-format=1, transform-hint=00, FIFO(0)={}11-29 23:07:08.410   161   161 D SurfaceFlinger:              [00:0xb8012d40] state=FREE    , 0xb8025d48 [ 153x 315: 154,  1]11-29 23:07:08.410   161   161 D SurfaceFlinger:              [01:0xb8014c10] state=FREE    , 0xb8037440 [ 153x 315: 154,  1]11-29 23:07:08.410   161   161 D SurfaceFlinger:             >[02:0xb8036220] state=ACQUIRED, 0xb80152b0 [ 153x 315: 154,  1]11-29 23:07:08.410   161   161 D SurfaceFlinger:              [03:0xb805d140] stat11-29 23:07:08.410   161   161 D SurfaceFlinger: + Layer 0xb805b738 (com.android.mms/com.sprd.mms.folderview.BoxMsgListActivity)11-29 23:07:08.410   161   161 D SurfaceFlinger:   Region transparentRegion (this=0xb805b89c, count=1)11-29 23:07:08.410   161   161 D SurfaceFlinger:     [  0,   0,   0,   0]11-29 23:07:08.410   161   161 D SurfaceFlinger:   Region visibleRegion (this=0xb805b740, count=1)11-29 23:07:08.410   161   161 D SurfaceFlinger:     [  0,  38, 480, 800]11-29 23:07:08.410   161   161 D SurfaceFlinger:       layerStack=   0, z=    22050, pos=(0,0), size=( 480, 800), crop=(   0,  38, 480, 800), isOpaque=1, invalidate=0, alpha=0xff, flags=0x00000000, tr=[1.00, 0.00][0.00, 1.00]11-29 23:07:08.410   161   161 D SurfaceFlinger:       client=0xb803b35011-29 23:07:08.410   161   161 D SurfaceFlinger:       format= 1, activeBuffer=[ 480x 800: 480,  1], queued-frames=0, mRefreshPending=011-29 23:07:08.410   161   161 D SurfaceFlinger:             mTexName=10 mCurrentTexture=111-29 23:07:08.410   161   161 D SurfaceFlinger:             mCurrentCrop=[0,0,0,0] mCurrentTransform=011-29 23:07:08.410   161   161 D SurfaceFlinger:             mAbandoned=011-29 23:07:08.410   161   161 D SurfaceFlinger:             -BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[480x800], default-format=1, transform-hint=00, FIFO(0)={}11-29 23:07:08.410   161   161 D SurfaceFlinger:              [00:0xb8018638] state=FREE    , 0xb804f748 [ 480x 800: 480,  1]11-29 23:07:08.410   161   161 D SurfaceFlinger:             >[01:0xb8024c40] state=ACQUIRED, 0xb8030440 [ 480x 800: 480,  1]11-29 23:07:08.410   161   161 D SurfaceFlinger:              [02:0xb80544d0] state=FREE    , 0xb8046a68 [ 480x 800: 480,11-29 23:07:08.410   161   161 D SurfaceFlinger: + Layer 0xb801eea0 (StatusBar)11-29 23:07:08.410   161   161 D SurfaceFlinger:   Region transparentRegion (this=0xb801f004, count=1)11-29 23:07:08.410   161   161 D SurfaceFlinger:     [  0,   0,   0,   0]11-29 23:07:08.410   161   161 D SurfaceFlinger:   Region visibleRegion (this=0xb801eea8, count=1)11-29 23:07:08.410   161   161 D SurfaceFlinger:     [  0,   0, 480,  38]11-29 23:07:08.410   161   161 D SurfaceFlinger:       layerStack=   0, z=   161000, pos=(0,0), size=( 480,  38), crop=(   0,   0, 480,  38), isOpaque=0, invalidate=0, alpha=0xff, flags=0x00000000, tr=[1.00, 0.00][0.00, 1.00]11-29 23:07:08.410   161   161 D SurfaceFlinger:       client=0xb801ecd811-29 23:07:08.410   161   161 D SurfaceFlinger:       format= 1, activeBuffer=[ 480x  38: 480,  1], queued-frames=0, mRefreshPending=011-29 23:07:08.410   161   161 D SurfaceFlinger:             mTexName=6 mCurrentTexture=011-29 23:07:08.410   161   161 D SurfaceFlinger:             mCurrentCrop=[0,0,0,0] mCurrentTransform=011-29 23:07:08.410   161   161 D SurfaceFlinger:             mAbandoned=011-29 23:07:08.410   161   161 D SurfaceFlinger:             -BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[480x38], default-format=1, transform-hint=00, FIFO(0)={}11-29 23:07:08.410   161   161 D SurfaceFlinger:             >[00:0xb802f200] state=ACQUIRED, 0xb80203f8 [ 480x  38: 480,  1]11-29 23:07:08.410   161   161 D SurfaceFlinger:              [01:0xb8025b10] state=FREE    , 0xb80257c8 [ 480x  38: 480,  1]11-29 23:07:08.410   161   161 D SurfaceFlinger:              [02:0xb8025dc0] state=FREE    , 0xb8024be8 [ 480x  38: 480,  1]11-29 23:07:08.410   161   161 D SurfaceFlinger:              [03:0xb80260e0] state=FREE    , 0

作为对比我们又测试了正常情况下,popwindow的layer:

11-29 23:07:06.158   161   161 D SurfaceFlinger: + Layer 0xb805b738 (com.android.mms/com.sprd.mms.folderview.BoxMsgListActivity)11-29 23:07:06.158   161   161 D SurfaceFlinger:   Region transparentRegion (this=0xb805b89c, count=1)11-29 23:07:06.158   161   161 D SurfaceFlinger:     [  0,   0,   0,   0]11-29 23:07:06.158   161   161 D SurfaceFlinger:   Region visibleRegion (this=0xb805b740, count=1)11-29 23:07:06.158   161   161 D SurfaceFlinger:     [  0,  38, 480, 800]11-29 23:07:06.158   161   161 D SurfaceFlinger:       layerStack=   0, z=    22050, pos=(0,0), size=( 480, 800), crop=(   0,  38, 480, 800), isOpaque=1, invalidate=0, alpha=0xff, flags=0x00000000, tr=[1.00, 0.00][0.00, 1.00]11-29 23:07:06.158   161   161 D SurfaceFlinger:       client=0xb803b35011-29 23:07:06.158   161   161 D SurfaceFlinger:       format= 1, activeBuffer=[ 480x 800: 480,  1], queued-frames=0, mRefreshPending=011-29 23:07:06.158   161   161 D SurfaceFlinger:             mTexName=10 mCurrentTexture=111-29 23:07:06.158   161   161 D SurfaceFlinger:             mCurrentCrop=[0,0,0,0] mCurrentTransform=011-29 23:07:06.158   161   161 D SurfaceFlinger:             mAbandoned=011-29 23:07:06.158   161   161 D SurfaceFlinger:             -BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[480x800], default-format=1, transform-hint=00, FIFO(0)={}11-29 23:07:06.158   161   161 D SurfaceFlinger:              [00:0xb8018638] state=FREE    , 0xb804f748 [ 480x 800: 480,  1]11-29 23:07:06.158   161   161 D SurfaceFlinger:             >[01:0xb8024c40] state=ACQUIRED, 0xb8030440 [ 480x 800: 480,  1]11-29 23:07:06.158   161   161 D SurfaceFlinger:              [02:0xb80544d0] state=FREE    , 0xb8046a68 [ 480x 800: 480,11-29 23:07:06.158   161   161 D SurfaceFlinger: + Layer 0xb805e618 (PopupWindow:41fc51d8)11-29 23:07:06.158   161   161 D SurfaceFlinger:   Region transparentRegion (this=0xb805e77c, count=1)11-29 23:07:06.158   161   161 D SurfaceFlinger:     [  0,   0,   0,   0]11-29 23:07:06.158   161   161 D SurfaceFlinger:   Region visibleRegion (this=0xb805e620, count=1)11-29 23:07:06.158   161   161 D SurfaceFlinger:     [  5,  98, 148, 392]11-29 23:07:06.158   161   161 D SurfaceFlinger:       layerStack=   0, z=    22055, pos=(5.11716,98), size=( 153, 315), crop=(   0,   0, 153, 315), isOpaque=0, invalidate=0, alpha=0x4d, flags=0x00000000, tr=[0.93, 0.00][0.00, 0.93]11-29 23:07:06.158   161   161 D SurfaceFlinger:       client=0xb803b35011-29 23:07:06.158   161   161 D SurfaceFlinger:       format= 1, activeBuffer=[ 153x 315: 154,  1], queued-frames=0, mRefreshPending=011-29 23:07:06.158   161   161 D SurfaceFlinger:             mTexName=2 mCurrentTexture=111-29 23:07:06.158   161   161 D SurfaceFlinger:             mCurrentCrop=[0,0,0,0] mCurrentTransform=011-29 23:07:06.158   161   161 D SurfaceFlinger:             mAbandoned=011-29 23:07:06.158   161   161 D SurfaceFlinger:             -BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[153x315], default-format=1, transform-hint=00, FIFO(0)={}11-29 23:07:06.158   161   161 D SurfaceFlinger:              [00:0xb8012d40] state=FREE    , 0xb8025d48 [ 153x 315: 154,  1]11-29 23:07:06.158   161   161 D SurfaceFlinger:             >[01:0xb8014c10] state=ACQUIRED, 0xb8037440 [ 153x 315: 154,  1]11-29 23:07:06.158   161   161 D SurfaceFlinger: + Layer 0xb801eea0 (StatusBar)11-29 23:07:06.158   161   161 D SurfaceFlinger:   Region transparentRegion (this=0xb801f004, count=1)11-29 23:07:06.158   161   161 D SurfaceFlinger:     [  0,   0,   0,   0]11-29 23:07:06.158   161   161 D SurfaceFlinger:   Region visibleRegion (this=0xb801eea8, count=1)11-29 23:07:06.158   161   161 D SurfaceFlinger:     [  0,   0, 480,  38]11-29 23:07:06.158   161   161 D SurfaceFlinger:       layerStack=   0, z=   161000, pos=(0,0), size=( 480,  38), crop=(   0,   0, 480,  38), isOpaque=0, invalidate=0, alpha=0xff, flags=0x00000000, tr=[1.00, 0.00][0.00, 1.00]11-29 23:07:06.158   161   161 D SurfaceFlinger:       client=0xb801ecd811-29 23:07:06.158   161   161 D SurfaceFlinger:       format= 1, activeBuffer=[ 480x  38: 480,  1], queued-frames=0, mRefreshPending=011-29 23:07:06.158   161   161 D SurfaceFlinger:             mTexName=6 mCurrentTexture=011-29 23:07:06.158   161   161 D SurfaceFlinger:             mCurrentCrop=[0,0,0,0] mCurrentTransform=011-29 23:07:06.158   161   161 D SurfaceFlinger:             mAbandoned=011-29 23:07:06.158   161   161 D SurfaceFlinger:             -BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[480x38], default-format=1, transform-hint=00, FIFO(0)={}11-29 23:07:06.158   161   161 D SurfaceFlinger:             >[00:0xb802f200] state=ACQUIRED, 0xb80203f8 [ 480x  38: 480,  1]11-29 23:07:06.158   161   161 D SurfaceFlinger:              [01:0xb8025b10] state=FREE    , 0xb80257c8 [ 480x  38: 480,  1]11-29 23:07:06.158   161   161 D SurfaceFlinger:              [02:0xb8025dc0] state=FREE    , 0xb8024be8 [ 480x  38: 480,  1]11-29 23:07:06.158   161   161 D SurfaceFlinger:              [03:0xb80260e0] state=FREE    , 0


这时对比异常和正常情况下的popwindow的layer值,发现:

根据底层添加的log信息,异常情况下popwin的Z轴值与正常情况有所区别:正常的情况下,popupwindow 的 z 值比BoxMsgListActivity 要大,显示在上方异常的时候,popupwindow 的 z 值比BoxMsgListActivity 要小,导致popupwindow在BoxMsgListActivity的下方,无法显示因此需要添加响应的log以及打开相应的开关,开追踪window的z轴值的处理部分在framework里面添加了一些log,主要是打开了一些wms以及ViewRootImpl的log信息,来关注window的z轴位置的处理以及对surfaceflinger的layer设置等。但是悲摧的时,添加log后一直没有复现这问题。


然后只能继续分析现有log 以及 code,

对比surfacelinger中正常情况和异常情况下,系统中各window的 z 值,发现异常的情况下,PopupWindow 的Z值小了1000。根据这个线索,猜测可能和下面的参数TYPE_LAYER_OFFSET(1000)的使用有关,这个参数用来为每一种类型的窗口都预留一个足够大的值域来作为Z轴位置。按照这个思路,发现在启动一个window的时候,会调整其过度动画的layer值,
public void setAnimation(Animation anim, int width, int height) {        animation = anim;        animating = false;        if (!anim.isInitialized()) {            anim.initialize(width, height, width, height);        }        anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);        anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());        int zorder = anim.getZAdjustment();        int adj = 0;        if (zorder == Animation.ZORDER_TOP) {            adj = WindowManagerService.TYPE_LAYER_OFFSET;        } else if (zorder == Animation.ZORDER_BOTTOM) {            adj = -WindowManagerService.TYPE_LAYER_OFFSET;        }        if (animLayerAdjustment != adj) {            animLayerAdjustment = adj;            updateLayers();        }......    }

在过度动画结束的时候,再将其layer的值调整回去;且调整值正好是TYPE_LAYER_OFFSET。因为整个系统中只有这一处调整layer值,基本可以确认,某种异常导致layer没有被调整为原来的值
为验证该推断,本地修改mms界面,动画结束后强制不重置layer值,100%必现这个问题。

代码如下:

 boolean stepAnimationLocked(long currentTime) {..............//动画执行结束        if (!animating && animation == null) {            return false;        }        mAnimator.setAppLayoutChanges(this, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM,                "AppWindowToken");        clearAnimation();        animating = false;        //重置layer        if (animLayerAdjustment != 0) {            animLayerAdjustment = 0;            updateLayers();        }......    }

由于一致没有复现,未找到root cause,启动activity的时候有设置window的layer值;在最后切换动画结束的时候,会重置layer值为原始值。但是中间执行过程较为发散

我的修改方案为:在切换动画结束结束的时候,检查layer值是否被设置回去,如果没有强制重置一下即可。

 boolean stepAnimationLocked(long currentTime) {..............//动画执行结束if (!animating && animation == null) {    //fix begin    if (animLayerAdjustment != 0) {       animLayerAdjustment = 0;       updateLayers();    }    //fix end    return false;}......    }


android平台本身没有考虑到这种异常的情况,虽然很偶现。



0 0
原创粉丝点击