MMI 训练课程 *** 议程: 1.mmi平台源码训练 2.UEM和NVRAM的用户化设置 3.mmi源和配置工具 4.图形设备接口(GDI) *** mmi平台源码训练 *** 1.mmi基本结构 2.任务结构 3.写个应用程序 4.电脑模拟器和网络模拟器 5.调试支持 6.配置外围设备成分 *** mmi基本结构 *** * 应用层 UI层 框架层 * 操作系统,协议栈层,驱动层 *** 1.应用层 用户定义应用程序 2.框架层 封装用于管理消息和事件处理器 为应用层提供方便 为操作系统提取提供便利 3.UI层 封装管理UI层的函数 *** 代码结构和导航 -\PLUTOMMI -\customer -\mmi -\mtkapp *** Customer Folder ... *** .mmi -inc -framework .eventhandling .filesystem .history .nvrammanager .osl .tasks -gui .UIcomponents .Category screen -[App] .AppSrc .AppInc .mtkapp -[App] .AppSrc .AppInc *** 任务结构 ~mmi本身就是一个任务~ *** 初始化 .硬件导入和设置系统栈等 .Nucleus Plus RTOS初始化 .硬件初始化 .任务/模块的初始化/配置 .任务生成 .TCT_schedule() for scheduler to context switch *** 任务结构简介: 图表略 .MMI队列:协议栈和L4把事件写入和MMI任务从次队列读出事件 .L4/NS Queue:MMI任务把事件写入和协议栈和L4从次队列读出事件 *** 任务结构的详细解释 .mmi任务规则 -等待消息发送到mmi队列 -协议栈向mmi队列发送消息 -框架层处理事件 -框架层触发返回应用层 -应用层使用UI层的种类模版函数和主题把屏幕显示出来 *** 任务间的事件流程图 例1:.触压键盘事件的应用 图略 *** .协议栈把一个事件写入MMI队列 .mmi任务从mmi队列读出任务 -框架使应用函数回调用最早的事件登记 -应用程序接收触压键盘事件并作出反应 *** 例2:-要求应用程序发出声响 图略 *** .应用程序向框架层发送向L4队列发送消息的请求 .框架把消息写入L4队列 .L4任务把事件读出并发出声响 *** mmi任务简介: 图略 *** .应用层 -用户编写代码执行逻辑问题 .框架层 -接收所有任务的事件 -帮助应用程序控制屏幕流(历史管理机制) -为系统提供调用应用程序的句柄 *** -框架元素 .事件处理器-多事件调用函数注册和执行应用程序 .历史-管理屏幕保存内部数据 .OSL-根据应用程序的调用为操作系统提供句柄 .文件系统-提供句柄用于文件系统的数据存取 .NVRAM-提供句柄用于NVRAM的数据存取(NVRAM非易失性随机访问存储器) *** .UI层 -为应用层提供用户接口 -UI层元素 .种类屏幕 -用于画出应用程序智能的方法 -接收字串ID和图像id资源 -使应用程序从屏幕,版面,外观独立出来 -为历史管理机制提供接口 *** 相同的种类屏幕(图略) *** .UI元素 -这里是提供使用UI元素的地方,元素如按钮,滚动条,菜单等 -这些都是用户接口的建立模块 .主题 -负责UI元素的多种固定显示外观 -主题组成 》物体外形和颜色 》字体(颜色,字体样式,大小) 》其他显示属性 *** .字体 -图形库使这类数据在LCD上显示信息 .图片 -用于显示图标,背景和弹出屏幕等 .图库 -支持原始图类 -包含用于显示字体和图片的函数 *** .框架层 -在运行的时候,为应用程序提供事件处理器接口来处理事件。 .键盘事件处理器接口-常用于实现应用程序和种类函数功能 -为特殊键设置处理器 -为一组键设置处理器 -触压键时执行当前键处理器 -清除特殊键处理器 -清除所有键处理器 -为开关机键提供特殊处理 *** .协议处理器接口-专用于应用程序 -设置协议事件处理器 -执行当前事件处理器 -清除特殊协议事件处理器 -清除所有协议事件处理器 .Misc.处理器 -退出处理器 》为特殊屏幕设置退出处理器 》执行当前屏幕退出处理器 》清除当前退出处理器 *** -历史 .屏幕快照数据库 .后进先出执行方式 .历史数据节点结构 -屏幕ID:保存一个屏幕 -入口函数指针:用于重画屏幕 -输入缓冲:用于保存屏幕中的文本数据 -GUI缓冲器:用于保存屏幕中的UI信息 *** .历史应用接口 -在历史栈中添加节点 -在历史栈中删除“n”个节点 -在历史栈中回到第“n”个节点 -在历史栈中找回屏幕 -在历史栈中找出屏幕缓冲器 -在历史栈中找回UI缓冲器 -转出历史开始调试 -初始化历史 .历史机制的微妙 -作为历史栈执行(后进先出) -第一个屏幕保存后,在没弹出前一直存在 -新节点加在历史栈顶 *** -OSL层 .提供抽象的系统调用,使MMI方便简易 .包装下面内核块 -队列 -时限 *** .队列应用接口 -生成队列 》oslMsgqid OslIntCreateMsgQ(PS8 queue_name,U32 max_msg_sizevolume_type=volume_type; setVolumeLevelReq->volume_level; Message.oslDataPtr=(oslParaType*)setVolumeLevelReq;//Local parameter buffer Message.oslPeerBuffPtr=NULL;//Peer parameter buffer Message.oslSrcId=MOD_MMI;//send from Source module Message.oslDestId=MOD_L4C;//send to destination module OslMsgSendExtQueue(&Message);//send to L4 task } *** 例子(Play Pattern) .Play a Pattern(LED/LCD/VIB)请求: void sendPlayPatternReqToHW(U8 pattern,U8 action) { MYQUEUE Message; mmi_eq_play_pattern_req_struct *displayLedPattern; Message.oslMsgId=MSG_ID_MMI_EQ_PLAY_PATTERN_REQ; displayLedPattern=OslConstructDataPtr(sizeof (mmi_eq_play_pattern_req_struct)); displayLedPattern->pattern=pattern; displayLedPattern->action=action; Message.oslDataPtr=(oslParaType*)displayLedPattern; Message.oslPeerBuffPtr=NULL; Message.oslsRCiD=MOD_MMI; Message.oslDestId=MOD_L4C; OslMsgSendExtQueue(&Message); } *** 例子(GPIO探测) .注册GPIO探测指示: -SetProtocolEventHandler(GpioDetectInd,MSG_IDMMI_EQ_GPIO.DETECT_IND); .接收GPIO探测指示: void GpioDetectInd(void *info) { mmi_eq_gpio_detect_ind_struct *gpioDetectInd; gpioDetectInd=(mmi_eq_gpio_detect_ind_struct *)info; switch(gpioDetectInd->gpio_device) { case EXT_DEV_EARPHONE: EarphonePlugInPopup(); break; ...... } } *** 编写一个应用程序 *** 一个应用程序的剖析 .整合资源 .初始化规则 -为应用程序设置数据的规则 .整合字串,图片和菜单资源 .注册协议事件和高亮处理器 .高亮处理器 .执行用户编写代码的高亮菜单条目 .入口和出口函数 .管理应用程序屏幕流的函数 .应用程序管理前部的屏幕流 .历史机制管理后部的屏幕流 *** .声明各类资源ID -声明独特的ID .屏幕(Screen) .菜单条目(Menu Items) .字串(Strings) .图片(Images) *** .用于整合的函数 -从资源生成器调用 -初始化所有必要的UI资源 .图片 -使用宏:ADD_APPLICATION_IMAGE2 .字串 -使用宏:ADD_APPLICATION_STRING2 .菜单条目 -使用宏:ADD_APPLICATION_MENUITEM -例子: void PopulateCmResData(void){ ADD_APPLICATION_STRING2(STR_INC_ACT_OPT_PSEUDO,"Incoming Call","String to display for incoming call"); ADD_APPLICATION_IMAGE2(ICN_INC_HLD_OPT_IGN,"..\\\\IMAGES\\\\16*12\\\\NoImage.ppf","no image"); ADD_APPLICATION_MENUITEM((MAIN_MENU_FILE_MNGR_MENUID,IDLE_SCREEN_MENU_ID,2,ORGANIZER_WORLDCLOCK_MENU,ORGANIZER_CALCULATOR_MENU,SHOW,MOVEABLEACROSSPARENT,DISP_LIST,MAIN_MENU_FILE_MNGR_TEXT,MAIN_MENU_FILEMNGR_ICON)); } *** .初始化函数 -从MMITask的初始化导入函数中调用INItializeAll() -初始化多个事件处理器 -样本代码 void InitIncomingCall(void){ ... SetProtocolEventHandler(psCBackCallIncoming,PRT_INCOMINGCALL_EVENT); SetHiliteHandler(MITEM_INC_OPT_ANSWER,HiliteMenuIncomingAnswer); ... } -那些回调函数也可以在应用逻辑程序中注册 *** .入口和出口函数 -入口函数和出口函数控制屏幕流 -入口函数执行过程 .调用入口函数并执行当前的出口处理器 .设置退出处理器 .获取当前屏幕的GUI缓冲器 .获取当前屏幕的显示元素 .注册高亮处理器 .调用种类屏函数画出屏幕 *** -出口函数执行过程 .创建历史节点 .在历史节点中保存入口函数 .给历史节点的输入缓冲器和GUI缓冲器赋值 .保存历史 -高亮处理器 .用于执行高亮菜单条条目对应的用户编写代码程序 .高亮函数执行过程 -更改左右键的处理器 *** 应用程序流程例子 图略 *** 电脑模拟器和网络模拟器 *** 电脑模拟器 .在win32环境下模拟MMI行为 .PixtelMMI.exe -MMI框架(MMI framework) -应用程序(Application) .mmiresource.dll -resource资源 .系统需求 -MVC .预先步骤 -目标代码步骤 -资源整合器 *** -建立过程 .打开VC++IDE .打开plutommi\mmi\pixtelmmi.dsw .设置正确的配置 -调试,释放,Level1 Release .建立两个工程 -PixtelMMI -ResourceDLL *** 网络模拟器 .用于模拟网络事件并发送到电脑模拟器 .导入过程 .调用管理 .指出存储管理服务(SMS) .信号和电量 .指出电话本 .指出调用历史 *** .接收信息处理器:接收MMI发送的信息 .发送信息处理器:给MMI发送信息 .信息处理器管理 -接收所有信息... -处理XML的信息处理器并创建发送缓冲器 .XML处理器 -网络模拟器的信息管理 -静态数据变量 .Plugin -在数据保存文件中演示确定操作 *** 消息过程 流程图略 *** .一连串的消息发送 .消息响应可以同步也可以异步 .响应事件可以自动也可以手动 .消息顺序有超过一条消息并且多数据被发出 .生成一个log文件包含消息过程的错误信息 *** GCML样本文本 . 外来消息ID:-指定外来消息的事件ID 应用程序ID:-指定在模拟器是否是自动或是手动响应 插件(Plugin):当网络模拟器接收到消息时指定哪个函数将被调用 Fmtname:-指定数据类型结构发送给MMI respmesg id:-指定发出信息的事件ID *** 调试支持 *** .PRINT_INFORMATION,PRINT_INFORMATION_2 -用于输出字符串格式(to print out the %s string type) .MMI_TRACE -用于记录跟踪信息(to log trace information) *** .描述跟踪图(在MMI_trc.h中) BEGIN_TRACE_MAP(MOD_MMI) /*TRACE_FUNC trace class*/ TRC_MSG(MMI_PHB_FUNC_STARTUP_CNF,"PHB:confirm result:%02d") END_TRACE_MAP(MOD_MMI) MOD_MMI:模块名字 MMI_PHB_FUNC_STARTUP_CNF:定义跟踪信息 "PHB:confirm result:%02d":跟踪信息的内容 *** .在源代码,.C文件,在你想跟踪LOG信息添加头文件 #include "kal_trace.h" #include "DebugInitDef.h" #include "mmi_trc.h" *** 在代码中,调用MMI_TRACE(())函数 MMI_TRACE((MMI_TRACE_FUNC,MMI_PHB_FUNC_STARTUP_CNF,result)); MMI_TRACE_FUNC:跟踪类 MMI_PHB_FUNC_STARTUP:跟踪信息ID result:嵌入跟踪信息的值 *** .使用DebugInitDef.h中的跟踪类 .有15个跟踪类,都可以在Catcher筛选 .一般的,你可以决定跟踪类并MMI_TRACE(())中定义ID: MMI_TRACE_FUNC,MMI_TRACE_STATE,MMI_TRACE_INFO,MMI_TRACE_WARNING,MMI_TRACE_ERROR,MMI_TRACE_G1_FRM,MMI_TRACE_G2_GUI,MMI_TRACE_G3_GOOTUP,MMI_TRACE_G4_PHB,MMI_TRACE_G5_CM,MMI_TRACE_G6_SMS,MMI_TRACE_G7_MISC,MMI_TRACE_G8_MEDIA,MMI_TRACE_G9_EMAIL,MMI_TRACE_G10_RESERVED *** 专用外围设备元件 *** 键盘处理器结构 .键盘处理器相关文件 -KeyBrd.c -KeyMap.cpp -KeyBrd.h -KeyMap.h *** .支持26个键 -0-9键 -4个导航键 -电源,清除,发送,结束,星号,井号,声调高,声调低,运行,菜单,软件等(Power,Clear,Send,End,Star,Pound,Vol Up,Vol Down,Function,Menu,Softkeys) .键盘布局N键盘布局 -键盘布局的主要元素结构,26个入口 .目前MMI版本支持22个键 *** .使用一个新键(从26个键中) -在PresentAllKeys结构中为新键添加新入口 -通过新键ID在应用程序屏幕中调用SetKeyHandler设置新键响应 *** Q&A