Commit 4a94e129 authored by KimJeongYeon's avatar KimJeongYeon
Browse files

jack2 supports android devices & rebase current changes to master

parent 0742159c
This diff is collapsed.
#define LOG_TAG "JAMSHMSERVICE"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <binder/MemoryHeapBase.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <utils/Log.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include "BnAndroidShm.h"
#include "AndroidShm.h"
#include "JackConstants.h"
#include <fcntl.h>
#include <signal.h>
#include <limits.h>
#include <errno.h>
#include <dirent.h>
#include <sys/mman.h>
#include <linux/ashmem.h>
#include <cutils/ashmem.h>
#include "JackError.h"
#include <semaphore.h>
#define MEMORY_SIZE 10*1024
#define SEMAPHORE_NULL_CHAR '\0'
// remove ALOGI log
#undef ALOGI
#define ALOGI
namespace android {
int AndroidShm::instantiate() {
defaultServiceManager()->addService(String16("com.samsung.android.jam.IAndroidShm"), new AndroidShm); // SINGLETON WITH SAME NAME
return 0;
}
int AndroidShm::sendCommand(const char* command) {
ALOGI("I(pid:%d) send command is %s\n", getpid(), command);
if(strcmp(command, "semaphore") == 0) {
// print debug message about semaphore simulation
for(int i = MAX_SEMAPHORE_MEMORY_COUNT -1 ; i >= 0; i--) {
printf("index[%3d] = ptr[%p] name[%s]\n", i, (mSemaphore[i] != NULL)?mSemaphore[i]->getBase():0, mSemaphoreName[i]);
ALOGI("index[%3d] = ptr[%p] name[%s]\n", i, (mSemaphore[i] != NULL)?mSemaphore[i]->getBase():0, mSemaphoreName[i]);
}
}
return NO_ERROR;
}
int AndroidShm::testGetBufferByNewProcess() {
ALOGI("testGetBufferByNewProcess...");
int status;
int childPid = fork();
if(childPid > 0) {
ALOGI("I(pid%d) made a child process(pid:%d)", getpid(), childPid);
ALOGI("I(pid%d) wait until child(%d) was finish", getpid(), childPid);
wait(&status);
// wait 하지 않으면 child process가 남아 있음.
ALOGI("child(%d) was finished. ", childPid);
} else if(childPid == 0) {
ALOGI("im a new child process(pid:%d) ", getpid());
if(-1 == execlp("/system/bin/getbufferclient","getbufferclient",NULL)) {
ALOGE("failed to execute getbufferclient");
}
exit(0);
} else {
ALOGI("failed creating child process");
}
return 0;
}
int AndroidShm::testGetBuffer() {
ALOGI("I(pid:%d) trying to test get buffer...", getpid());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("get default ServiceManager is done");
sp<IBinder> b;
//String16* serviceName = new String16("com.samsung.android.jam.IAndroidShm");
do {
//ALOGI("here");
b = sm->getService(String16("com.samsung.android.jam.IAndroidShm"));
//ALOGI("getservice is done");
if(b != 0)
break;
//ALOGI("AndroidShm is not working, waiting...");
usleep(500000);
} while(true);
sp<IAndroidShm> service = interface_cast<IAndroidShm>(b);
//shared buffer.
sp<IMemoryHeap> receiverMemBase = service->getBuffer(0);
unsigned int *base = (unsigned int *) receiverMemBase->getBase();
int ret = 0;
if(base != (unsigned int *) -1) {
ALOGD("AndroidShm::testGetBuffer base=%p Data=0x%x\n",base, *base);
*base = (*base)+1;
ret = (unsigned int)(*base);
ALOGI("AndroidShm::testGetBuffer base=%p Data=0x%x CHANGED\n",base, *base);
receiverMemBase = 0;
} else {
ALOGE("Error shared memory not available\n");
}
return 0;
}
sp<IMemoryHeap> AndroidShm::getBuffer(int index) {
ALOGI("I(pid:%d) getBuffer index:%d", getpid(), index);
if(index < 0 || index >= MAX_SHARED_MEMORY_COUNT) {
ALOGE("error : out of index [%d]", index);
return NULL;
}
return mMemHeap[index];
}
int AndroidShm::MemAlloc(unsigned int size) {
ALOGI("try to allocate memory size[%d]", size);
for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) {
if(mMemHeap[i] == NULL) {
mMemHeap[i] = new MemoryHeapBase(size);
if(mMemHeap[i] == NULL){
ALOGI("fail to alloc, try one more...");
continue; // try one more.
}
return i;
}
}
ALOGE("fail to MemAlloc");
return -1; // fail to alloc
}
AndroidShm::AndroidShm() {
ALOGI("AndroidShm is created");
for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) {
mMemHeap[i] = NULL;
}
mRegistryIndex = 10000;
//mMemHeap = new MemoryHeapBase(MEMORY_SIZE);
//unsigned int *base = (unsigned int*) mMemHeap->getBase();
//*base = 0xdeadcafe;//
for(int j = 0; j < MAX_SEMAPHORE_MEMORY_COUNT; j++) {
mSemaphore[j] = NULL;
memset(mSemaphoreName[j], SEMAPHORE_NULL_CHAR, MAX_SEMAPHORE_NAME_LENGTH);
}
}
AndroidShm::~AndroidShm() {
ALOGI("AndroidShm is destroyed");
for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) {
(mMemHeap[i]).clear();
}
for(int j = 0; j < MAX_SEMAPHORE_MEMORY_COUNT; j++) {
(mSemaphore[j]).clear();
}
}
//status_t AndroidShm::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
// return BnAndroidShm::onTransact(code, data, reply, flags);
//}
int AndroidShm::allocShm(const int size) { // if negative return value is error
ALOGI("try to alloc shared memory size[%d]", size);
return MemAlloc(size);
}
int AndroidShm::removeShm(const unsigned int index) { // shared memory 제거
ALOGI("try to remove shared memory index[%d]", index);
if(index >= MAX_SHARED_MEMORY_COUNT) {
ALOGE("remove shared memory: out of index");
return -1;
}
(mMemHeap[index]).clear();
return 1;
}
int AndroidShm::isAllocated(const unsigned int index) { // allocated 여부 확인
ALOGI("try to check the memory allocation index[%d]", index);
if(index >= MAX_SHARED_MEMORY_COUNT) {
ALOGE("shared memory: out of index");
return 0;
}
if(mMemHeap[index] == NULL)
return 0;
else
return 1;
}
int AndroidShm::setRegistryIndex(const unsigned int index) {
ALOGI("set registry index %d", index);
mRegistryIndex = index;
return 1;
}
int AndroidShm::getRegistryIndex() {
return mRegistryIndex;
}
sp<IMemoryHeap> AndroidShm::InitSemaphore(const char* name) {
ALOGI("init semaphore [%s]", name);
for(int i = 0; i < MAX_SEMAPHORE_MEMORY_COUNT; i++) {
if(mSemaphoreName[i][0] == SEMAPHORE_NULL_CHAR) {
mSemaphore[i] = new MemoryHeapBase(sizeof(sem_t));
if(mSemaphore[i] == NULL){
ALOGI("fail to alloc, try one more...");
continue;
}
if(sem_init((sem_t*)(mSemaphore[i]->getBase()), 1, 0) == 0) {
strncpy(mSemaphoreName[i], name, MAX_SEMAPHORE_NAME_LENGTH - 1);
mSemaphoreName[i][MAX_SEMAPHORE_NAME_LENGTH - 1] = '\0';
ALOGI("sem_init success");
return mSemaphore[i];
} else {
(mSemaphore[i]).clear();
ALOGE("sem_init failed null returned");
return NULL;
}
} else {
// find already exist name
if(strcmp(mSemaphoreName[i], name) == 0) { // found
ALOGI("found - return alread allocated semaphore");
return mSemaphore[i];
}
}
}
ALOGE("sem_init failed null returned 2");
return NULL;
}
};
#ifndef ANDROIDSHM
#define ANDROIDSHM
#include <binder/Parcel.h>
#include "BnAndroidShm.h"
#include <utils/Log.h>
#include <binder/MemoryHeapBase.h>
#include "shm.h"
#include "android/Shm.h" //android extension of shm.h
namespace android {
class AndroidShm : public BnAndroidShm
{
#define MAX_SHARED_MEMORY_COUNT 257
private:
int MemAlloc(unsigned int size);
public:
virtual ~AndroidShm();
static int instantiate();
virtual int sendCommand(const char* command);
virtual int allocShm(const int size); // if negative return value is error
virtual int removeShm(const unsigned int index); // shared memory
virtual int isAllocated(const unsigned int index); // allocated Ȯ
virtual int setRegistryIndex(const unsigned int index);
virtual int getRegistryIndex();
virtual sp<IMemoryHeap> InitSemaphore(const char* name);
virtual sp<IMemoryHeap> getBuffer(int index);
//virtual status_t onTransact(
// uint32_t code,
// const Parcel& data,
// Parcel* reply,
// uint32_t flags);
private:
int testGetBuffer();
int testGetBufferByNewProcess();
AndroidShm();
sp<MemoryHeapBase> mMemHeap[MAX_SHARED_MEMORY_COUNT];
unsigned int mRegistryIndex;
// for named semaphore simulation
#define MAX_SEMAPHORE_MEMORY_COUNT 300
#define MAX_SEMAPHORE_NAME_LENGTH 300
sp<MemoryHeapBase> mSemaphore[MAX_SEMAPHORE_MEMORY_COUNT];
char mSemaphoreName[MAX_SEMAPHORE_MEMORY_COUNT][MAX_SEMAPHORE_NAME_LENGTH];
};
};
#endif
#define LOG_TAG "main_androidshmservice"
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include "../../common/shm.h"
#include "../Shm.h" //android extension of shm.h
using namespace android;
int main(int argc, char *argv[]) {
jack_instantiate();
ProcessState::self()->startThreadPool();
ALOGI("AndroidShmService is starting now");
IPCThreadState::self()->joinThreadPool();
return 0;
}
IAndroidShm의 기능을 테스트 하기 위한 용도로 사용되는 프로그램입니다.
AndroidShm은 service manager에 shared memory를 할당해주는 서비스입니다.
service name: com.sec.apa.IAndroidShm
실행 파일:
/system/bin/androidshmservice
-------------------------------------------
./test
AndroidShmService를 테스트하는 프로그램
/system/bin/shmservicetest
AndroidShmService에서 제공하는 기능을 UnitTest합니다.
동작 확인 방법:
adb logcat 으로 로그로 성공/실패 확인함.
전제 조건:
/system/bin/androidshmservice를 실행중인 상태이어야 합니다.
\ No newline at end of file
#include "../../IAndroidShm.h"
#include <binder/MemoryHeapBase.h>
#include <binder/IServiceManager.h>
#include "../../../common/shm.h"
namespace android {
static sp<IMemoryHeap> receiverMemBase;
#define MAX_SHARED_MEMORY_COUNT 257
sp<IAndroidShm> getAndroidShmService() {
sp<IAndroidShm> shm = 0;
/* Get the buffer service */
if (shm == NULL) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
binder = sm->getService(String16("com.samsung.android.jam.IAndroidShm"));
if (binder != 0) {
shm = IAndroidShm::asInterface(binder);
//shm = interface_cast<IAndroidShm>(binder);
}
}
return shm;
}
unsigned int * getBufferMemPointer(int index)
{
sp<IAndroidShm> shm = getAndroidShmService();
if (shm == NULL) {
printf("The EneaBufferServer is not published\n");
return (unsigned int *)-1; /* return an errorcode... */
} else {
receiverMemBase = shm->getBuffer(index);
if(receiverMemBase != NULL)
return (unsigned int *) receiverMemBase->getBase();
else
return (unsigned int*)-1;
}
}
}
using namespace android;
void showStatus() {
sp<IAndroidShm> shm = getAndroidShmService();
if(shm == NULL) {
printf("shm service is not available\n");
return;
}
printf("<<<<<<<<<<< dump memory allocation status >>>>>>>>>>\n");
for(int i = 256; i >= 0; i--) {
if(shm->isAllocated(i) == 1) {
printf("Mem[%3d] == 0x%x\n", i, (unsigned int)getBufferMemPointer(i));
} else {
printf("Mem[%3d] == NULL\n", i);
}
}
}
void showRegistryIndex() {
sp<IAndroidShm> shm = getAndroidShmService();
if(shm == NULL) {
printf("shm service is not available\n");
return;
}
printf("<<<<<<<<<<< show registry index >>>>>>>>>>\n");
printf("index [%3d]\n",shm->getRegistryIndex());
}
void showHeader() {
sp<IAndroidShm> shm = getAndroidShmService();
if(shm == NULL) {
printf("shm service is not available\n");
return;
}
if(shm->getRegistryIndex() > 256) {
printf("don't have a registry header\n");
return;
}
unsigned int* buffer = getBufferMemPointer(shm->getRegistryIndex());
if(buffer) {
jack_shm_header_t * header = (jack_shm_header_t*)buffer;
printf("<<<<<<<<<< register header value >>>>>>>>>>\n");
printf("memory address 0x%x 0x%x\n", (unsigned int)(header), (unsigned int)buffer);
printf("magic = %d\n", header->magic);
printf("protocol = %d\n", header->protocol);
printf("type = %d\n", header->type);
printf("size = %d\n", header->size);
printf("hdr_len = %d\n", header->hdr_len);
printf("entry_len = %d\n", header->entry_len);
for(int j = 0; j < MAX_SERVERS; j++) {
//char name[256];
//memset(name, '\0', 256);
//strncpy(name, header->server[j].name, 10);
printf("server[%d] pid = %d, name = %s\n", j, header->server[j].pid, header->server[j].name);
}
}
}
void showBody() {
sp<IAndroidShm> shm = getAndroidShmService();
if(shm == NULL) {
printf("shm service is not available\n");
return;
}
if(shm->getRegistryIndex() > 256) {
printf("don't have a registry body\n");
return;
}
unsigned int* buffer = getBufferMemPointer(shm->getRegistryIndex());
if(buffer) {
jack_shm_header_t * header = (jack_shm_header_t*)buffer;
printf("<<<<<<<<<< registry body value >>>>>>>>>>\n");
jack_shm_registry_t * registry = (jack_shm_registry_t *) (header + 1);
for(int k = 255; k >= 0; k--) {
printf("registry[%3d] index[%3d],allocator[%3d],size[%6d],id[%10s],fd[%3d]\n", k,
registry[k].index, registry[k].allocator, registry[k].size,
registry[k].id,
registry[k].fd);
}
}
}
void showSemaphore() {
sp<IAndroidShm> shm = getAndroidShmService();
if(shm == NULL) {
printf("shm service is not available\n");
return;
}
shm->sendCommand("semaphore");
printf("log will be shown in the logcat log\n");
}
int main(int argc, char** argv) {
// base could be on same address as Servers base but this
// is purely by luck do NEVER rely on this. Linux memory
// management may put it wherever it likes.
if(argc < 2) {
printf("usage\n shmservicedump [status|header|body|index|semaphore]\n");
printf(" status: show the shared memory allocation status\n");
printf(" header: show the registry header infomations if the registry exist\n");
printf(" body: show the registry body infomations if the registry exist\n");
printf(" index: show the index of array that is allocated registry shared memory\n");
printf(" semaphore: show the memory array about semaphore simulation\n");
return 0;
}
if(strcmp(argv[1], "semaphore") == 0) {
showSemaphore();
} else if(strcmp(argv[1], "index") == 0) {
showRegistryIndex();
} else if(strcmp(argv[1], "status") == 0) {
showStatus();
} else if(strcmp(argv[1], "header") == 0) {
showHeader();
} else if(strcmp(argv[1], "body") == 0) {
showBody();
} else {
printf("%s is invalid parameter\n", argv[1]);
}
return 0;
}
#include "../../IAndroidShm.h"
#include <binder/MemoryHeapBase.h>
#include <binder/IServiceManager.h>
namespace android {
static sp<IMemoryHeap> receiverMemBase;
#define MAX_SHARED_MEMORY_COUNT 257
sp<IAndroidShm> getAndroidShmService() {
sp<IAndroidShm> shm = 0;
/* Get the buffer service */
if (shm == NULL) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
binder = sm->getService(String16("com.samsung.android.jam.IAndroidShm"));
if (binder != 0) {
shm = IAndroidShm::asInterface(binder);
//shm = interface_cast<IAndroidShm>(binder);
}
}
return shm;
}
unsigned int * getBufferMemPointer(int index) {
sp<IAndroidShm> shm = getAndroidShmService();
if (shm == NULL) {
ALOGE("The EneaBufferServer is not published");
return (unsigned int *)-1; /* return an errorcode... */
} else {
receiverMemBase = shm->getBuffer(index);
if(receiverMemBase != NULL)
return (unsigned int *) receiverMemBase->getBase();
else
return (unsigned int*)-1;
}
}
}
using namespace android;
void setup_test() {
sp<IAndroidShm> shm = getAndroidShmService();
if(shm == NULL) return;
for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) {
shm->removeShm(i);
}
}
void teardown_test() {
}
void increase_value_once() {
ALOGD("*****test: increase_value_once*****\n");
sp<IAndroidShm> shm = getAndroidShmService();
if(shm == NULL) return;
int slot = shm->allocShm(10000);
unsigned int *base = getBufferMemPointer(slot);
if(base != (unsigned int *)-1) {
ALOGD("ShmServiceTest base=%p Data=0x%x\n",base, *base);
*base = (*base)+1;
ALOGD("ShmServiceTest base=%p Data=0x%x CHANGED\n",base, *base);
//receiverMemBase = 0;
} else {
ALOGE("Error shared memory not available\n");
}
}
void increase_value_10times() {
ALOGD("*****test: increase_value_10times*****\n");
sp<IAndroidShm> shm = getAndroidShmService();
if(shm == NULL) return;