Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
TPF
jack2
Commits
4a94e129
Commit
4a94e129
authored
Feb 05, 2014
by
KimJeongYeon
Browse files
jack2 supports android devices & rebase current changes to master
parent
0742159c
Changes
50
Expand all
Hide whitespace changes
Inline
Side-by-side
android/Android.mk
0 → 100644
View file @
4a94e129
This diff is collapsed.
Click to expand it.
android/AndroidShm.cpp
0 → 100644
View file @
4a94e129
#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
;
}
};
android/AndroidShm.h
0 → 100644
View file @
4a94e129
#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
android/AndroidShmServer/main_androidshmservice.cpp
0 → 100644
View file @
4a94e129
#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
;
}
android/AndroidShmServer/readme.txt
0 → 100644
View file @
4a94e129
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
android/AndroidShmServer/test/shmservicedump.cpp
0 → 100644
View file @
4a94e129
#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
;
}
android/AndroidShmServer/test/shmservicetest.cpp
0 → 100644
View file @
4a94e129
#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
;