droidVncServer
droidVncServer copied to clipboard
Stopped working with Android 4.2 on Nexus 7
After upgrading my Nexus 7 to Android 4.2 today, the VNC server package stopped working. Using the framebuffer method only yields a garbled image of the recovery system, while the surfaceflinger method fails to load to to library trouble:
V/VNCserver( 2154): Starting /data/data/org.onaips.vnc/files/androidvncserver -r 0 -s 100 -P 5901 -m gingerbread I/VNCserver( 5537): rotating to 0 degrees I/VNCserver( 5537): scaling to 100% I/VNCserver( 5537): Grab method "gingerbread" not found, sticking with auto-detection. I/VNCserver( 5537): Initializing grabber method... I/VNCserver( 5537): No grabber method selected, auto-detecting... I/VNCserver( 5537): --Loading flinger native lib-- I/VNCserver( 5537): Loading lib: /data/data/org.onaips.vnc/files//libdvnc_flinger_sdk10.so I/VNCserver( 5537): Loading lib: /data/data/org.onaips.vnc/files//libdvnc_flinger_sdk14.so I/VNCserver( 5537): Couldnt load any flinger library! Error string: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbo l "_ZN7android16ScreenshotClient6updateEv" referenced by "libdvnc_flinger_sdk14.so"... I/VNCserver( 5537): --Loading gralloc native lib-- I/VNCserver( 5537): Loading lib: /data/data/org.onaips.vnc/files//libdvnc_gralloc_sdk10.so E/gralloc ( 5537): creating nvcap video capture service E/gralloc ( 5537): failed to load libnvcap_video.so (Cannot load library: load_library(linker.cpp:745): library "/system/lib/libnvcap_video.s o" not found) E/gralloc ( 5537): Failed to create overlay for display 0 E/gralloc ( 5537): Failed to create overlay for display 0 E/gralloc ( 5537): Failed to create overlay for display 0 E/gralloc ( 5537): Failed to create overlay for display 1 E/gralloc ( 5537): Failed to create overlay for display 1 E/gralloc ( 5537): Failed to create overlay for display 1 E/gralloc ( 5537): Failed to create overlay for display 2 E/gralloc ( 5537): Failed to create overlay for display 2 E/gralloc ( 5537): Failed to create overlay for display 2 I/gralloc ( 5537): using (fd=11) I/gralloc ( 5537): id = tegra_fb I/gralloc ( 5537): xres = 800 px I/gralloc ( 5537): yres = 1280 px I/gralloc ( 5537): xres_virtual = 800 px I/gralloc ( 5537): yres_virtual = 2560 px I/gralloc ( 5537): bpp = 32 I/gralloc ( 5537): r = 0:8 I/gralloc ( 5537): g = 8:8 I/gralloc ( 5537): b = 16:8 I/gralloc ( 5537): smem_start = 0xbec00000 I/gralloc ( 5537): smem_len = 0x00900000 I/gralloc ( 5537): format = 1 I/gralloc ( 5537): stride = 800 I/gralloc ( 5537): width = 104 mm (195.384613 dpi) I/gralloc ( 5537): height = 162 mm (200.691360 dpi) I/gralloc ( 5537): refresh rate = 60.00 Hz I/VNCserver( 5537): Gralloc method not supported by this device! I/VNCserver( 5537): --Initializing framebuffer access method-- I/VNCserver( 5537): line_lenght=3200 xres=800, yres=1280, xresv=800, yresv=2560, xoffs=0, yoffs=0, bpp=32 I/VNCserver( 5537): Initializing virtual keyboard and touch device... I/VNCserver( 5537): ---Initializing uinput...--- I/EventHub( 1006): New device: id=7, fd=269, path='/dev/input/event3', name='qwerty', classes=0x27, configuration='/system/usr/idc/qwerty.idc ', keyLayout='/system/usr/keylayout/qwerty.kl', keyCharacterMap='/system/usr/keychars/qwerty.kcm', builtinKeyboard=true, usingSuspendBlockIoc tl=true, usingClockIoctl=false W/InputReader( 1006): Ignoring spurious device added event for deviceId 0. I/ActivityManager( 1006): Config changed: {1.0 ?mcc?mnc de_DE ldltr sw600dp w600dp h880dp 213dpi lrg port finger -keyb/v/h dpad/v s.17} I/VNCserver( 5537): Initializing VNC server: I/VNCserver( 5537): width: 800 I/VNCserver( 5537): height: 1280 I/VNCserver( 5537): bpp: 32 I/VNCserver( 5537): port: 5901 I/VNCserver( 5537): Colourmap_rgba=0:8:16:24 lenght=8:8:8:8 I/VNCserver( 5537): Starting IPC connection... I/VNCserver( 5537): binded to port 13132 V/VNCserver( 2154): RECEIVED ~SERVERSTARTED| I/PCKeyboard( 1233): onConfigurationChanged() I/VNCserver( 5537): I/VNCserver( 5537): Waiting for a connection
+1 on this issue.
+1 focused on 'fb' mode to bypass flinger and gralloc lib issues. It runs OK but does not send any rectangles. logic guiding whether rfbserver.framebufferupdate() sends any data to client is not making it thru any of the filter conditions that compare regions. Result , good client connection on the chosen protocol but no regions ever get sent by the server.
+1 on this issue with Android 4.2.1.
Both FB and Surfaceflinger mode give me a purple corrupted version of the bootloader screen, but mouse clicks work OK. Gralloc says: Unsupported pixel depth Getting root permissions Could not start server
Android 4.2.1, Nexus 7. I've tried a variety of dev options with both FB and Surfaceflinger: Force GPU rendering : Force use of GPU for 2D drawing Disable HW overlays: Always use GPU for screen compositing Force 4x MSAA in OpenGL ES 2.0 apps Simulate secondary displays All get the purple bootloader screen.
Done some more digging. It looks like the surfaceflinger method is failing because it's calling ScreenshotClient::update(), which doesn't exist in 4.2.1 as a method without parameters: 4.2.1 source, 4.1.2 source,
Here's a workaround, which is to put the function back in. While patching the ROM isn't an option, I wonder if we could call another version of update(xxx), such as ScreenshotClient::update(const sp<IBinder>& display) with display=0? All the update(...) functions pass down 'display' to the same place, so I think this should work.
(I've never done any Android development and don't have a toolchain, otherwise I'd have a go at compiling)
Edit: looks like this problem is exactly the missing method listed in the log above
id love to get it working on 4.2 as i have no other solution. I built droid-vnc with a cross-toolchain for API #17 using the NDK, but i did not build any AOSP code along with it. Its alot of time to rebuild and to link with AOSP. I spent alot of time on list statements in vnc/LibVNCServer-0.9.9/libvncserver/rfbserver.c .
TO me , it did not look like it was close to the filtering conditions as to whether any rectangles had changed meaning they needed to be sent. Everything was black for me.. It would start up Ok and it would inspect frames on the client and would think nothing was changing and therfor, nothing needing to be sent.
I've made some progress and can declare a successful failure.
First I downloaded the full SDK, NDK and AOSP for 4.2.1 (targeting Nexus 7 'grouper'). I set these building overnight. Then I followed the build insturctions for Droid VNC server and found it wouldn't compile due to the ScreenshotClient::update() problem I mentioned. I fixed that to refer to the main display, eDisplayIdMain, and rebuilt the project according to the README (NDK build then native interfaces then Eclipse project). Patch here: https://gist.github.com/4342455 I didn't have any problems with libvncserver, but then I rebuilt everything from scratch.
I took the .apk over to the Nexus 7. This changed things. Instead of a noisy purple screen showing the bootloader robot, I get a noisy white screen showing nothing recognisable. I tried eDisplayIdHdmi which gave the same results. The white noise doesn't change when the LCD changes.
Next up I tried framebuffer mode: same noisy white screen. To compare, I downloaded a screenshot app Screenshot UX Trial and took a screenshot: same noisy white screen. I also did cat /dev/graphics/fb0 > /sdcard/tmp/fb0
(and the same for fb1 which is the HDMI screen) and converted that:
ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s 800x1280 -i fb0 fb0.png
which gave a similar white image for both fb0 and fb1:
ioctl -rl 28 /dev/graphics/fb0 17920
confirms the screen is 800x1280 at 32 bits colour. I've been through various image formats and none of them give anything useful (RGB all varieties of white, YUV types of purple), so I think we're looking at data or code here. The purpleness of the corrupt bootloader screen suggests we're interpreting it in YUV format. It could be YUV, but I'd guess RGB is more likely for an LCD panel.
Then I patched up the gralloc code in AOSP - nvidia's patch needed rewriting to fit 4.2.1: https://gist.github.com/4342442 However this still complains pixel format not supported - which can also mean the graphics device would not open. Indeed, there's no /dev/gpu0 on the Nexus 7.
So... I think graphics capture is fundamentally broken on 4.2.1. gralloc doesn't work because it's not a Tegra 2. Framebuffer doesn't work because it returns garbage. SurfaceFlinger::ScreenshotClient also returns the same garbage. And other apps have the same problem so it's not just us.
This is my first time doing any Android dev, so I may well have missed something here. In particular I don't have adb set up so I'm missing any debug messages coming out (my android tools are on a remote machine) and I haven't checked if update() is actually getting called at all (though the colour change from purple to white when I changed to the new display API suggests is might).
I'm not sure why the format of the fb0 device has changed in Android 4.2.1 on the N7, but the preferred method is to use the "screencap" binary, which seems to be available on all ICS+ devices. You can see a reference implementation here: https://github.com/android/platform_frameworks_base/blob/master/cmds/screencap/screencap.cpp
If you don't include any parameters, you will get a binary stream of the screen pixels with a short header describing the data (width, height, pixel format).
+1 for this issue. Is the developer still maintening that app ?
+1 on this issue, on my Nexus 4 with Android 4.2.
Another +1 on my Nexus 7 Second generation on android 4.3.
+1 on Nexus 7, Android 4.3. Any progress with this issue?
Irrelavent to VNC, but soinfo_relocate(linker.cpp:975) happens on ndk-r8e build, on Android 4.2.X
I try to use "/system/bin/screencap" to get the screen capture,but still doesn't work.My code looks like this
unsigned int* readBuffer(void) { FILE* stream; //int status; int count=1024; int total=0; memset(buf,0,displayInfo.size); stream=popen("/system/bin/screencap","r"); if(stream!=0){ while(fgets(((char*)buf)+total,count,stream)!=0){ //L("total:%d\n",total); total=total+count; }
L("total:%d\n",total);
pclose(stream);
}
return buf;
}
+1 on Nexus 7 1st Gen, Android 4.4
+1 on Nexus 7 1st Gen, Android 4.4
+1 Samsung galaxy s5