EntryIdleScreen()
g_idle_context.IsOnIdleScreen = 1;
g_idle_context.IsOnDialerScreen = 0;
g_pwr_context.PowerOnMMIStatus = MMI_POWER_ON_IDLE
自动键盘锁定时器:IDLE_APP_AUTO_LOCK_TIMER_ID
自动键盘锁CBack:IdleSetKeyPadLockFlag()。
此时键盘没有锁,进入if分支:
mmi_idle_entry_idle_screen()
ShowCategory33Screen()
SetGroupKeyHandler(HandleIdleScreenDigitEntry)//键盘0-9,*,#响应
IdleSetLRKey(); //设置左软件、右软件
RegisterDedicatedKeyHandlers(); //方向键的快捷方式
CHISTResetCallLogIndex(); //清除CALL LOG信息
SetKeyHandler(CHISTGetCallLogBySENDKey,
KEY_SEND,KEY_EVENT_DOWN);
键盘锁定时器溢出之后,进入CBack函数:
IdleSetKeyPadLockFlag()
g_keylock_context.gKeyPadLockFlag = 1;
屏保没有执行时,再次进入:EntryIdleScreen(),此时键盘已锁,进入else分支:
mmi_idle_set_keypad_lock_string();
设置左软件、右软件的标签
ShowCategory33Screen()
SetLeftSoftkeyFunction(EntryScrAfterPessingRSK,KEY_EVENT_DOWN);
设置左软件的解锁响应
IdleSetLRKey()
输入数字:
HandleIdleScreenDigitEntry()
GetkeyInfo(&Keycode, &Keytype); //获取按键
sprintf(g_idle_context.DialPadCallBuffer, "");
g_idle_context.IdleScreenDigitKeyCode = Keycode; //保存按键
IdleScreenDigitHandler()
ShowCategory16Screen( ),此时g_idle_context.DialPadCallBuffer为空。
ExecuteCurrKeyHandler(g_idle_context.IdleScreenDigitKeyCode, KEY_EVENT_DOWN);
MMI_key_2_down()
MMI_key_input_handler(KEY_2, KEY_EVENT_DOWN);
MMI_key_input_handler()
MMI_key_down_handler_function(key_code);
dialer_inputbox_direct_input((UI_character_type)('0' + k));
gui_dialer_input_box_insert_character(&MMI_dialer_inputbox, c);
把输入的数字插入MMI_dialer_inputbox.text以及
g_idle_context.DialPadCallBuffer中。
redraw_dialer_inputbox(); //重画输入框
dialer_inputbox_input_callback(); 实际上是执行:
wgui_handle_dialer_inputbox_input()
改变右软件的标签以及响应
SetLeftSoftkeyFunction(EntryScrDialOptions, KEY_EVENT_UP); 左软件响应
SetKeyHandler(((mmi_bootup_is_sim_valid() == MMI_TRUE) ? IdleDialPadCall : EntryScrEmergencyCallDialing),
KEY_SEND, KEY_EVENT_UP); //SEND键响应
SetKeyHandler(IdleAbbrevDialling, KEY_POUND, KEY_EVENT_UP); //#键响应(静音模式)
SetCategory16RightSoftkeyFunction(GoBackHistory, KEY_EVENT_UP); //必须这么设置,不能直接SetRightkeyFunction 来设置为GoBackHistory()。 在所有的接收用书输入的Category Screen中,都是这么设置的。
SetGroupKeyHandler(IdleCallSpeedDialOnLongPress, SpeedDialKeys,
MAX_SPEED_DIAL_KEYS - 1, KEY_LONG_PRESS); //速拨
SetKeyHandler(DialVoiceMail, KEY_1, KEY_LONG_PRESS); //数字0的快捷响应
SetGroupKeyHandler(IdleDisableLongPress, (PU16) PresentAllKeys, (U8) TOTAL_KEYS, KEY_EVENT_UP);
然后,用户按下其他数字键,不会再进入IdleScreenDigitHandler()这个函数,而是直接执行:MMI_key_X_down(),就是从上面的蓝色部分开始执行,把数字插入进去,然后直接重画输入框。
实验发现:
在速拨关闭的时候,按住‘2’一直不放,那么在输入框中将连续显示2222…..,在释放数字2之后,CALL:IdleDisableLongPress()
在速拨打开时,按住‘2’一直不放,进入速拨的响应:IdleCallSpeedDialOnLongPress()
猜想:有个定时器,按住某个键不放,定时器溢出之后,判断该数字键的响应。 如果没有速拨的响应,那么视为再次输入相同的数字。
实验:
1.开启速拨功能,长按数字键2:
TimerCallBack()
KeyTimerExpiryProc()
KeyEventHandler()
ExecuteCurrKeyHandler()
IdleCallSpeedDialOnLongPress()
2.短按数字键2
ProcessKeyEvent()
KeyEventHandler()
ExecuteCurrKeyHandler()
HandleIdleScreenDigitEntry()
IdleScreenDigitHandler()
ExecuteCurrKeyHandler()
MMI_key_2_down()
在函数ExecuteCurrKeyHandler()处下断点,查看执行顺序,理解如下:
在进入IDLE screen的时候(键盘没有锁),进入函数mmi_idle_entry_idle_screen(),有如下设置:
SetGroupKeyHandler(HandleIdleScreenDigitEntry, IdleScreenDigits, MAX_IDLE_SCREEN_DIGITS - 1, KEY_EVENT_DOWN);
1.在Idle Screen短按数字键
(1)首先短按2, 进入上面的函数HandleIdleScreenDigitEntry(),再进入IdleScreenDigitHandler( ),在其中SHOW出拨号输入框ShowCategory16Screen()时,有如下调用:
wgui_setup_dialer_inputbox()
register_dialer_inputbox_dialer_keys()
register_MMI_key_input_handler() 在这里,设置了数字键0—9的DOWN, UP,REPEAT响应函数。
然后回到函数时IdleScreenDigitHandler,注册:
SetGroupKeyHandler(IdleCallSpeedDialOnLongPress, SpeedDialKeys, MAX_SPEED_DIAL_KEYS - 1, KEY_LONG_PRESS);
(2)再短按数字键,如3
进入ProcessKeyEvent()
KeyEventHandler()
ExecuteCurrKeyHandler() //keyCode=3, keyType=0(DOWN)
MMI_key_2_down()
MMI_key_input_handler(KEY_2, KEY_EVENT_DOWN);指针函数:MMI_key_input_handler()
MMI_key_down_handler_function();指针函数:dialer_inputbox_handle_key_down()
dialer_inputbox_handle_multitap_complete(WGUI_DIALER_BOX_ACTIVE_MULTITAP_ANY);
dialer_inputbox_direct_input((UI_character_type) ('0' + k));
gui_dialer_input_box_insert_character(&MMI_dialer_inputbox, c); //插入数字
redraw_dialer_inputbox(); //重画输入框
dialer_inputbox_input_callback();指针函数:wgui_handle_dialer_inputbox_input(),注意是设置右 软键的标签(清除、返回),以及右软件的响应函数。
2.在Idle Screen长按数字键,eg:2
ProcessKeyEvent()
KeyEventHandler()
ExecuteCurrKeyHandler(), 在这里,currFuncPtr = currKeyFuncPtrs[keyCode][keyType]获取数字键2的响应,然后执行。由于 在ILDE界面时,所有的数字键都被注册响应:HandleIdleScreenDigitEntry()
HandleIdleScreenDigitEntry()获取按键信息
IdleScreenDigitHandler()
ShowCategory16Screen()这里,与上面的紫红色一样,注册数字键的DONW,UP,REPEAT响应。
ExecuteCurrKeyHandler(),就是执行上一行所注册的MMI_key_2_down()。过程就是把数字2插入输入框中,然后 重画输入框,再设置右软件的标签以及响应。
SetGroupKeyHandler(IdleCallSpeedDialOnLongPress,SpeedDialKeys,MAX_SPEED_DIAL_KEYS-1, KEY_LONG_PRESS);
//如果速拨开启,设置速拨键的响应2-9
此时一直按住键不放,分如下2 种:
(1)情况1:没有开启速拨功能,那么就没有注册函数:IdleCallSpeedDialOnLongPress()
TimerCallBack()
KeyTimerExpiryProc()//装载消息KEYBRD_MESSAGE KeyBrdMsg; 消息类型是:REPEAT
KeyEventHandler((KEYBRD_MESSAGE*) & KeyBrdMsg);
ExecuteCurrKeyHandler(short 2, short 3) repeat事件
MMI_key_2_down()//ShowCategory16Screen()中注册的
(2)情况2:已经启动了速拨功能
TimerCallBack()
KeyTimerExpiryProc()//装载消息KEYBRD_MESSAGE KeyBrdMsg; 消息类型是:LONG_PRESS
ExecuteCurrKeyHandler(short 2, short 2) LONG_PRESS事件
IdleCallSpeedDialOnLongPress( ) IdleScreenDigitHandler()中注册的速拨函数
通过对情况(1)和(2)的比较发现,问题的关键是在上面蓝色的函数KeyTimerExpiryProc()中,所装载的按键消息是REPEAT还是LONG_PRESS。即如下代码:
if (nKeyPadStatus[i] == KEY_EVENT_DOWN)
{
nKeyPadStatus[i] = KEY_LONG_PRESS; //进入速拨
bNeedToDo = MMI_TRUE;
}
else if ((nKeyPadStatus[i] == KEY_LONG_PRESS) || (nKeyPadStatus[i] == KEY_REPEAT))
{
nKeyPadStatus[i] = KEY_REPEAT; //重复输入号码
bNeedToDo = MMI_TRUE;
}