barchart-udt icon indicating copy to clipboard operation
barchart-udt copied to clipboard

ARM support for Android

Open carrot-garden opened this issue 12 years ago • 47 comments

see #2

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

http://code.google.com/p/maven-android-plugin/ https://github.com/jayway/maven-android-plugin/

carrot-garden avatar Jan 01 '13 14:01 carrot-garden

i am now learning the android NDK,may i build the so

He-Pin avatar Jan 14 '13 05:01 He-Pin

i have build the android's libudt.so,and what should i do next? change this in epoll.h

#ifdef LINUX #include <sys/epoll.h> #include <unistd.h> #endif

==>

#include <sys/epoll.h> #include <unistd.h> #include #include #include #include

and the android make is file :Android.mk

LOCAL_PATH := $(call my-dir) LOCAL_CPP_EXTENSION:=.cpp include $(CLEAR_VARS) LOCAL_MODULE := udt LOCAL_SRC_FILES := api.cpp buffer.cpp cache.cpp ccc.cpp channel.cpp common.cpp core.cpp epoll.cpp list.cpp md5.cpp packet.cpp queue.cpp window.cpp include $(BUILD_SHARED_LIBRARY)

and one application make is contains too file :Application.mk APP_STL := stlport_static APP_CPPFLAGS += -fexceptions APP_CPPFLAGS += -frtti APP_CPPFLAGS += -fpermissive

download file https://www.box.com/s/2drueif1y4l82dkm81f2

He-Pin avatar Jan 14 '13 08:01 He-Pin

ok ,ok,you guys change the udt's default implement ,i finally build the android so and your last version of com_barchart_udt_SocketUDT ,the build log is :

kerr@DearPanda:~/Dev-Projects/UDTAndroid$ ~/Dev-Resources/android-ndk-r8d/ndk-build /home/kerr/Dev-Resources/android-ndk-r8d/build/core/add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 4 in ./AndroidManifest.xml
Compile++ thumb : com_barchart_udt_SocketUDT <= com_barchart_udt_CCC.cpp Compile++ thumb : com_barchart_udt_SocketUDT <= com_barchart_udt_SocketUDT.cpp Compile++ thumb : com_barchart_udt_SocketUDT <= JNICCC.cpp jni/JNICCC.cpp: In function 'JNIEnv* AttachToJVM(JavaVM_)': jni/JNICCC.cpp:50:62: warning: invalid conversion from 'void__' to 'JNIEnv_* {aka JNIEnv**}' [-fpermissive] /home/kerr/Dev-Resources/android-ndk-r8d/platforms/android-14/arch-arm/usr/include/jni.h:1072:10: warning: initializing argument 1 of 'jint JavaVM::AttachCurrentThread(JNIEnv**, void)' [-fpermissive] Compile++ thumb : com_barchart_udt_SocketUDT <= JNICCCFactory.cpp jni/JNICCCFactory.cpp: In member function 'JNIEnv JNICCCFactory::AttachToJVM()': jni/JNICCCFactory.cpp:66:67: warning: invalid conversion from 'void**' to 'JNIEnv** {aka _JNIEnv**}' [-fpermissive] /home/kerr/Dev-Resources/android-ndk-r8d/platforms/android-14/arch-arm/usr/include/jni.h:1072:10: warning: initializing argument 1 of 'jint _JavaVM::AttachCurrentThread(JNIEnv**, void*)' [-fpermissive] Compile++ thumb : com_barchart_udt_SocketUDT <= JNIHelpers.cpp Prebuilt : libstlport_static.a <= <NDK>/sources/cxx-stl/stlport/libs/armeabi/ Compile++ thumb : udt <= api.cpp Compile++ thumb : udt <= buffer.cpp Compile++ thumb : udt <= cache.cpp Compile++ thumb : udt <= ccc.cpp Compile++ thumb : udt <= channel.cpp Compile++ thumb : udt <= common.cpp Compile++ thumb : udt <= core.cpp Compile++ thumb : udt <= epoll.cpp Compile++ thumb : udt <= list.cpp Compile++ thumb : udt <= md5.cpp Compile++ thumb : udt <= packet.cpp Compile++ thumb : udt <= queue.cpp Compile++ thumb : udt <= window.cpp SharedLibrary : libudt.so SharedLibrary : libcom_barchart_udt_SocketUDT.so Install : libcom_barchart_udt_SocketUDT.so => libs/armeabi/libcom_barchart_udt_SocketUDT.so Install : libudt.so => libs/armeabi/libudt.so https://www.box.com/s/8fnduuul4epewv4i6xu5 https://www.box.com/s/2drueif1y4l82dkm81f2 please have a look~~

update: i build them all into one so https://www.box.com/s/7el2kctncig5u4x1eazh

He-Pin avatar Jan 14 '13 10:01 He-Pin

@hepin1989 thank you for the effort.

  1. to incorporate your result we need to go on path similar to how arm/rpi was supported: build a vmware android image.

  2. since google is testing their tool chains and emulators, I guess we could use x86 android ndk with cross compile to intel, arm, mips, and test only for intel, since it will be the fastest vm in vmware.

  3. building *.so is not enough; I never looked on how our java code behaves on dalvik vm, some one needs to do this.

carrot-garden avatar Jan 14 '13 23:01 carrot-garden

@carrot-garden you may not that familar with android platform ,for build the code on android ,first should write the Android.mk,to build the so,and cause some c++ feture is not support by default with the NDK,so we need an Application.mk to specify that,i think you could just install an android ADT for eclipse and setup an emulator,for vmware,the android x86 project is ok,but it not arm...

i will keep my trying this day ,thanks for your guys hard work.

@carrot-garden ,haha,you don't have an android phone,you use apple?

He-Pin avatar Jan 15 '13 01:01 He-Pin

and how about the http://code.google.com/p/bridj/ bridj https://github.com/ochafik/nativelibs4java/tree/master/libraries/BridJ quote: The BridJ project is used as the interoperability layer between Java and C++ native code. It's based on JNA, and according to BridJ developers it's much faster, however I didn't perform any tests to verify this.

He-Pin avatar Jan 15 '13 01:01 He-Pin

@hepin1989

re: "haha,you don't have an android phone,you use apple" - not true, I have one of the first nexus one phones, and I really hate apple :-)

re: "first should write the Android.mk" - yes, I know how google wants you to do build c++ on android. but this is no good for us. I suggest you try to understand how we build multi-platform java with c++ in barchart-udt using maven-nar-plugin. then hopefully you will see how to adapt google model to our model.

carrot-garden avatar Jan 15 '13 02:01 carrot-garden

re: "BridJ" - yes, I evaluated it way back. great idea, but not production ready.

carrot-garden avatar Jan 15 '13 02:01 carrot-garden

@carrot-garden re:"and I really hate apple :-)"

  • i hate apple too! re: "I suggest you try to understand how we build multi-platform java with c++ in barchart-udt using maven-nar-plugin. then hopefully you will see how to adapt google model to our model."
  • okay ,would you going to adapt the android ~?

He-Pin avatar Jan 15 '13 03:01 He-Pin

@carrot-garden i found that the android's java lib is not the same with oracle's java.so the current JNI cpp code should change to adapt the android platform

He-Pin avatar Jan 15 '13 07:01 He-Pin

ia_AddressID = env->GetFieldID(jdk_clsInet4Address, "address", "I");

the Inet4Address on android don't have the field address....but it have an name of ipaddress which is an bytes array

He-Pin avatar Jan 15 '13 09:01 He-Pin

re: "Inet4Address on android don't have the field address" - yes, this change makes sense. please submit pull request. make sure current unit tests all pass.

carrot-garden avatar Jan 15 '13 15:01 carrot-garden

@carrot-garden ,i am handling the android porting,why i always get 01-18 18:03:17.820: W/System.err(3931): com.barchart.udt.ExceptionUDT: UDT Error : 1000 : connection setup failure : bind0:bind [id: 0x22fe75cd] ,when i bind? change some method

// NOTE: ipv4 only int X_ConvertInetSocketAddressToSockaddr(JNIEnv* env, jobject objInetSocketAddress, sockaddr* sockAddr) {

CHK_NUL_RET_ERR(env, "env");
CHK_NUL_RET_ERR(sockAddr, "sockAddr");
CHK_NUL_RET_ERR(objInetSocketAddress, "objInetSocketAddress");

jobject objInetAddress = env->GetObjectField(objInetSocketAddress,
        isa_InetAddressID);
CHK_NUL_RET_ERR(objInetAddress, "objInetAddress");

#ifdef ANDROID jobject address = env->GetObjectField(objInetAddress,ia_AddressID); //cast jbyteArray * ipaddress = reinterpret_cast<jbyteArray*>(&address); jbyte data[4]; env->GetByteArrayRegion(ipaddress,0,4,data); sockaddr_in sockAddrIn = (sockaddr_in_) sockAddr; //set the address jint * intPtr = (jint_)data; sockAddrIn->sin_addr.s_addr = htonl(*intPtr); #else jint address = env->GetIntField(objInetAddress, ia_AddressID);

sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;
//set the address
sockAddrIn->sin_addr.s_addr = htonl(address);

#endif

jint port = env->GetIntField(objInetSocketAddress, isa_PortID);
sockAddrIn->sin_port = htons(port); // msvc C4244

return JNI_OK;

}

He-Pin avatar Jan 18 '13 10:01 He-Pin

please commit these changes in your fork, so I can clone your fork and reproduce this for myself. if you want, you can grant me pull/push access to your fork so I can apply fixes there.

carrot-garden avatar Jan 18 '13 17:01 carrot-garden

@carrot-garden the bug is fixed via i add the network permission in android Mainefest,this work need more test,after i test all of them, i will push them to the you,thanks.for now,i will look more deep in it to handle them on android.thanks.

He-Pin avatar Jan 19 '13 15:01 He-Pin

@carrot-garden this bug is caused by then permisson of android,i forget to add the Internet access permission for that test project. thank you.

He-Pin avatar Jan 19 '13 15:01 He-Pin

ok, great. thanks for the update.

carrot-garden avatar Jan 19 '13 15:01 carrot-garden

@carrot-garden android sending and receving test passed via NIO,an issue it that when i get the address from the socketUDT,it crash,i will going to fix that

He-Pin avatar Jan 21 '13 03:01 He-Pin

@carrot-garden i push an new branch named Android there,add i add you the permission, for the current ,the test can run and build. there are some isussue such as get the socketAddress from the socketUDT.

i am really wanna you to apply some fixes there.thanks a lot

He-Pin avatar Jan 21 '13 07:01 He-Pin

@carrot-garden i am leanning maven,so i can not handle it now,sorry for that

He-Pin avatar Jan 21 '13 07:01 He-Pin

@hepin1989 please:

  • try to arrange your experimental project so you do not duplicate existing code
  • do not commit /bin/*. and other build results to the source
  • add .gitignore to your test project

carrot-garden avatar Jan 21 '13 13:01 carrot-garden

@hepin1989 re: "i am leanning maven" - great, take your time. consider converting your experimental project to http://code.google.com/p/maven-android-plugin/

carrot-garden avatar Jan 21 '13 13:01 carrot-garden

@hepin1989 android-support-v4.jar probably should change to v11.

carrot-garden avatar Jan 21 '13 13:01 carrot-garden

@hepin1989 please review changes I made in your fork/branch https://github.com/hepin1989/barchart-udt/commits/android

carrot-garden avatar Jan 21 '13 16:01 carrot-garden

@carrot-garden i think that we should remove the sl4j api instead of android's logcat

He-Pin avatar Jan 22 '13 02:01 He-Pin

@carrot-garden hi carrot,i move the project to here https://github.com/hepin1989/barchart-udt-android.git to make it allitle clean,and i copy all your changes to there. there is a bug when i call the get socket address for the java side ,that issue must cause by the function int X_ConvertSockaddrToInetSocketAddress(JNIEnv* env, sockaddr* sockAddr, jobject objInetSocketAddress)

could you help to fix it?!thanks your effort

He-Pin avatar Jan 22 '13 03:01 He-Pin

I do not see this issue in this project https://github.com/hepin1989/barchart-udt/commits/android

your test app seem to run fine both in android-9 emulator and android v 2.3.6 real phone

01-22 10:45:01.083: I/System.out(410): send data
01-22 10:45:01.083: I/System.out(410): readed bytes data from remote server
01-22 10:45:01.083: I/System.out(410): data :java.nio.ReadWriteHeapByteBuffer, status: capacity=1024 position=0 limit=4
01-22 10:45:01.083: I/System.out(410): data in string :haha

carrot-garden avatar Jan 22 '13 16:01 carrot-garden

re: 'remove the sl4j api" - I suggest we use http://www.slf4j.org/android/

carrot-garden avatar Jan 22 '13 16:01 carrot-garden

@carrot-garden the issue is quick fixed by the code change below: in SocketUDT.java ,line 1538 @Override public String toString() {

/* return String.format( // "[id: 0x%08x] %s %s bind=%s:%s peer=%s:%s", // socketID, // type, // status(), // getLocalInetAddress(), // getLocalInetPort(), // getRemoteInetAddress(), // getRemoteInetPort() // );*/ //comment this for the get address issue on android return String.format( // "[id: 0x%08x] %s %s", // socketID, // type, // status()); }

this issue is cause by the getRemoteInetAddress(),getLocalInetAddress() call,this call will call the native code to change socketAddr to inetSocketAddress,the native code lay in JNIHelper.cpp int X_ConvertSockaddrToInetSocketAddress(JNIEnv* env, sockaddr* sockAddr, jobject objInetSocketAddress)

so if your want to reproduce the issue,just chage the comment back to your origin code

He-Pin avatar Jan 23 '13 02:01 He-Pin

@carrot-garden thanks,do you have any plan for android?

He-Pin avatar Feb 06 '13 13:02 He-Pin