Ref.
http://wangkuiwu.github.io/2014/09/03/Binder-ServiceManager-Daemon/
[The example is a system app send message through binder to mediaserver audio]
Target:
1.
external/sepolicy/system_app.te
type system_app, domain;
app_domain(system_app)
net_domain(system_app)
### begin issue: ###
binder_use(system_app)
binder_call(system_app, binderservicedomain)
binder_call(system_app, appdomain)
### end issue: ###
binder_service(system_app)
2.
external/sepolicy/service_contexts
media.audio_flinger u:object_r:mediaserver_service:s0
### begin issue: ###
media.audio_openal u:object_r:mediaserver_service:s0
### end issue: ###
media.audio_policy u:object_r:mediaserver_service:s0
3.
device/fsl/matrix_io/matrix_io.mk
...
...
...
SUPPORT_OPENAL := true
ifeq ($(SUPPORT_OPENAL),true)
PRODUCT_PACKAGES += OpenalConfig
PRODUCT_COPY_FILES += \
frameworks/av/media/libnbaio/default-44100.mhr:system/media/audio/default-44100.mhr \
frameworks/av/media/libnbaio/default-48000.mhr:system/media/audio/default-48000.mhr \
frameworks/av/media/libnbaio/eq.txt:system/media/audio/eq.txt
endif
4.
frameworks/av/media/mediaserver
#include "SoundTriggerHwService.h"
#include "RadioService.h"
/*begin issue:*/
#include <media/nbaio/AudioStreamOutSink.h>
/*end issue:*/
MediaPlayerService::instantiate();
/*begin issue:*/
#ifdef AL_ALEXT_PROTOTYPES
OpenAlStreamMessage::instantiate();
#endif
/*end issue:*/
ResourceManagerService::instantiate();
5.
frameworks/av/include/media/nbaio/AudioStreamOutSink.h
#ifndef ANDROID_AUDIO_STREAM_OUT_SINK_H
#define ANDROID_AUDIO_STREAM_OUT_SINK_H
#include <hardware/audio.h>
#include "NBAIO.h"
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
namespace android
{
#ifdef AL_ALEXT_PROTOTYPES
class IOpenAlStreamMessage: public IInterface
{
public:
enum
{
APP_MESSAGE = IBinder::FIRST_CALL_TRANSACTION,
};
//DECLARE_META_INTERFACE(OpenAlStreamMessage)
static const android::String16 descriptor;
static android::sp<IOpenAlStreamMessage> asInterface(const android::sp<android::IBinder>& obj);
virtual const android::String16& getInterfaceDescriptor() const;
IOpenAlStreamMessage();
virtual ~IOpenAlStreamMessage();
virtual void BindMessage(int command) = 0;
};
/****************************************************/
/****************************************************/
/****************************************************/
class BpOpenAlStreamMessage : public BpInterface<IOpenAlStreamMessage>
{
public:
BpOpenAlStreamMessage(const sp<IBinder>& impl) : BpInterface<IOpenAlStreamMessage>(impl)
{
}
virtual void BindMessage(int32_t val);
};
/****************************************************/
/****************************************************/
/****************************************************/
class BnOpenAlStreamMessage : public BnInterface<IOpenAlStreamMessage>
{
public:
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
};
class OpenAlStreamMessage : public BnOpenAlStreamMessage
{
public:
static void instantiate();
OpenAlStreamMessage();
~OpenAlStreamMessage();
virtual void BindMessage(int command);
};
#endif
...
...
...
} // namespace android
#endif // ANDROID_AUDIO_STREAM_OUT_SINK_H
6.
frameworks/av/media/libnbaio/AudioStreamOutSink.cpp
namespace android
{
#ifdef AL_ALEXT_PROTOTYPES
const android::String16 IOpenAlStreamMessage::descriptor("media.audio_openal");
android::sp<IOpenAlStreamMessage> IOpenAlStreamMessage::asInterface(const android::sp<android::IBinder>& obj)
{
android::sp<IOpenAlStreamMessage> intr;
if (obj != NULL)
{
intr = static_cast<IOpenAlStreamMessage*>(obj->queryLocalInterface(IOpenAlStreamMessage::descriptor).get());
if (intr == NULL)
{
intr = new BpOpenAlStreamMessage(obj);
}
}
return intr;
}
const android::String16& IOpenAlStreamMessage::getInterfaceDescriptor() const
{
return IOpenAlStreamMessage::descriptor;
}
IOpenAlStreamMessage::IOpenAlStreamMessage()
{
}
IOpenAlStreamMessage::~IOpenAlStreamMessage()
{
}
/****************************************************/
/****************************************************/
/****************************************************/
void BpOpenAlStreamMessage::BindMessage(int32_t val)
{
Parcel data, reply;
data.writeInterfaceToken(IOpenAlStreamMessage::getInterfaceDescriptor());
data.writeInt32(val);
remote()->transact(APP_MESSAGE, data, &reply);
}
/****************************************************/
/****************************************************/
/****************************************************/
status_t BnOpenAlStreamMessage::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code)
{
case APP_MESSAGE:
{
CHECK_INTERFACE(IOpenAlStreamMessage, data, reply);
int32_t val;
val = data.readInt32();
BindMessage(val);
return NO_ERROR;
}
break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
/****************************************************/
/****************************************************/
/****************************************************/
void OpenAlStreamMessage::instantiate()
{
defaultServiceManager()->addService(String16("media.audio_openal"), new OpenAlStreamMessage());
}
OpenAlStreamMessage::OpenAlStreamMessage()
{
}
OpenAlStreamMessage::~OpenAlStreamMessage()
{
}
void OpenAlStreamMessage::BindMessage(int command)
{
s_alsa_save = command; //get message here
}
#endif
...
...
...
}
Client App:
1.
//A new system app
packages/apps/OpenalConfig/AndroidManifest.xml
package="com.android.openalconfig"
android:sharedUserId="android.uid.system" -->add here
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
...
...
...
2.
packages/apps/OpenalConfig/Android.mk
### begin issue: ###
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false ###--> add this important
LOCAL_JNI_SHARED_LIBRARIES := libmessagebinder ###--> add this for java load
LOCAL_PACKAGE_NAME := OpenalConfig
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_SDK_VERSION := current
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)
# Use the folloing include to make our test apk.
include $(call all-makefiles-under,$(LOCAL_PATH))
### end issue: ###
3.
packages/apps/OpenalConfig/jni/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libmessagebinder
LOCAL_CFLAGS := -std=c++11
LOCAL_C_INCLUDES := \
../../../system/core/include \
../../../frameworks/av/include \
../../../frameworks/native/include
LOCAL_SRC_FILES := \
../cc_src/jniapi.cpp \
../cc_src/interfacefuncs.cpp
### installed app build by ndk toolchain ###
#LOCAL_LDLIBS := \
#-L../../../../out/matrix_io/android/target/product/matrix_io/symbols/system/lib/ \
#-llog \
#-lutils \
#-lbinder
### system app build by mm ###
LOCAL_SHARED_LIBRARIES := \
liblog \
libutils \
libbinder
include $(BUILD_SHARED_LIBRARY)
4.
packages/apps/OpenalConfig/cc_src/jniapi.cpp
#include <jni.h>
#include <android/native_window.h> // requires ndk r5 or newer
#include <android/native_window_jni.h> // requires ndk r5 or newer
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "interfacefuncs.h"
#include "jniapi.h"
JNIEXPORT void JNICALL Java_com_android_openalconfig_OpenalConfig_nativeBindMessage(JNIEnv* env, jobject obj, jint command)
{
Interface_BindMessage(env, obj, command);
}
5.
packages/apps/OpenalConfig/cc_src/interfacefuncs.h
#ifndef INTERFACEFUNCS_H__
#define INTERFACEFUNCS_H__
namespace android
{
class IOpenAlStreamMessage: public IInterface
{
public:
enum
{
APP_MESSAGE = IBinder::FIRST_CALL_TRANSACTION,
};
//DECLARE_META_INTERFACE(OpenAlStreamMessage)
static const android::String16 descriptor;
static android::sp<IOpenAlStreamMessage> asInterface(const android::sp<android::IBinder>& obj);
virtual const android::String16& getInterfaceDescriptor() const;
IOpenAlStreamMessage();
virtual ~IOpenAlStreamMessage();
virtual void BindMessage(int command) = 0;
};
class BpOpenAlStreamMessage : public BpInterface<IOpenAlStreamMessage>
{
public:
BpOpenAlStreamMessage(const sp<IBinder>& impl) : BpInterface<IOpenAlStreamMessage>(impl)
{
}
virtual void BindMessage(int32_t val);
};
}
extern void Interface_BindMessage(JNIEnv* env, jobject obj, jint command);
#endif // AndroidUtils_h__
6.
packages/apps/OpenalConfig/cc_src/interfacefuncs.cpp
#include <stdio.h>
#include <jni.h>
#include <android/log.h>
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "interfacefuncs.h"
using namespace android;
static JavaVM* s_JavaVM = NULL;
static int s_loop = 0;
extern "C"
{
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env;
if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK)
{
return -1;
}
s_JavaVM = vm; //save to use this for the rest of the app. Not neccesarily safe to use the Env passed in though.
return JNI_VERSION_1_4;
}
}
static JNIEnv* GetJavaEnv()
{
JNIEnv *env = NULL;
s_JavaVM->GetEnv((void **)&env, JNI_VERSION_1_4);
if (!env)
{
return NULL;
}
return env;
}
/****************************************************/
/****************************************************/
/****************************************************/
const android::String16 IOpenAlStreamMessage::descriptor("media.audio_openal");
android::sp<IOpenAlStreamMessage> IOpenAlStreamMessage::asInterface(const android::sp<android::IBinder>& obj)
{
android::sp<IOpenAlStreamMessage> intr;
if (obj != NULL)
{
intr = static_cast<IOpenAlStreamMessage*>(obj->queryLocalInterface(IOpenAlStreamMessage::descriptor).get());
if (intr == NULL)
{
intr = new BpOpenAlStreamMessage(obj);
}
}
return intr;
}
const android::String16& IOpenAlStreamMessage::getInterfaceDescriptor() const
{
return IOpenAlStreamMessage::descriptor;
}
IOpenAlStreamMessage::IOpenAlStreamMessage()
{
}
IOpenAlStreamMessage::~IOpenAlStreamMessage()
{
}
/****************************************************/
/****************************************************/
/****************************************************/
void BpOpenAlStreamMessage::BindMessage(int32_t val)
{
Parcel data, reply;
data.writeInterfaceToken(IOpenAlStreamMessage::getInterfaceDescriptor());
data.writeInt32(val);
remote()->transact(APP_MESSAGE, data, &reply);
}
/****************************************************/
/****************************************************/
/****************************************************/
void Interface_BindMessage(JNIEnv* env, jobject obj, jint command)
{
sp<IBinder> binder = defaultServiceManager()->getService(String16("media.audio_openal"));
sp<IOpenAlStreamMessage> pfunc = interface_cast<IOpenAlStreamMessage>(binder);
pfunc->BindMessage(command);
}
Download:
http://www.mediafire.com/file/84qu8sdml46a104/binder.tar.gz
沒有留言:
張貼留言