App:系统级应用程序。(第三方应用程序和系统及应用程序(权限比较大))
Bin:binary 二进制可执行程序(一种是 shell,一种是 c 编译的可执行文件,一般是 命令)
Framework:框架 安卓核心框架. .jar 就是 java库,可以执行,也可以当依赖包,(apk 应用程序的库,开发接口都在这里)。
相同的程序,在不同的版本上,执行起来会有一些差异。这些都是和框架层有关系的。
JNI 是一个供给 java 用的库,
lib: 文件的类型都是。So 动态库,C C++需要用到的库。
增加 ALOGI
1. 编译的时候 需要增加 LOCAL_SHARED_LIBRARIES : = liblog
2.文件中需要定义 #define LOG_TAG "lowmemorykiller" // 必须在文件的第一行
3.包含头文件 #include <log/log.h>
4. app中: Log.d(LOG_TAG, msg); //debug Log.i //info Log.e //error Log.w // warning Log.v // vebose
5. 之后进入 logcat 查看
JNI
demo_jni.java
public class Demo_Jni{
public static int sum(int a, int b)
{
return a + b;
}
public static void main(String args[])
{
System.out.println("Demo_jni is called ");
int c = sum(10, 20);
System.out.println(“sum:" + c);
}
public native static void show(); // JNI 声明 native 表示在java中声明,但是在C中实现
static {
System.loadLibrary("Demo_Jni"); // libDemo_Jni.so
}
}
之后进行编译 javac Demo_Jni.java
生成一个 Demo_Jni.class
源文件: Demo_Jni.java
第一步是生成.class, 第二步为了生成.h
通过 javah -jni Demo_Jni 将字节码文件Demo_Jni.class 生成Demo_Jni.h 文件
....
JNIEXPORT void JNICALL Java_Demo_Jni_show(JNIEnv *, jclass);
这个是在上面Demo_Jni.java中定义的时候增加的 static,, 可以用类名.来调用 Dem_jni.show()
如果没有定义static, 需要用对象来调用 New Demo_Jni().show()
JNIEXPORT void JNICALL Java_Demo_Jni_dislpay(JNIEnv *, jobject);
...
JNIEnv: 这个是通过虚拟机来解析这个文件, 就是来读虚拟机里面的信息,这个接口就是JNIEnv
jclass: 就是类名
以上的方法是静态生成,现在基本不用。都是用动态生成的方法。
例如:Demo_Jni.java
package com.example.demo; // 文件夹路径 com/example/demo
public class Demo_Jni{
public static int sum(int a,int b)
{
return a+b;
}
public static void main(String args[])
{
System.out.println("Demo_Jni is called");
int c = sum(10,20);
System.out.println("sum:"+c);
Demo_Jni.show();
new Demo_Jni().display();
}
public native static void show();//jni shengming
public native void display();
static {
System.loadLibrary("Demo_Jni");//libDemo_Jni.so
}
}
Demo_Jni.c
#include <stdio.h>
#include <jni.h>
void jni_show(JNIEnv *env, jclass claz)
{
printf("jni :function show is called]\n");
}
void jni_display(JNIEnv *env, jobject obj)
{
printf("jni:function display is called\n");
}
JNINativeMethod methods[] = {
{ "show", "()V", (void *)jni_show }, // 前面是java中的函数名,中间是签名,后面是本C中的方法名
{ "display", "()V", (void *)jni_display} ,
};
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved) { // 相当于main
JNIEnv *env;
jclass cls;
if ((*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_4)) {
return JNI_ERR;
}
cls = (*env)->FindClass(env, "com/example/demo/Demo_Jni"); // 包名
if (cls == NULL) {
return JNI_ERR;
}
(*env)->RegisterNatives(env, cls, methods,
sizeof(methods) / sizeof(methods[0])); //注册native 方法
return JNI_VERSION_1_4;
}
Android.mk
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional #指定模块的名称
LOCAL_MODULE :=libDemo_Jni #指定模块的源文件
LOCAL_SRC_FILES := \
Demo_Jni.c
LOCAL_SHARED_LIBRARIES := libcutils libutils liblog
LOCAL_CFLAGS += -O #定义编译标志
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_SHARED_LIBRARY) // 这个就会把Demo_Jni.c 生成 libDemo_Jni.so
ART: 是 andorid runtime 缩写 AOT Ahead-Of-Time 方式运行Android引用程序的机制。
生成 .jar
1 .linux 平台编译方式: javac Demo_Jni.java 生成了 Demo_Jni.class
2. dx --dex --output = "Demo_Jni.jar " Demo_Jni.class 生成产物: Demo_Jni.jar
3. 运行: 两个文件拷贝Android平台 so--> /system/lib jar---> /system
4. 方式一: dalvikm -cp /system/Demo_Jni.jar Demo_Jni 命令生成Jar 用android.mk
第二种方式: app_process 在 /frameworks/base/cmds/app_process / 用来启动 zygote: 所有应用程序的父进程
CLASSPATH=/system/Demo_Jni.jar app_process .
app_process 使用了davilk 虚拟机, 会默认给你添加线程的服务。
#Demo_Jni.jar
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE := Demo_Jni
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_MODULE_PATH :=$(LOCAL_PATH)
include $(BUILD_JAVA_LIBRARY)
Client : APP apk // 通过 aidl , serverManager
server: 系统级应用 // 需要添加到系统服务
JNI: C转java 或则 Java转C // 上层是Java 驱动是C // 需要添加到系统JNI
HAL: 驱动的逻辑代码, 保护厂商的利益,统一接口
Driver: 通过C语言 操作硬件
APP:
package com.example.a02_demoapp;
import android.app.Activity;
import android.os.Bundle;
import android.os.IDemoService;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.os.*;
public class MainActivity extends Activity {
private EditText et_user, et_password;
private Button btn_get;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_user = (EditText) findViewById(R.id.et_user);
et_password = (EditText) findViewById(R.id.et_password);
btn_get = (Button) findViewById(R.id.btn_get);
btn_get.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// get user data
String userdata = et_user.getText().toString();
// get system server demo_service
// client
IDemoService service = IDemoService.Stub.asInterface(ServiceManager.getService("Demo"));
// 客户端是来使用aidl文件的 (该文件由DemoService extends IDemoService.stub)
try {
service.set_username(userdata);
String pwd = service.get_password();
et_password.setText(pwd);
} catch (RemoteException e) {
e.printStackTrace();
}
//set edit text UI et_password
}
});
}
}
driver:
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <linux/fs.h>
static unsigned char mem[1024];
static ssize_t driver_demo_read(struct file * file, char __user * buf, size_t len, loff_t *ppos){
int res;
const char* username ="admin";
const char* password = "123456";
const char* error = "username is error";
res = strcmp(mem,username);
if(res ==0)
{
copy_to_user(buf,password,len);
return -EINVAL;
}else{
copy_to_user(buf,error,len);
return -EINVAL;
}
printk("demo_driver:driver_demo_read is called");
return len;
}
static ssize_t driver_demo_write(struct file * file, const char __user * buf,size_t len, loff_t *ppos){
int res;
ssize_t writen =len;
res = copy_from_user(mem,buf,len);
mem[writen] ='\0';
printk("demo_driver:driver_demo_write is called");
return res;
}
static const struct file_operations demo_fops ={
.owner = THIS_MODULE,
.read = driver_demo_read,
.write =driver_demo_write,
};
static struct miscdevice demo_dev={
.minor =MISC_DYNAMIC_MINOR,
.name = "demo",
.fops = &demo_fops,
};
static int __init demo_init_module(void)
{
int res = misc_register(&demo_dev);
printk("demo_driver: demo_init_module is sucess\n");
}
static void __exit demo_cleanup_module(void)
{
misc_deregister(&demo_dev);
printk("demo_driver: demo_cleanup_module is success\n");
}
module_init(demo_init_module);
module_exit(demo_cleanup_module);
1. 添加服务(应用层中有getservice()),
2. 注册服务 : 服务在手机后台是一致开着的类似 daemon
2..5 编写 aidl 实现c/s 之间的通信
3.实现JNI
4.实现HAL
lsusb
adb reboot bootloader
sudo fastboot -l 0x1f3a flash system system.img
sudo fastboot - l 0x1f3a reboot
1. 添加服务(应用层中有getservice()),
参考 :/frameworks/base/services/core/java/com/android/server/VibratorService.java
/frameworks/base/core/java/com/android/server/DemoService.java
package com.android.server;
import android.os.IDemoService;
import android.os.IBinder;
import android.os.Binder;
import android.util.Slog;
import android.os.ServiceManager;
public class DemoService extends IDemoService.Stub // 这很关键
{
private static final String TAG ="DemoService";
public DemoService(){
Slog.i(TAG,"constructor is called");
native_device_open();
}
public void set_username(String str)
{
Slog.i(TAG,"set_username"+str);
native_setusername(str);
}
public String get_password()
{
String s = "HELLO WELCOM TO";
Slog.i(TAG,"get_password"+s);
s = native_getpassword();
return s;
}
public static native void native_setusername(String str);
public static native String native_getpassword();
public static native void native_device_open();
}
2. 注册服务 : 添加到serviceManager
/frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
private void run() {
// Initialize native services.
System.loadLibrary("android_servers"); // libandorid_servers.so
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
private void startOtherServices() {
DemoService demo = NULL;
traceBeginAndSlog("StartDemoService");
demo= new DemoService();
ServiceManager.addService("Demo", demo); // 需要跟app一致
traceEnd();
2.5 添加 aidl 实现 c/s 之间的通信
参考: /frameworks/base/core/java/android/os/IVibratorService.aidl
/frameworks/base/core/java/android/os/IDemoService.aidl
IDemoService.aidl
package android.os;
/** {@hide} */
interface IDemoService{
void set_username(String username);
String get_password();
}
添加编选项
参考 : "core/java/android/os/IVibratorService.aidl",
编译的时候 会生成
编译自动生成 IDemoService.java // 注意这个名字和 IDemoService.aidl
package android.os;
/** {@hide} */
public interface IDemoService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.IDemoService
{
private static final java.lang.String DESCRIPTOR = "android.os.IDemoService"; // 很关键
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an android.os.IDemoService interface,
* generating a proxy if needed.
*/
public static android.os.IDemoService asInterface(android.os.IBinder obj)
3.实现JNI
/frameworks/base/services/core/jni/onload.cpp
int register_android_server_VibratorService(JNIEnv* env);
int register_android_server_DemoService(JNIEnv* env);
register_android_server_VibratorService(env);
register_android_server_DemoService(env);
/frameworks/base/services/core/jni/com_android_server_VibratorService.cpp
参考学习以上的 进行添加
com_android_server_DemoService.cpp
#define LOG_TAG "DemoService"
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <android/log.h>
#include <log/log.h>
#include <hardware/hardware.h>
#include <utils/misc.h>
#include <utils/Log.h>
#include <stdio.h>
#include <hardware/jni_demo.h>
namespace android
{
struct demo_device_t* mydevice;
static void jni_device_open(JNIEnv* /* env */, jobject /* clazz */)
{
struct hw_module_t* module;
struct hw_device_t* device;
int res = hw_get_module("demo", (const struct hw_module_t**)&module); // 调用hal层 很重要
// hw_get_module是更具hal中hw_device_t 中设置的ID来进行查找的
// 其实这里主要是利用common 两个结构体收地址相同的方法,来偷换概念。 解释如下:
// 1.用的是 hw_get_module 会找动态库(hal生成的.so)
// 2.找变量名字 HAL_MODULE_INFO_SYM struct hw_module_t HAL_MODULE_INFO_SYM = {
// 3. 通过HAL_MODULE_INFO_SYM 中的id来判断"demo", 是否是自己要找的
// 4. 是的话 就会返回struct hw_module_t* module; 结构体
// 5. 根据成员 .methods = &demo_module_t
static struct hw_module_methods_t demo_module_t ={
.open = demo_device_open
};
// 6.下面 就是使用它的open方法
// 7. open方法基本是 固定的, 就是填充结构体,ruct demo_device_t *context;
// 8. 之后再open方法中 将*device =&(context->common); 返回
// 注意: 这里就是 hw_mothod_和 hw_device_t 方法的名字一致,地址一致的方法,返回
// 9. 这样 在jni就利用利用 hw_device_t (hal层)里面定义的方法来实现java转C的方法
// 10. hal层主要是保护厂商的利益,编译生成.so 利用driver提供的接口进行逻辑操作
res = module->methods->open(module,"demo", (struct hw_device_t**)&device); // hal open
mydevice = (struct demo_device_t*)device; //得到指针
}
static void jni_setusername(JNIEnv* env , jobject /* clazz */, jstring jstr)
{
jboolean isCopy;
const char* cstr = env->GetStringUTFChars(jstr,&isCopy);
ALOGI("JNI--jni_setusername: cstr:%s\n",cstr);
mydevice->hal_setusername(mydevice,cstr);
}
static jstring jni_getpassword(JNIEnv *env, jobject clazz)
{
char buf[20];
mydevice->hal_getpassword(mydevice,buf);
ALOGI("JNI--jni_getpassword: buf:%s\n",buf);
jstring jstr = env->NewStringUTF(buf);
return jstr;
}
static JNINativeMethod method_table[] = {
{ "native_setusername", "(Ljava/lang/String;)V", (void *)jni_setusername },
{ "native_getpassword", "()Ljava/lang/String;", (void *)jni_getpassword },
{ "native_device_open", "()V", (void *)jni_device_open }
};
int register_android_server_DemoService(JNIEnv *env)
{
return jniRegisterNativeMethods(env, "com/android/server/DemoService",
method_table, NELEM(method_table));
}
};
相应的Android.mk
Android.mk
$(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \
$(LOCAL_REL_DIR)/com_android_server_DemoService.cpp \
会生成文件 jni_demo
4.实现HAL
hal_demo.h
struct demo_module_t{
struct hw_module_t common;
};
struct demo_device_t{
struct hw_device_t common;
int (*hal_setusername)(struct demo_device_t *dev,char* buf); //read write
int (*hal_getpassword)(struct demo_device_t *dev,char* buf); //参数当作返回,read(fd,buf,len);
int fd;
};
hal_demo.c
#define LOG_TAG "HAL_DEMO"
#include <hardware/hardware.h>
#include <cutils/log.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <hardware/hal_demo.h>
#include <string.h>
static int demo_device_close(struct hw_device_t* device)
{
struct demo_device_t* ctx = (struct demo_device_t*)device;
if(ctx)
{
free(ctx);
}
return 0;
}
int hal_setusername(struct demo_device_t *dev,char* buf)
{
ALOGI("function hal_setusername is called \n");
int len = strlen(buf);
int res = write(dev->fd,buf,len);
ALOGI("buf : %s\n",buf);
return res;
}
int hal_getpassword (struct demo_device_t *dev,char* buf)
{
ALOGI("function hal_getpassword is called \n");
char str[20];
int res = read(dev->fd,str,20);
strcpy(buf,str);
ALOGI("buf:%s\n",buf);
return res;
}
static int demo_device_open(const struct hw_module_t* module,const char* id,
struct hw_device_t** device){
// hw_device_t 赋值;
struct demo_device_t *context;
context =(struct demo_device_t *)malloc(sizeof(*context));
memset(context,0,sizeof(*context));
context->common.tag = HARDWARE_DEVICE_TAG;
context->common.version = 1;
context->common.module = module;
context->common.close = demo_device_close;
context->hal_setusername =hal_setusername;
context->hal_getpassword =hal_getpassword;
context->fd = open("/dev/demo",O_RDWR);
*device =&(context->common);
ALOGI("function demo_device_open is called \n");
return 0;
}
static struct hw_module_methods_t demo_module_t ={
.open = demo_device_open
};
struct hw_module_t HAL_MODULE_INFO_SYM = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id= "demo",
.name= "1711",
.author="xxx",
.methods = &demo_module_t
};
Android.mk
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS :=eng
LOCAL_PRELINK_MODULE:=false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
#LOCAL_MODULE_PATH := $(LOCAL_PATH)
LOCAL_SHARED_LIBRARIES := liblog libhardware libcutils libbinder libutils
LOCAL_SRC_FILES := hal_demo.c
LOCAL_MODULE:=demo.default
include $(BUILD_SHARED_LIBRARY)
会生成文件 demo.default.so
以下是重点==============================================
会生成两个文件 demo.default.so 和 jni_demo
可以本地编译之后考入手机,也可以直接放在手机中编译。
adb push demo.default.so /system/lib/hw
adb push jni_demo /system
frameworks/base/core/java/android/hardware/Camera.java
frameworks/base/core/jni/android_hardware_Camera.cpp
":libcamera_client_aidl",
":libcamera_client_framework_aidl",
"frameworks/av/camera/aidl",
/frameworks/av/camera/aidl/android/hardware/ICameraService.aidl
interface ICameraService
/**
* Return the number of camera devices available in the system
*/
int getNumberOfCameras(int type);
/**
* Fetch basic camera information for a camera device
*/
CameraInfo getCameraInfo(int cameraId);
/**
* Default UID/PID values for non-privileged callers of
* connect(), connectDevice(), and connectLegacy()
*/
const int USE_CALLING_UID = -1;
const int USE_CALLING_PID = -1;
/**
* Open a camera device through the old camera API
*/
ICamera connect(ICameraClient client,
int cameraId,
String opPackageName,
int clientUid, int clientPid);
/**
* Open a camera device through the new camera API
* Only supported for device HAL versions >= 3.2
*/
ICameraDeviceUser connectDevice(ICameraDeviceCallbacks callbacks,
String cameraId,
String opPackageName,
int clientUid);
/**
* halVersion constant for connectLegacy
*/
const int CAMERA_HAL_API_VERSION_UNSPECIFIED = -1;
/**
* Open a camera device in legacy mode, if supported by the camera module HAL.
*/
ICamera connectLegacy(ICameraClient client,
int cameraId,
int halVersion,
String opPackageName,
int clientUid);
/**
* Add listener for changes to camera device and flashlight state.
*
* Also returns the set of currently-known camera IDs and state of each device.
* Adding a listener will trigger the torch status listener to fire for all
* devices that have a flash unit
*/
CameraStatus[] addListener(ICameraServiceListener listener);
/**
* Remove listener for changes to camera device and flashlight state.
*/
void removeListener(ICameraServiceListener listener);
/**
* Read the static camera metadata for a camera device.
* Only supported for device HAL versions >= 3.2
*/
CameraMetadataNative getCameraCharacteristics(String cameraId);
/**
* Read in the vendor tag descriptors from the camera module HAL.
* Intended to be used by the native code of CameraMetadataNative to correctly
* interpret camera metadata with vendor tags.
*/
VendorTagDescriptor getCameraVendorTagDescriptor();
/**
* Retrieve the vendor tag descriptor cache which can have multiple vendor
* providers.
* Intended to be used by the native code of CameraMetadataNative to correctly
* interpret camera metadata with vendor tags.
*/
VendorTagDescriptorCache getCameraVendorTagCache();
/**
* Read the legacy camera1 parameters into a String
*/
String getLegacyParameters(int cameraId);
/**
* apiVersion constants for supportsCameraApi
*/
const int API_VERSION_1 = 1;
const int API_VERSION_2 = 2;
// Determines if a particular API version is supported directly
boolean supportsCameraApi(String cameraId, int apiVersion);
void setTorchMode(String cameraId, boolean enabled, IBinder clientBinder);
/frameworks/av/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
/** @hide */
interface ICameraDeviceUser
/**
* Cancel the repeating request specified by requestId
* Returns the frame number of the last frame that will be produced from this
* repeating request, or NO_IN_FLIGHT_REPEATING_FRAMES if no frames were produced
* by this repeating request.
*
* Repeating request may be stopped by camera device due to an error. Canceling a stopped
* repeating request will trigger ERROR_ILLEGAL_ARGUMENT.
*/
long cancelRequest(int requestId);
/**
* Begin the device configuration.
*
* <p>
* beginConfigure must be called before any call to deleteStream, createStream,
* or endConfigure. It is not valid to call this when the device is not idle.
* <p>
*/
void beginConfigure();
/**
* The standard operating mode for a camera device; all API guarantees are in force
*/
。。。。
/**
* End the device configuration.
*
* <p>
* endConfigure must be called after stream configuration is complete (i.e. after
* a call to beginConfigure and subsequent createStream/deleteStream calls). This
* must be called before any requests can be submitted.
* <p>
* @param operatingMode The kind of session to create; either NORMAL_MODE or
* CONSTRAINED_HIGH_SPEED_MODE. Must be a non-negative value.
* @param sessionParams Session wide camera parameters
*/
void endConfigure(int operatingMode, in CameraMetadataNative sessionParams);
void deleteStream(int streamId);
。。。
/**
* Create an output stream
*
* <p>Create an output stream based on the given output configuration</p>
*
* @param outputConfiguration size, format, and other parameters for the stream
* @return new stream ID
*/
int createStream(in OutputConfiguration outputConfiguration);
/**
* Create an input stream
*
* <p>Create an input stream of width, height, and format</p>
*
* @param width Width of the input buffers
* @param height Height of the input buffers
* @param format Format of the input buffers. One of HAL_PIXEL_FORMAT_*.
*
* @return new stream ID
*/
int createInputStream(int width, int height, int format);
/**
* Get the surface of the input stream.
*
* <p>It's valid to call this method only after a stream configuration is completed
* successfully and the stream configuration includes a input stream.</p>
*
* @param surface An output argument for the surface of the input stream buffer queue.
*/
Surface getInputSurface();
// Keep in sync with public API in
// frameworks/base/core/java/android/hardware/camera2/CameraDevice.java
const int TEMPLATE_PREVIEW = 1;
const int TEMPLATE_STILL_CAPTURE = 2;
const int TEMPLATE_RECORD = 3;
const int TEMPLATE_VIDEO_SNAPSHOT = 4;
const int TEMPLATE_ZERO_SHUTTER_LAG = 5;
const int TEMPLATE_MANUAL = 6;
CameraMetadataNative createDefaultRequest(int templateId);
CameraMetadataNative getCameraInfo();
void waitUntilIdle();
long flush();
void prepare(int streamId);
void tearDown(int streamId);
void prepare2(int maxCount, int streamId);
void updateOutputConfiguration(int streamId, in OutputConfiguration outputConfiguration);
void finalizeOutputConfigurations(int streamId, in OutputConfiguration outputConfiguration);
}
frameworks/av/camera/Camera.cpp
frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp
frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.h