This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

screen capture problem on Samsung Galaxy Nexus

Other Parts Discussed in Thread: 4430, 4460

Dear Sir,


I want to do screenshot on Samsung Galaxy Nexus(TI chip, ICS). I tried the method of reading screen data from framebuffer ( /dev/graphics/fb0 ), but the data was totally black. Then I used the shell command "adb pull /dev/graphics/fb0 D:\test.rgb",  got the same result.

The method I wrote above normally works ok (on Moto ME863, TI chip, Gingerbread), so I want to ask that is there any difference about framebuffer between the two devices? How can I get screen data on Samsung Galaxy?

Thank you very much.

BR,

Qiao

  • Hi Qiao,

    You can try to dump the contents of fb0 using the following command.

    cat /dev/fb0 > /tmp/rgb.bin

    You can use IrfanView freeware to read the contents which are in RGB format. (I guess you need rename the file with .raw extension before opening in IrfanView)

    Let us know if this works for you.

    Thanks & Best Regards,

    Venkat

  • Hi Venkat,

    Thanks for quick reply.

    I tried your method, but still got black frame. 

    I tried on 3 different devices:

    1.Moto ME863  with Android 2.3, OMAP 4430, works ok, get right screen data;

    2.Samsung Galaxy Nexus with Android 4.0, OMAP 4460, works wrong, get black data;

    3.Samsung Galaxy Tab 2 with Android 4.0, OMAP 4430, works wrong, get black data.

    So, could you drop some light on me?

    Thanks.

    BR,

    Qiao

  • Hi Peng,

    It looks to me that this method would work fine on Gingerbread Pastry (Android 2.3) of Android releases and not on ICS (Android 4.0) Pastry.

    It should be noted that one of the major enhancements or modifications for ICS releases was allocation of graphic and video buffers from Gralloc module of SGX core. In ICS, you need to lock the graphic buffers before you can access the data within the buffers or any layer. It looks to me that we do not have permission to read the frame buffer content.

    Thanks & Best Regards,

    Venkat

  • I think next posts talks about it,

    http://e2e.ti.com/support/omap/f/849/p/163304/655597.aspx

    http://e2e.ti.com/support/omap/f/849/p/161893/649683.aspx

  • Hi Manuel,

    Thanks for your info.

    So, isn't  there a way to get the address of final composition data shown on the display?

    Thanks.

    Best Regards,

    Qiao

  • For what I know ICS uses Graphic's components instead of framebuffer as GB, and both previous post are post are correct.

    You could try to use DDMS/Screenshot application from Android SDK binaries to get a screen image.

    http://developer.android.com/sdk/index.html

    http://developer.android.com/tools/debugging/ddms.html

    If you cannot access the  screen capture image it means it is not allowed in the current path and it must be because of security reasons/features that are meant to be there.

  • Hi Peng,

    I also wanted to highlight one of the drawbacks of screen capture using DDMS is that only the layers composed by SGX core on to the frame buffer memory area would be captured by the DDMS screen shot tool. The layers which get blended using the OMAP4 DSS Overlay Managers would not be captured. For instance, if the video is getting rendered using DSSComp and one of the video pipelines of DSS, then this would not be captured under snapshot.

    Thanks & Best Regards,

    Venkat

  • Hi Manuel,
    thanks for reply.
    Yes, I have tried the method of DDMS, capturing from surfaceflinger, using API of the class ScreenshotClient, and it worked.
    But it turned out to be too slow. Capturing a raw image costs about 100ms, this can hardly meet our demands, so I am asking for help here to see whether there is a
    faster solution.  Could you give me some suggestions?
    Thank you in advance.
    Best Regards,
    Qiao

  • Hi VenKat,

    Thank you for your infomation.

    The problem you mentioned is our next stage plan, but it is really important.

    Thank you very much again.

    Best Regards,

    Qiao

  • I looked into that issue time back but it was when framebuffer was used and accessing it directly was used, and not that specific search about screen capture in ICS yet.

    By doing a quick search in main Surface and related objects,

    http://developer.android.com/reference/android/Manifest.permission.html

    String     ACCESS_SURFACE_FLINGER     Allows an application to use SurfaceFlinger's low level features

    String     READ_FRAME_BUFFER     Allows an application to take screen shots and more generally get access to the frame buffer data

    /4AI.1.6/mydroid/frameworks/base/services/surfaceflinger/SurfaceFlinger.h
    /4AI.1.6/mydroid/frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp

    You can find a captureScreen function here that is what is used from within the service,

    and the interface has too a captureScreen function with next message

    /4AI.1.6/mydroid/frameworks/base/include/surfaceflinger/ISurfaceComposer.h

        /* Capture the specified screen. requires READ_FRAME_BUFFER permission
         * This function will fail if there is a secure window on screen.
         */

    The other file that has a reference to READ_FRAME_BUFFER is Window Manager Service by reading the code it is like a screenshot application function, it has some code to eliminate not needed applications, and it is based in surface capturescreen function, function's name is screenshotApplications(), this could be what you are looking for, see the comments for mentioned function.

    /4AI.1.6/mydroid/frameworks/base/services/java/com/android/server/wm/WindowManagerService.java

    Has the service surfaceflinger as CAPTURE_SCREEN switch/case for when processing the command, that checks for READ_FRAME_BUFFER permissions.

    /4AI.1.6/mydroid/frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp

    and many test applications that shows how to take a screenshot, matter to check what time are they consuming?

    /4AI.1.6/mydroid/frameworks/base/services/surfaceflinger/tests/screencap/screencap.cpp

    /4AI.1.6/mydroid/frameworks/base/libs/gui/tests/Surface_test.cpp

    these is this note to take in count in this file, that is the point about secured buffers and security stuffs.

    -Verify the screenshot works with no protected buffers.

    another test that does it,

    /4AI.1.6/mydroid/frameworks/base/services/surfaceflinger/tests/Transaction_test.cpp

    and for the previously mentioned screenshot application it has a sleep (100) that could be reflecting in the 100ms that you are seeing.

    /4AI.1.6/mydroid/sdk/screenshot/src/com/android/screenshot/Screenshot.java

                // we can't just ask for the device list right away, as the internal thread getting
                // them from ADB may not be done getting the first list.
                // Since we don't really want getDevices() to be blocking, we wait here manually.
    This code has Thread.sleep(100) and count++, where for "let's not wait > 10 sec." and the if (count > 100), it seems that sleep is in miliseconds if it is not more than 10 seconds, matter to check.

    you can try accessing SurfaceFlinger in a direct way and measure times, just in case.

    After tracing those 2 permission all are SurfaceFlinger related, and seems to be the method that Android providing screen capture.

    I found another 2 BIND_REMOTEVIEWS that are for Widgets and from Activity Manager Service that provides a getTaskThumbnails() function, this could work in some way with proper permissions and measuring times to see if it checks ok.

    /4AI.1.6/mydroid/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java