2009年7月1日水曜日

RFBServer on Cupcake

1.0のソースコードには含まれていたSurfaceFlingerのVNC Server機能をAndroid 1.5へマージしてみた。

RFBServer on cupcake

(1) 1.0 のソースコードから frameworks/base/libs/surfaceflinger/RFBServer.{cpp,h} をコピーする。
(2) 外部から接続できるようRFBServerをすべてのインタフェースにbindするために下記のように変更。
*** RFBServer.cpp       2009-07-12 11:56:19.000000000 +0900
--- RFBServer.cpp.orig 2009-07-12 11:55:46.000000000 +0900
***************
*** 112,119 ****
do {
retry:
if (serverfd < 0) {
! // serverfd = socket_loopback_server(port, SOCK_STREAM);
! serverfd = socket_inaddr_any_server(port, SOCK_STREAM);
if (serverfd < 0) {
if ((errno == EADDRINUSE) && (port < (VNC_PORT+10))) {
LOGW("port %d already in use, trying %d", port, port+1);
--- 112,118 ----
do {
retry:
if (serverfd < 0) {
! serverfd = socket_loopback_server(port, SOCK_STREAM);
if (serverfd < 0) {
if ((errno == EADDRINUSE) && (port < (VNC_PORT+10))) {
LOGW("port %d already in use, trying %d", port, port+1);


(3) 1.0のSurfaceFlinger.cppを参考にVNC処理部分を追加していく。
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/Surfac
eFlinger.cpp
index c2adf07..030a8e9 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -55,6 +55,7 @@
#include "LayerBitmap.h"
#include "LayerOrientationAnim.h"
#include "OrientationAnimation.h"
+#include "RFBServer.h"
#include "SurfaceFlinger.h"
#include "VRamHeap.h"

@@ -64,6 +65,11 @@

#define DISPLAY_COUNT 1

+// the VNC server even on local ports presents a significant
+// thread as it can allow an application to control and "see" other
+// applications, de-facto bypassing security permissions.
+#define ENABLE_VNC_SERVER 1
+
namespace android {

// ---------------------------------------------------------------------------
@@ -455,6 +461,9 @@ status_t SurfaceFlinger::readyToRun()
if (mDebugNoBootAnimation == false)
mBootAnimation = new BootAnimation(this);

+ if (ENABLE_VNC_SERVER)
+ mRFBServer = new RFBServer(w, h, f);
+
return NO_ERROR;
}

@@ -572,6 +581,18 @@ void SurfaceFlinger::postFramebuffer()
debugShowFPS();
}

+ if (UNLIKELY(ENABLE_VNC_SERVER &&
+ mRFBServer!=0 && mRFBServer->isConnected())) {
+ if (!mSecureFrameBuffer) {
+ GGLSurface fb;
+ // backbufer, is going to become the front buffer really soon
+ hw.getDisplaySurface(&fb);
+ if (LIKELY(fb.data != 0)) {
+ mRFBServer->frameBufferUpdated(fb, mInvalidRegion);
+ }
+ }
+ }
+
hw.flip(mInvalidRegion);

mInvalidRegion.clear();

diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceF
linger.h
index e023182..d18c324 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -40,6 +40,7 @@
#include "CPUGauge.h"
#include "Layer.h"
#include "Tokenizer.h"
+#include "RFBServer.h"

struct copybit_device_t;
struct overlay_device_t;
@@ -348,6 +349,7 @@ private:
sp mGPU;
GLuint mWormholeTexName;
sp mBootAnimation;
+ sp mRFBServer;
nsecs_t mBootTime;

// Can only accessed from the main thread, these members