HiI'm currently working on a project to port some hardware to android. We need to run it as a native daemon, (as root is fine), and to build a SDK so people can communicate with it.I've found a lot of different into on how to get this working. The hardware relies on low latency between hardware and client application. We've looked into ashmem, (and been recommended to not ever touch it), and the android Binder.My current attempt is building https://github.com/keesj/Android-HelloWorldService into android_source/packages/apps/Android-HelloWorldService. Building this produces two c++ native applications. If I as root run them both they can communicate, but I can't get that to build an apk for a client side app, and I'm not sure how to go about doing it either.Am I doing about this the right way? We need low latency communication between the daemon and the client side applications.I think what I'll eventually end up with is:1. Our current library, cross compiled to a shared library using gcc4.6 for arm. (GCC 4.5 or higher is a build requirement, current NDK is 4.4).2. A daemon that links to the library above + has binder code. I was thinking just using init.d to start this on boot.3. A client native library that connects to the binder above. (The one from HelloWorldService works, but I have to run it as root to get it to connect).4. A java wrapper for the library above.5. A demo app using our library.And I guess per device we put the hardware in we'll need to build step 2 and 3 and push them to the device. Installing #2 and possibly something in #3 as root.Best regardsN--
unsubscribe: android-porti...@googlegroups.com
website: http://groups.google.com/group/android-porting
As luck would have it, I actually just did exactly what you're talking about, though we're only moving barcodes around, and on account of the simplicity of the data we just used Binder to move everything. Native -> Java was simple enough; we just implemented a Binder on the Java side and put it into ServiceManager. The native daemon grabs the binder via the native side of ServiceManager, and it's that simple. I'm not sure if we're being entirely kosher with our usage, or if the latency would be low enough to be useful for you, but it's certainly lower latency than the keyboard wedge we were using before.
On Thursday, June 21, 2012 1:56:25 AM UTC-4, neuron wrote:HiWe are planning to bundle this with devices. So the highest performance lowest latency option is to send the ashmem fd through a binder? This was my original plan, but I had several people saying dont link directly to cutils, use the binder api instead, as it's a more stable interface.
On Thursday, June 21, 2012 4:22:11 AM UTC+2, Dianne Hackborn wrote:
Are you intending this to be a regular third party app that you build against the SDK, or as something built against a specific version of the source code that is bundled with the device? If the latter, why have you been told to never touch it? (Though truth be told you will probably want to use binder to transfer references to the ashmem region.)
If the former, you can't do this as pure native code, you need to use the SDK facilities like Service and the Binder interfaces in the Java language, and you definitely aren't going to be running as anything like root.
On Wed, Jun 20, 2012 at 6:32 AM, neuron <aaga...@gmail.com> wrote:
HiI'm currently working on a project to port some hardware to android. We need to run it as a native daemon, (as root is fine), and to build a SDK so people can communicate with it.I've found a lot of different into on how to get this working. The hardware relies on low latency between hardware and client application. We've looked into ashmem, (and been recommended to not ever touch it), and the android Binder.My current attempt is building https://github.com/keesj/Android-HelloWorldService into android_source/packages/apps/Android-HelloWorldService. Building this produces two c++ native applications. If I as root run them both they can communicate, but I can't get that to build an apk for a client side app, and I'm not sure how to go about doing it either.Am I doing about this the right way? We need low latency communication between the daemon and the client side applications.I think what I'll eventually end up with is:1. Our current library, cross compiled to a shared library using gcc4.6 for arm. (GCC 4.5 or higher is a build requirement, current NDK is 4.4).2. A daemon that links to the library above + has binder code. I was thinking just using init.d to start this on boot.3. A client native library that connects to the binder above. (The one from HelloWorldService works, but I have to run it as root to get it to connect).4. A java wrapper for the library above.5. A demo app using our library.And I guess per device we put the hardware in we'll need to build step 2 and 3 and push them to the device. Installing #2 and possibly something in #3 as root.Best regards
N--
unsubscribe: android-porting+unsubscribe@googlegroups.com
website: http://groups.google.com/group/android-porting
--
Dianne Hackborn
Android framework engineer
hac...@android.com
Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them.
Hi
We are planning to bundle this with devices. So the highest performance lowest latency option is to send the ashmem fd through a binder? This was my original plan, but I had several people saying dont link directly to cutils, use the binder api instead, as it's a more stable interface.
On Thursday, June 21, 2012 4:22:11 AM UTC+2, Dianne Hackborn wrote:
Are you intending this to be a regular third party app that you build against the SDK, or as something built against a specific version of the source code that is bundled with the device? If the latter, why have you been told to never touch it? (Though truth be told you will probably want to use binder to transfer references to the ashmem region.)
If the former, you can't do this as pure native code, you need to use the SDK facilities like Service and the Binder interfaces in the Java language, and you definitely aren't going to be running as anything like root.
On Wed, Jun 20, 2012 at 6:32 AM, neuron <aaga...@gmail.com> wrote:
HiI'm currently working on a project to port some hardware to android. We need to run it as a native daemon, (as root is fine), and to build a SDK so people can communicate with it.I've found a lot of different into on how to get this working. The hardware relies on low latency between hardware and client application. We've looked into ashmem, (and been recommended to not ever touch it), and the android Binder.My current attempt is building https://github.com/keesj/Android-HelloWorldService into android_source/packages/apps/Android-HelloWorldService. Building this produces two c++ native applications. If I as root run them both they can communicate, but I can't get that to build an apk for a client side app, and I'm not sure how to go about doing it either.Am I doing about this the right way? We need low latency communication between the daemon and the client side applications.I think what I'll eventually end up with is:1. Our current library, cross compiled to a shared library using gcc4.6 for arm. (GCC 4.5 or higher is a build requirement, current NDK is 4.4).2. A daemon that links to the library above + has binder code. I was thinking just using init.d to start this on boot.3. A client native library that connects to the binder above. (The one from HelloWorldService works, but I have to run it as root to get it to connect).4. A java wrapper for the library above.5. A demo app using our library.And I guess per device we put the hardware in we'll need to build step 2 and 3 and push them to the device. Installing #2 and possibly something in #3 as root.Best regards
N--
unsubscribe: android-porting+unsubscribe@googlegroups.com
website: http://groups.google.com/group/android-porting
--
Dianne Hackborn
Android framework engineer
hac...@android.com
Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them.
--
unsubscribe: android-porti...@googlegroups.com
website: http://groups.google.com/group/android-porting
Sure thing. Before I put down the code, I should mention that the native side runs as root and the other end (an Android/Java service) runs as android.uid.system-- we bundle both with our images.
On the native side, the relevant part is this. I'm cheating with SAMPLE_REQUEST_CODE-- I didn't get the base from somewhere authoritative like I did in the service, and just declared it as a constant instead. I may have missed some includes on the native side-- I still haven't cleaned up.
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
const char* SERVICE_NAME = "org.demo.helloworldservice";
int helloworld() {
android::sp<android::IServiceManager> sm = android::defaultServiceManager();
android::String16* service_name = new android::String16(SERVICE_NAME);
android::sp<android::IBinder> mBinder = sm->getService(*service_name);
delete service_name;
android::Parcel data;
android::Parcel reply;
unsigned int flags = 0;
mBinder->transact(SAMPLE_REQUEST_CODE, data, &reply, flags);
return 0;
}
And in the service:
package org.demo.helloworldservice;
import android.app.Service;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ServiceManager;
import android.util.Log;
public class HelloworldService extends Service {
private static final String SERVICE_NAME = "org.demo.helloworldservice";
private static final int SAMPLE_REQUEST_CODE = IBinder.FIRST_CALL_TRANSACTION + 0;
private IBinder mBinder = null;
private IHelloworldService mHelloworldService = null;
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onCreate(){
super.onCreate();
mHelloworldService = new IHelloworldService();
mBinder = mHelloworldService.asBinder();
ServiceManager.addService(SERVICE_NAME, mBinder);
}
class IHelloworldService extends Binder {
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags){
switch(code) {
case SAMPLE_REQUEST_CODE:
//Parcel data is the same one that was passed from native transact()
reply.write(1);
break;
default:
reply.write(0);
}
return true;
}
public IBinder asBinder() {
return this;
}
}
}
I don't know what significance, if any, the return value from onTransact bears. As far as I can tell, it doesn't have any effect from this side. For the communication with other Android-side apps, you could do another service with .aidl and have it talk to this one. I haven't tried communication the other direction (e.g. HelloworldService -> native), but I doubt it's much more complicated than this was (just implement a Binder on the native side and register it with IServiceManager). There's probably some way to get .aidl to work on both sides, but for my purposes, it wasn't worth the effort.
You have a couple of options for getting non-root apps to talk to the root HelloworldService, but those aren't hard to find information on (in the Android Developers guide on services and on Binder). I'm not sure there's any way around having to have another class for apps to talk to, which can then talk to the package-local HelloworldService, though.
Testing is pretty easy. HelloworldService has to be signed, but after that you can uninstall/reinstall/start with am, and the native component can be built, pushed, and started from adb shell. We're building the native component in-tree, so it was a matter of a couple of seconds to build with mm and push.
Latency-wise it's proving to be pretty good. Even with the added overhead of a Settings check, creation/broadcast/reception of a broadcast intent, and copying of the intent payload into a text element, it can push out easily 20-30 barcodes a second.
Hope this helps.
Jay
--
unsubscribe: android-porti...@googlegroups.com
website: http://groups.google.com/group/android-porting