Question

I'm working on a custom version of Android on a device with a closed source camera HAL, so I've had to add a camera wrapper, which is a lib that Android loads instead of the vendor camera, so that bugs and peculiarities with the vendor implementation can be worked around. I've found that I need to vary the behavior between apps, so that while in Snapchat I don't want to implement a certain parameter, for example, Hangouts crashes if I don't set it. The problem is Android doesn't tell the camera which app is using it. I tried the following code to see what my pid was but the result was "/system/bin/mediaserver" not exactly what I had in mind. Asking for parent id was even worse, it just returned 1. What I seek is trivial in Android java, but I'm constrained to C and whatever includes I can find in Bionic here. Any help?

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

later

const static char * whiteList[] = {"com.android.camera2"};
const static int whiteListLen = 1;
const pid_t pid = getpid();
char plink[64];
char pname[64];
FILE *fptr;
snprintf(plink, sizeof(plink), "/proc/%i/cmdline", pid);
fptr = fopen(plink, "r");
if (fptr != NULL) {
    ALOGD("Determining name of running PID %i", pid);
    fscanf(fptr, "%s", pname);
    ALOGD("Process is %s", pname);
    for(int i = 0; i < whiteListLen; i++) {
        if(strcmp(whiteList[i], pname) == 0) {
            ALOGD("Camera opened by whitelisted app %s, enabling XXX.", pname);
            XXX;
            break;
            }
        }
} else {
    ALOGD("Unable to open /proc/%i/cmdline", pid);
}
fclose(fptr);
Was it helpful?

Solution

The problem is Android doesn't tell the camera which app is using it.

It does via libbinder and the BinderAPIs. As a service process (like mediaserver) all caller requests will have their calling process information stored as part of the Binder transaction. This is how all major services enforce permissions, they have to know who the request came from!

At the Java layer, this is easy enough to request with Binder.getCallingPid(). In native code, you will have to link against libbinder and use something like:

IPCThreadState::self()->getCallingPid()

which is what the Java wrapper does under the hood.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top