From 466741d8a78965b8509bf527344f289e50873092 Mon Sep 17 00:00:00 2001 From: Mike LeBeau Date: Sat, 16 Jan 2010 12:21:23 -0800 Subject: [PATCH] Migrate voice features into the open-source LatinIME. This includes the change to logging to remove any private dependencies and use broadcast intents to VoiceSearch instead. I have audited this code and it appears good to go for open-source, but would appreciate a second pair of eyes. Still to do after submitting this CL: * Reintroduce Amith's memory leak fix (37557) which was the only CL added to LatinIME since the last merge over to the private copy. * Make some changes to allow LatinIME to work without voice search installed. Currently I believe it will show the mic but fail if you press it. We need to base the visibility on the mic on the availability of the service. * Fix this code to use the new Gservices framework, it's still trying to use the old one. --- res/drawable-hdpi/ic_mic_dialog.png | Bin 0 -> 3634 bytes .../ic_suggest_strip_microphone.png | Bin 0 -> 548 bytes .../ic_suggest_strip_microphone_swipe.png | Bin 0 -> 438 bytes .../list_selector_background_pressed.9.png | Bin 0 -> 4203 bytes res/drawable-hdpi/mic_slash.png | Bin 3095 -> 5615 bytes res/drawable-hdpi/speak_now_level0.png | Bin 1508 -> 1512 bytes res/drawable-hdpi/speak_now_level1.png | Bin 1587 -> 2215 bytes res/drawable-hdpi/speak_now_level2.png | Bin 1687 -> 3130 bytes res/drawable-hdpi/speak_now_level3.png | Bin 1636 -> 3647 bytes res/drawable-hdpi/speak_now_level4.png | Bin 1635 -> 3626 bytes res/drawable-hdpi/speak_now_level5.png | Bin 1706 -> 3670 bytes res/drawable-hdpi/speak_now_level6.png | Bin 0 -> 4006 bytes .../sym_keyboard_feedback_mic.png | Bin 0 -> 681 bytes res/drawable-hdpi/sym_keyboard_mic.png | Bin 0 -> 1440 bytes ...round.9.png => voice_ime_background.9.png} | Bin res/drawable-mdpi/ic_mic_dialog.png | Bin 0 -> 3312 bytes .../ic_suggest_strip_microphone.png | Bin 0 -> 398 bytes .../ic_suggest_strip_microphone_swipe.png | Bin 0 -> 309 bytes .../list_selector_background_pressed.9.png | Bin 0 -> 11006 bytes .../sym_keyboard_feedback_mic.png | Bin 0 -> 483 bytes res/drawable-mdpi/sym_keyboard_mic.png | Bin 0 -> 859 bytes res/drawable/cancel.png | Bin 0 -> 1259 bytes res/drawable/caution.png | Bin 0 -> 1100 bytes .../dialog_top_dark_bottom_medium.9.png | Bin 0 -> 1574 bytes res/drawable/ic_dialog_alert_large.png | Bin 0 -> 4089 bytes res/drawable/ic_dialog_voice_input.png | Bin 0 -> 1040 bytes res/drawable/ic_dialog_wave_0_0.png | Bin 0 -> 8471 bytes res/drawable/ic_dialog_wave_1_3.png | Bin 0 -> 9017 bytes res/drawable/ic_dialog_wave_2_3.png | Bin 0 -> 9614 bytes res/drawable/ic_dialog_wave_3_3.png | Bin 0 -> 10089 bytes res/drawable/ic_dialog_wave_4_3.png | Bin 0 -> 10514 bytes res/drawable/mic_slash.png | Bin 0 -> 3098 bytes res/drawable/ok_cancel.png | Bin 0 -> 8453 bytes res/drawable/speak_now_level0.png | Bin 0 -> 3263 bytes res/drawable/speak_now_level1.png | Bin 0 -> 3572 bytes res/drawable/speak_now_level2.png | Bin 0 -> 3974 bytes res/drawable/speak_now_level3.png | Bin 0 -> 4270 bytes res/drawable/speak_now_level4.png | Bin 0 -> 4241 bytes res/drawable/speak_now_level5.png | Bin 0 -> 4252 bytes res/drawable/speak_now_level6.png | Bin 0 -> 2201 bytes res/drawable/voice_ime_background.9.png | Bin 0 -> 20661 bytes res/drawable/voice_swipe_hint.png | Bin 0 -> 3111 bytes res/drawable/working.png | Bin 0 -> 33111 bytes res/layout/recognition_status.xml | 98 +++ res/layout/voice_punctuation_hint.xml | 49 ++ res/layout/voice_swipe_hint.xml | 56 ++ res/values-cs/strings.xml | 32 +- res/values-da/strings.xml | 32 +- res/values-de/strings.xml | 32 +- res/values-el/strings.xml | 32 +- res/values-es-rUS/strings.xml | 32 +- res/values-es/strings.xml | 32 +- res/values-fr/strings.xml | 32 +- res/values-it/strings.xml | 32 +- res/values-ja/strings.xml | 32 +- res/values-ko/strings.xml | 32 +- res/values-nb/strings.xml | 32 +- res/values-nl/strings.xml | 32 +- res/values-pl/strings.xml | 32 +- res/values-pt-rPT/strings.xml | 32 +- res/values-pt/strings.xml | 32 +- res/values-ru/strings.xml | 32 +- res/values-sv/strings.xml | 32 +- res/values-tr/donottranslate.xml | 2 +- res/values-tr/strings.xml | 32 +- res/values-zh-rCN/strings.xml | 31 +- res/values-zh-rTW/strings.xml | 32 +- res/values/bools.xml | 2 + res/values/donottranslate.xml | 2 - res/values/keycodes.xml | 2 +- res/values/strings.xml | 100 ++- res/xml-de/kbd_qwerty.xml | 77 +++ res/xml-fr/kbd_qwerty.xml | 78 ++- res/xml/kbd_qwerty.xml | 85 ++- res/xml/method.xml | 4 +- res/xml/prefs.xml | 6 + .../inputmethod/latin/CandidateView.java | 2 +- src/com/android/inputmethod/latin/Hints.java | 188 ++++++ .../inputmethod/latin/KeyboardSwitcher.java | 81 ++- .../android/inputmethod/latin/LatinIME.java | 625 ++++++++++++++++-- .../latin/LatinIMEBackupAgent.java | 2 +- .../inputmethod/latin/LatinIMESettings.java | 140 +++- .../inputmethod/latin/LatinKeyboardView.java | 4 +- .../inputmethod/voice/EditingUtil.java | 162 +++++ .../inputmethod/voice/FieldContext.java | 91 +++ .../inputmethod/voice/GoogleSettingsUtil.java | 175 +++++ .../inputmethod/voice/LatinIMEWithVoice.java | 28 + .../voice/LatinIMEWithVoiceSettings.java | 21 + .../inputmethod/voice/LoggingEvents.java | 96 +++ .../inputmethod/voice/RecognitionView.java | 321 +++++++++ .../android/inputmethod/voice/VoiceInput.java | 551 +++++++++++++++ .../inputmethod/voice/VoiceInputLogger.java | 174 +++++ .../inputmethod/voice/WaveformImage.java | 90 +++ .../android/inputmethod/voice/Whitelist.java | 67 ++ .../voicesearch/LatinIMEWithVoice.java | 29 + .../LatinIMEWithVoiceSettings.java | 5 + 96 files changed, 3808 insertions(+), 244 deletions(-) create mode 100644 res/drawable-hdpi/ic_mic_dialog.png create mode 100644 res/drawable-hdpi/ic_suggest_strip_microphone.png create mode 100644 res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png create mode 100644 res/drawable-hdpi/list_selector_background_pressed.9.png mode change 100755 => 100644 res/drawable-hdpi/mic_slash.png create mode 100755 res/drawable-hdpi/speak_now_level6.png create mode 100644 res/drawable-hdpi/sym_keyboard_feedback_mic.png create mode 100644 res/drawable-hdpi/sym_keyboard_mic.png rename res/drawable-hdpi/{voice_background.9.png => voice_ime_background.9.png} (100%) create mode 100644 res/drawable-mdpi/ic_mic_dialog.png create mode 100644 res/drawable-mdpi/ic_suggest_strip_microphone.png create mode 100644 res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png create mode 100644 res/drawable-mdpi/list_selector_background_pressed.9.png create mode 100644 res/drawable-mdpi/sym_keyboard_feedback_mic.png create mode 100644 res/drawable-mdpi/sym_keyboard_mic.png create mode 100644 res/drawable/cancel.png create mode 100644 res/drawable/caution.png create mode 100644 res/drawable/dialog_top_dark_bottom_medium.9.png create mode 100644 res/drawable/ic_dialog_alert_large.png create mode 100644 res/drawable/ic_dialog_voice_input.png create mode 100644 res/drawable/ic_dialog_wave_0_0.png create mode 100644 res/drawable/ic_dialog_wave_1_3.png create mode 100644 res/drawable/ic_dialog_wave_2_3.png create mode 100644 res/drawable/ic_dialog_wave_3_3.png create mode 100644 res/drawable/ic_dialog_wave_4_3.png create mode 100644 res/drawable/mic_slash.png create mode 100644 res/drawable/ok_cancel.png create mode 100644 res/drawable/speak_now_level0.png create mode 100644 res/drawable/speak_now_level1.png create mode 100644 res/drawable/speak_now_level2.png create mode 100644 res/drawable/speak_now_level3.png create mode 100644 res/drawable/speak_now_level4.png create mode 100644 res/drawable/speak_now_level5.png create mode 100644 res/drawable/speak_now_level6.png create mode 100644 res/drawable/voice_ime_background.9.png create mode 100644 res/drawable/voice_swipe_hint.png create mode 100644 res/drawable/working.png create mode 100644 res/layout/recognition_status.xml create mode 100644 res/layout/voice_punctuation_hint.xml create mode 100644 res/layout/voice_swipe_hint.xml create mode 100644 src/com/android/inputmethod/latin/Hints.java create mode 100644 src/com/android/inputmethod/voice/EditingUtil.java create mode 100644 src/com/android/inputmethod/voice/FieldContext.java create mode 100644 src/com/android/inputmethod/voice/GoogleSettingsUtil.java create mode 100644 src/com/android/inputmethod/voice/LatinIMEWithVoice.java create mode 100644 src/com/android/inputmethod/voice/LatinIMEWithVoiceSettings.java create mode 100644 src/com/android/inputmethod/voice/LoggingEvents.java create mode 100644 src/com/android/inputmethod/voice/RecognitionView.java create mode 100644 src/com/android/inputmethod/voice/VoiceInput.java create mode 100644 src/com/android/inputmethod/voice/VoiceInputLogger.java create mode 100644 src/com/android/inputmethod/voice/WaveformImage.java create mode 100644 src/com/android/inputmethod/voice/Whitelist.java create mode 100644 src/com/google/android/voicesearch/LatinIMEWithVoice.java create mode 100644 src/com/google/android/voicesearch/LatinIMEWithVoiceSettings.java diff --git a/res/drawable-hdpi/ic_mic_dialog.png b/res/drawable-hdpi/ic_mic_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..349dc4b37c6a5530cd2846eeba3024f976cab75a GIT binary patch literal 3634 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 Eg7g2=lmGw# literal 0 HcmV?d00001 diff --git a/res/drawable-hdpi/ic_suggest_strip_microphone.png b/res/drawable-hdpi/ic_suggest_strip_microphone.png new file mode 100644 index 0000000000000000000000000000000000000000..c00b4aaa645b244f89b209b540668737795f29f3 GIT binary patch literal 548 zcmV+<0^9wGP)Qbr4?NbAC_iWm?CIEC93Ze4hRxD604pbVe|G=T?Dj=%{xTqK92J~o6qfDlAd z^uzJKo|a`fxfZ#ZT#*QjzzB@M2+XDAw#~_l} z3dS2iorb!meFKOVt*!S#YzDLvva6{Df_?rFnt3qX7YqS2mpCIZ0wXY^%-RsrV~nH< z65qB(cHdwMIl?&yYt3M8i7?_uF1ZHJ(FwK6XR+%wc@6KjrNO)lo5|U`PwEvDsfw%x znL9bbU~yECsTX{H*MR;3Ar)U(1L)*UN2(cJW+LSJ43Pf8723;^UAJ;BJF&d{V)pV1 zKshP20$kTx{DHMkvbG_|6|nZ)ss@HbBjyDfXm`#y@GF4D;N?dLN;CCHD<)y zDmUhysNr{=bq5VVCSn9)-Kt=p6dT44t+};LALZINRffA@U^x!;pM7)&!$SR@#HRbv zWNmBBu>N|+jG7v%s^U>EjX!|Qu*Yr^8e4RHdg}9P^GDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_cg42%(;E{-7;x8B^a1+rFks3r|)(xXRNY%zf@1Y z18ew{rGgpFoD+M?rzNdsIvwnwe3|73|FT=(CM>l*P!zN84{Ps1cAt+6o@B~Q)K2;Q zE+(pC?vxlK-JL5pNo1+lgvAGKZttIUe14f6_uGbf4%A9Z>& z(YV2GRk?Jc`dt?Fb8p_Us%-u8_T0T)&koAZLh~$;d!zr6&H;wvCn?t)v^G2gMg)VW LtDnm{r-UW|Fh{jU literal 0 HcmV?d00001 diff --git a/res/drawable-hdpi/list_selector_background_pressed.9.png b/res/drawable-hdpi/list_selector_background_pressed.9.png new file mode 100644 index 0000000000000000000000000000000000000000..ba79cf7f85d3cf1709ef6332322fb6543555fab3 GIT binary patch literal 4203 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 JPDHLkV1m-vmY4tl literal 3095 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 Jl4j%@^M4C==)wR1 diff --git a/res/drawable-hdpi/speak_now_level0.png b/res/drawable-hdpi/speak_now_level0.png index 5c5ca309d05e05143d6a151f24fc708670705bc1..a681da606b634b33c3ce5be7096c5ec42afca4ba 100755 GIT binary patch delta 1457 zcmV;i1y1_p3+M}wNq>q-L_t(|+U%YEPa8)Nh6iIefk22!NG%5tg`*lC z0f0dO1_2m=d839{DOE24oEyr%RW_;Y(z)0FRrW>Mjz!HWFx9Kc=ju?55%8 zww1kA)&?+pO*n&^yFhc^Q??=CdH`0OzEQTK>}pQeJ5csa*(reKuPe${m0iyHx+lt> zDmy}ym~UXQQUENHYp#S8Rr(HWMA@K6U*X7Vl#HiL(rLXLO1Ov-)n{hXBr7=PawZNYH&)bR%&!uN5G$ z7R7J)YuShiigds!6_VDeCnZR6nW3havCMq0V<7`eQxeRs!*X>qmYK-HcH5exZ))T_ z&i}DPV1LIM%4_Y5RwOW;RCkwR{_irC(2-$ThjkV*u&xHQ@tFVbIRv(6SXPt!^}Y{F zYue&M`+pn-9zF4GQr1XTaxl6E)=X$lcN_rQNvI{wl+PZP0oXyx>%3z>ZnotQ2f*Td z)+s%^zH*Vf5SV&#tbiqmY$ z=TFMgB$7rgxth>FaC+C5RP3Z`UwoV<^j&Gq;U``Fb$I^^t2}U~d*~bYHVf0+MEDa6tHX~W9Y0&wX z+7(T>FEj!To;klxgVQ0VDSjrsE3+5d@;7b1FG>tOqfyphZ4dBm=dE9rhn%J@WxpBr zSrhbitwmHD`-b5**R1=>ZfU%i1C^(?M}PLVf$@);KapMnuFuMzlf9E0_~eNnNiV@A z*V>;o#+bqOVZ#H=-!^;-XRCfRQ{ju4!41nCeJy!oRzjJ zKx&rr6aIWSj%rlKXHD``+zdV=w=2240u~Kcc_HS!XR!DO%{S!HUI5oDIkS<@HR5@EV5Z)73&4}XJY)YSnnZo^0+}U8WvhwrSpYM8V6L^~>6h8N zLQQ$nuj*_<2QbfqpgMr1>lkGT3m9*Z+x4IvyW}?CRZvkPrs&3UJblJ zgB4Q~mVELe9NwYH%Luvv1}c@dNrV6lz#ssF01Ut&0E3M5p8x{@6 delta 1453 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 delta 1533 zcmV7Da+e$8tHBm~8F}B9*Iqtb| zNt>OS+@0B(?e`0ZeYksfcIUHm=FE?s>1sBc1f`=ZkOcq+0e=_-U;qXI7zALcYiUKE zqsCTe>u2lJ7qL%&n_z3|ag6OW+ia>2+Ld_2c{$r4+a|~V9cMetHU(heB%tnOTe8Ui z&#?`&9RV=E>So)?wxOWwonSk__78#%4=)(ot^#3+Zf1K7QKCOLSod(!9|5P(4d24Khn0D}Mw0x$rB01N^!0D}Mw0x$rB01N^! z0D}Mw0x$rB01N^!0D}Mw>P#Wm>5vcR?`+yTCTi zHcHu=Ajt!hhkJsug-=?#mF*nc2YO6NvOdTjJ+`aCw$JBF7|JCM&V$wd;JeB1r?5Ue z#qLYMB7H`$AGe1BmbX%kdCgH72j4viZKdNx z&hPyeZN`}@0Q=SAoV+FVWaZHB1Kj6#26tw&?0?^HRRA_&an5FgTl|8uRYZMBqS0Z4 zJKSt>o$)FF`^n-Q$&jsv;N>%q_xP!ybZs@fP%VvC0oas9^d%ZFWXiW}UwgQ}uh>Qm zFVlc!ggI3OU}VUU_V(DIMM*eX;C;!p4jIlFB)cA)W4<#nB(P(ay%yUH5o4=9`-nPQ ze}7&g*Zq1eGDL>kEbG7#-Sbh~9^`yGqsK(}6R3*~oj%?I_3xB1< z_Bz07=rd7Ofk}}*NcMehGHK@-3bRD{DotyRLu30Oh3Pgc%_X)ZGpHVSIA7f2VGS0F zzG>+nyo2o?avLq)@4KNK6EM;Y8gTrNG)_OKY+I=!w4Uuga-XI!tS=B~c;aC9@HC>KkvjOL{DxHk>n*LMh5q@>|=#K(GFPe1DBz>~cB3 zCH^0Pm7&+^?Q5rLCbxU5muiPl!XnXWYV>LoU_nh1y_@=TV%Y}(g8&QyFaU!947ylJ z^mK4z_d!1FqWo>=rHiU=xRgvI$Qvq=FFoJq#`F;YTRg0n`0!ldWM5%uZvmJ)th@Q} zW(i5l1kpVVZ8Ww#iMR?u2s+%gqQtaU0+_odOHBJLfVpdk!ml+YlEKXn z0nAZc=^y8V3}A(vUm>H7DCq)fI$ET j0T_Tm00v#G{{$ES=5IE7YcV+400000NkvXXu0mjf4>8$! diff --git a/res/drawable-hdpi/speak_now_level2.png b/res/drawable-hdpi/speak_now_level2.png index be5a7d37aea56566098edd2fe31319aab7e92513..45cbff2b7f63cf0ceb36f4d4578b564fe0c659c7 100755 GIT binary patch delta 3089 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 diff --git a/res/drawable-hdpi/speak_now_level3.png b/res/drawable-hdpi/speak_now_level3.png index 82968f4768864ac8bb93f9fd6289a2d683a60e0e..abda8f683c4670ca983559d46e509da6021953d5 100755 GIT binary patch delta 3610 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 h0D?g6}~&WYbROTdDw~bXp@GdR3)f{iWaH@ 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 KMNUMnLSTZb#K_$M delta 1582 zcmV+}2GRMd9ODd-NPh+eNkl&q^KbN010Zqlv+WmMF_NlR-#x76)Bi%tx6?Olu-4LYEbfrg`ieyuv9{W5Tiw? zA->1G!w@e!Z|`AO|RQUTj<~PhS2$n7ynfEfUO(?yem?xP3!0AZg0b_1SP%Oc9%zNM^rq>O&r;zS? zO&fwGh%1@5rhl0JZJGxJO9*#pmzZXE+XcarfxJ^);~}3m<{AiAJ=#6ywH|_1kE=cA z)ds<;#}yv)%5|5Rc`R{&2A%iprJYS4O=_~(w7|Cd63m5WTD58y?YrA^wy&dwRft*o zYq>@v0K$A21Op%#0Kp&_0KotV2EhOb20$7!$>QEX4A)C! z7kA3gt*vuhKjTrbAFH%=PRks$mpJ3N-li|pOMl^OkAj_wxVDnq$3pyB3vRuun`v0$ zJ*|WhPtJ$raU$Y+r{SIPLM;e(+Hg-##IxvN#%n>aQNuk_A=@0D;+_<3+~a6n+Z+#637-Wo7<*0U4BnTZ&rvBy zn16>;F!2!cnB!sUvv`vzz&*;k9A0Q2Uvi z4dYF#+G3ghIh^J^SP8z*nmWk5-_X6RRevEKr0Ce5Jk_r%r6tHg%Q7=?75z6u@H_Lo zetr?di(8>KtThG(4*IA-@8{MJ(BK37vDYypFXEs>J+fi-I13eIUC`eSYg%#FlpN7l1MkSg5wb6m zJ+QhE8RIh@~Y1HC3=Hpd#Yh7jDjVNIc z^MD~TQuBh9AQf>|TTEj@?s-y>X`L6y77wl6F{})vLLQ;&VuVR!Mr}Hl2V?TMdu2?= zvymLwGNQKR=5H7Cy4^@75@kx`Ve-3Ts)RF|cR%@EVi&AnB}go>mx}XM(|;cFo7TK~ z$?r<7Af1k=0soM)n|U7<7sE6rnEt4aQ77|W8KM30_DN-niYH+tnX|fyiqjyih884U z+-dzjsp-vxQURg{j@)%aHWvTB%LNEY=0T2v=0T2v;U=R$* z5kiS{bW`!blBgpWEL(wgF@K+mxc&nb*T;`Ru*xCfq=ynp%e92>%3#DiCZD?#d`%nY!5w!Qx|0hItntSbR)pnD-O}iw~Lex|Bh_vdLitg2jid z;FUENK2LO$mBX?I@jTr6${^cp$JGf)dt8w&Se9a+&1+?3vOf%{-6t*)fM5^|fM5Uw ggJ3`w_*Z}d0AzF;`PBZR^#A|>07*qoM6N<$f@8+^Jpcdz diff --git a/res/drawable-hdpi/speak_now_level5.png b/res/drawable-hdpi/speak_now_level5.png index 77d0b8e9bb4780599c142095b4c48b44d4c9e496..7d4fd5f20848b753e27d67bd4db7852265cf7432 100755 GIT binary patch delta 3633 zcmV-14$kqa4b~ixNPi9ZNklKnOtu z5@cVB6Z5L5w`)qAJ_bbxhRx6>FY zKotN`KhXfu5YZss`xR(LfwfAsLbOb@g!fed81VlQ4;u!q*WD@{EA+b=qFJIj0LZ|tR%)UWU5&K$WK77~tY1$h zDitVFH3Fcv6YV5$-r)QG$N1SvSyb2O!!Uf5pY-Dt(SJ06yDZYysfuj3?%gu$ZIv(& zYH$EjGfA|I=wP8xxQC?*fA1_)0+_zPnE?A!5Co6VuU^8K=*KKeYo)Acp(@mpH43S^ z4vqa;df$7MMHDEncT$f(NT7WK(x#^Z)j`eHG0nFOEK!AhP=gZy>nMTsg)V@l(_YS# z^X4*8)_;gd9C&dO)`lu9!dxH6cy%*1?1S{aHHGrFa^56qb0lf2YOWU8I#2U0lP(#z zwxGxFCF9}&fR|PpM;Uuj<`(c!uu;l<3#Dri(zJtm|1pxV8&WTr%HXoNOq4wcUL0Tv zy!0y*ejhdD`+C+}YGv(1*(2b^cYrllhef3hw|`NOzZ+v&uhJ08+@{oG(KfYcOAnIq zYf#27SZ}>$qE@DiV}szy0oH_%K3UZuBj8AnrE5*fQ1%FT>9b8O+9Y9Xi@Vg*U!NHx zwX%mrB{~Uf&PM?QJ*%Pv8S-)fJoJMnCt)qduch`m5k4%pY8qo@2Zgh+kFcap(cQuSHJ z?^6LSEx_bJIeXDgdY-q3=oYS67=|b4c@gBRMzK*X#!rRvQ6!FNFzNd~*JmV(qJI~N z&Y?atF%@Y&VDSUx`wE4^eFWB>sJNkuUMA4KL-e>(k%7g4i5D;*^xH%H-%0ct)Uhf_ z1lZ$25FA&MrO!!QZPx2kloJHjrwFXOOk+$9K2G!?(NXkRQJ0=Y)?=gq>jRJ5m}ll) zfyIf#NZiGBHT6gYsh!^RyWATEFn_KfM*z6HS-JGLPnz0!VgbxI_5?K%K70k(R`9%T zo1w0|Vt{#hkg)2(a;m@q)51rd{=T0cW2Sxp+$i0jrR5kXK4jQn9>>6Qv&5%v4&s0N z@*rVxD>3On!+^53#6*^mc`F$Lwia_LW^`!FuvyYzd3gX#PnwgWW))yb_J7CbXk{A2 zXEM`;wX(~~ESLG@s7a1*RW>R6<);ByRI7JXN<`N4w#NXI_=Zy%O4t;5C~LsLYf@S= zDF+zyy9`vQ%-YMSKr6tmS1NIB5=vm7%uvEkg731@1Owo;Ra&KQXO%il1vEbe=@P)W z0v8hi<3W5#jd%RrB7OI_jDHM|0A(*KmCn2kB^VqAljhYl=U{077OJ&19=xX${{N7v zhgc{mz|Ihz%0RkKaoGwmF*ruRYpZWXm98o&GkK6O35>i_xbsZBUIqRLcxE0yX6KQ(mr$ zxC}J-49fORef{uAl7EE=O;R%TxcHU40k#UjO4JyCY-2ul2R(Q!8;8{xq5-Dp``>UR z>=ehXN4X5lze*^32pwoAcuP{JT*rCTc{NWGCgYfF>T%ro=ZRiTGVgiY0-$Y$I^sNd zUUQZj^v6U$?6RpJaGsnumw~d%D4TiMNj!Zh$(-l9Q6A3%?0-cy;Wl{zOvbTgRAQDY z^;9AwzJCYe(C%la5b^9>;jwe3lyK_Y4Rms974|nDmuOWeUACgu${5V}REfm+0@OD6bC_ zeb96sqK|jHe}6^v3wl3?d@n(b6=AJ%hdIE!w2}V>%ImiPY$0ufBQ3zRT3kef@L2Rq zYUF#93=nFl`>FSTTUB}<4JuNwKzTh(^lQqGukkp7xWN4_mW=*O^k-b>@hbAVgypjU z^DPEzH^92zv=MTh>qL+9$ZJt`G?O>Lv|8i_zett)9e*|KyNGT~7|#v^wBx28EKKG` zC8cU-D9@MZ`2;4nH)75208|xE+E?g#8oAe8VBZ0QY#P@(|C!FzK%+79Ez0d z>!|c9M1K*cyTr#oOcHya0G_naOC9PgAWw*h5s&pR@WRdUG3j@XZYm5Px8QrSE>Gu9KQqs|pp<+O0qb&y<~G z9r{0ba$J#9)3C0r3zu)S(WFS)qn{ zis(rU^z%?dTGiQ(~nb7teW7A?UVoQ5w3KNnzavNUZ+4BzcACN>&c{S1Ni zbzEI_MlBMzy>6H{z;ut-pzVQr{CtP%v43X?YVd1NgXh)(tF3ug9syeqvz_WYc2)6xsuTuX!1YkvvL z@|IbBNNx~PH4ZD1fqN4H_fdM@)FYr?B%ppu&u0}-b86YC90w~4z_PqjF*H~DGRjUh z@1xCw>Q}l^8eqo1NSo!*Wse4rc=H zcD~Gp=yfnyHj=8Y2kg>DKs}?zr+-UoGQOy#%CxwUdo!uThKi^gW@VB+fO(T#WiJ3$ z?{p^6b`yZ_ZF7lBmX!WL&)1a2CjiM+_u`Wwli@_E+O!vMqhSI>6%fCWWi;lzsUKVA zclLQ?5YBc0*ja$}GAzFttp(F~3V*WQGz}HV z5;lu`wQIE%<5aEyTSww#?k0CE3s|KMWLr{WRmrFwV%veT9e8ndy%-f?`uE}8@33>~@B1OKk-72^USz9^ELsRu zL6N>GPa1p_=KYB2>{zOYZ-2&MZ1|?W+O8+>0n~3`BXC8Fz|!%l#Ia^jNs|Cr-RHu5 ztkX29z#3HmiBTgazU*RGfwKv;q9tIhg^K_nqo6IOenL|K6HlkH4HP$yvc^o^14~aG zv@4vrA4F`a+5(yl66PteWF=zgVQ*Z#v7Fv z)c7ce<*fkBhP6ZiYbyX?@85e6S*F(=iWh?)3xePgQ*#BlfO*?8Nm#{(r77P6>GIXG z6GurqMqnMwNc#Ci=rQ@)%WGsYH=p?M3O&FF{NIl^X!Vv@j4LIMm9OC=f0Y4#eZx%pAOULcRy_EPB%=W z_??au-|aE9Axwp-Ipl~_&YIVhElxO@FHLbnU}bz&HJ}`|9aN^ZpAulQqb=)+izenZ zWz*uX4HBlu)A*iM(bQM!y_5jcAp>RAUfdDFZW$ccoY$0TbSy2K#yd{ZoC`(f$~$3F zjVgMr0A^y1lqx%ai_K!zyW{}7c2if34wrhD{x84)X-1wr#@jd!00000NkvXXu0mjf DrDoqL delta 1653 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 M07*qoM6N<$f?VNiKL7v# literal 0 HcmV?d00001 diff --git a/res/drawable-hdpi/sym_keyboard_feedback_mic.png b/res/drawable-hdpi/sym_keyboard_feedback_mic.png new file mode 100644 index 0000000000000000000000000000000000000000..cb86a5598a7a9213a0755ea1670f6e27d25e9528 GIT binary patch literal 681 zcmV;a0#^NrP)~KI=mg0I$p*yknV!!l1GYp-uF{<@4{S>xmSjmzhha!=neLJs zCkDU(7ytv zW})((?VM(f12Aq!)>`zK(H>~Y>=J)}RR3QAR_xn7K?$Jp2-$gDt2A>)E(%cE7J#t% z5HPm+vkMLb;*{Vr(cq9tdP8G;qD3nH)0*GBhq48m^e^=%O9<)#OJ4NZ!89 zXYZWE@$v})*wg}9YwAlTxhuf{uDPwUfGXp-$xM0J0_Ea6vLsEgA+$oC1I?ykR7D^t z+JwHqbW0yNBj@*M14f!q9+byBKXKIo|8N< P00000NkvXXu0mjf%Rwia literal 0 HcmV?d00001 diff --git a/res/drawable-hdpi/sym_keyboard_mic.png b/res/drawable-hdpi/sym_keyboard_mic.png new file mode 100644 index 0000000000000000000000000000000000000000..0a0a68a96cdb53b36df9610654eca6e3ecd452b4 GIT binary patch literal 1440 zcmV;R1z-A!P)& zLnh>PDI3MUoPDdYH^aC^V>t;83AO=PB_iA3P62R1^BpO9du`caaduDAZ(ByauAj zi4eyl<2g>|T%6nLUx$Ak{x&mv_SO+3T<|e7Yp=D}xBvZLzO_bTj2X^SlMQFAofA4I z^uHryQg%p^q-TDj!Mbt@O+BV#JcLAGL@UdLNK65CA`59CBO?(rz=AO0HBKN52q7YX zD3W5SCM3x4IaWX>ffcWD0ztqbzy}BbjtHrgTgZruX8|4tJjy>?TU)QjVlm_L^0Iq$ zbkqfXcL8_sAsCX&TrSrwyWQRl*DC-|B5A8y zME_@f9fY_w9|RQf#adcgZn6Z8lPoDIc?ZT_1r*?GHKv*ncixMDX8^D5?CfkamDbbK z^COIV1+DauntRaoWt~aXjOKqJH#av=ZE$&cc^O(JjYMHeGquP&7FV*QVXw-6dYb0F8hfEJ<5mU;h)vH38lP*hN2lF9ke-D!`)TU`kRZ ztR9bto7NDCL`-NQixyqu_xpqR)e3Ut61kLtA}($@kyS+cJyL6HYg}j<^78VY#+z|s z(WRxOH8nyL6BB>neJoW~RabalI2`to+NN2cNw_et=FbCO73S{h>iQmjf52ZwMMcHU z05p}?bp!Ar;QhI|x!-yJ=H{joe!mQO3Z;xitNe&kvA(*x`Wx?TXlSsD$ef&Xs zOLcX1&-M5Bf5R`#&dxe*Hd{CGBO}o}G{;CqMMaqqSrzmStyZ&6{Uh}=*#F!*H%_meieS=^?L6(9F8A=*r#yqW57oom6esB4Gj(b z6buIaVr+MJw*#(K0(fBLqV?~qNUfS$D85Gkg#a!|uMH0mf2(xj?d@&%#>R$AxdS;k zIPf$zHGP6)o(1FsE}%2ZdPTm3PmzvEtPm|#Ra;woeQ|Mdl3IZ_ZoTpG@&3}%(zjsz zOSo++K(TLChP|F$hai=Kq#nm7<)K^8L%P1c-T@Zc;Y1+v7I-><{`UZ{175@s&qp$8 z@e-n*T?fO638CZq&@p{ti`>`OciZRl-OI{ux7!P(_R(Pj=)i}>;ls%eAhgH`plf@xPTbK}KaptCEZ!e=WazD5{KR@5WG_=mn&N>Y9 zEKDO(DtE5;=R-D6`lO%^4!5?p4)mU=B`O_>qD`p33z#&s@V5x%FgmYrelI$8fcRX> zj`V26`S5p;NL+e?c7!AX#GzAuU=<@z$nd+LoHI(~T#>4UupUBMUzu`mC97Gk literal 0 HcmV?d00001 diff --git a/res/drawable-hdpi/voice_background.9.png b/res/drawable-hdpi/voice_ime_background.9.png similarity index 100% rename from res/drawable-hdpi/voice_background.9.png rename to res/drawable-hdpi/voice_ime_background.9.png diff --git a/res/drawable-mdpi/ic_mic_dialog.png b/res/drawable-mdpi/ic_mic_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..77613ca05c3686518c0879d325adb0111ead893d GIT binary patch literal 3312 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 literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png b/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png new file mode 100644 index 0000000000000000000000000000000000000000..ff629b6744095c35ecc715ed6a91ff90c7b28e8d GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0vp^DnP8p!3HGPoUoh>q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6{Js>~|R+EiWk& z&}g~SpjaZ6KINjq?R3VKIy!ta+ujLCBrHr`#Mb(!WP!8UgJ2ha_S&|#6G=%Tmv1@# zZm2N4U^u_?>H&*efif_cE(m1rwd&Z#pm2aeaGzVJwa(-ZKrb?Qy85}Sb4q9e0D>xU A>Hq)$ literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/list_selector_background_pressed.9.png b/res/drawable-mdpi/list_selector_background_pressed.9.png new file mode 100644 index 0000000000000000000000000000000000000000..02b4e9a536fedd342ecef1d0153ef97a3fe69452 GIT binary patch literal 11006 zcmds-yNg{_7{&J;lNmE+EFwbC#@gD>#>j+ZP=kmFVk1_TiYWvOL937^Vkd&>ECl}p zOItxi{3C3{CK%&f_c~|)-0Oa`&*R>?8HhWav%bgr9_yTWgqgYZ`i*M``_JsBln#!r zAHI?C1znHt=KGHyKl^)z-S=L(c9@p>clU>Hzs!*fA6$R?qm-U_O4lNN_4VZ(+`D=7 z+SR?^E?!D6UjF6h&tFaHxpZ`R<<0lcFK#}6``5*Cxy-DGdlrjDHzdzmJlshsb%MV8 zaIxIUqZZp3w{DLuJWsuo<9xk!C#7?GVh0!Uo6Od^$2NF=2mm)|(Ul+!T%*r}e^UDE zL0`}bdio%xC$p&C^E0}zxX^7%iQ!M73&0k-J<;R--zoihuP1eaB<9k^{7I-!(bi!} zM1bOY&iz)ORxB>=KEgcK=yC6U4R(U`W+Y~RuO|MpSU#c%#IPM@&pB~fM5q=!Vxun~ zU7estz7Mgma3^2*%3=$3BKFbg`;Z{T)e|wt)`}VnVGavoVHZNoQJwJVDu2#lX>nOx zwb;J6_K=S-&*da zkgL!H!-ABhU=G4}ls$CR6CvV6-|Lj)z!P$j%UA`G6zaG?$ELCw+Fh}os8k>cq2!F$+e-+ePl;y}ppEv^}o<;<Ow-4#+&mGC|*2 z#t%&$y%Dy$IA^@;NiKaNuGzPLLo7luO<9UONZgTJMCZ88({}Vcw)#bmVqDJ4c6~#U zAfjTNXv2?j@jXU;L^vRI^0}yq9O7P6V)b*#Np5>H8hD-jXD z`0?ynK96~Ch_622S#HQoaANj6K@&}y>9GaIa?NJ*gVW!KG~Bf?SAfmUmQhe3p@qT?RG5IkNGwTj;_XP1}M*q&Y(Te}Kv%g5`xe_`NrM zXO5%n=(`YdjqbyOMD{|2Aw)TBab1x7xrZ5!(U$MmNbhk$Dx?w1J1Q52;ExPlNvVfU z3z-e}%+dR_Aj)a#f|Nr5=rL-C5E05_J2G>qz7d}8yAR;{C_z_v0IDSO(GjV-E xG;R%^5gSDrymS20H+O#eLeJvp>W#ziUw-$qe*spuA{hVx literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/sym_keyboard_feedback_mic.png b/res/drawable-mdpi/sym_keyboard_feedback_mic.png new file mode 100644 index 0000000000000000000000000000000000000000..247d5b3a9cec75d14aac825139c52ab6207f1c23 GIT binary patch literal 483 zcmV<90UZ8`P)%nybc3(~$^@kozy`2^xvLC1os@7dA&M&5(vuLxm*@LF<5EhiCD+Sp;Z+C} z0x$vRoF{AvM?%VI31JiiE<-D5dBP8G>%j+N@6RSkpc!~M<4mY#A&^g>45$$TNDf$I z{I+xz_|gXofkNQ_6UYOnCd4VmO?G{yq%qy_sz`vnGs}JHZ@YrrUuJ@0zHv~b@8Yk31 z0%V4&D8XZ?V-X@?16lw(@45_pWBo&q$Wq4Y>u@;QM@B~CXy<@D@D1{=UiZqd7kH>Q@nM|f+mhX_Ep`j@HP6BOwY^rvR2wH*O>FMd0a*YrP`Yr>9)PhB^ zX%t1YgS~FI`$TQW9!Mk->BDC;`)OBUYGx8usZ=U9?iY4TAn1*eB+1PE!atJ9yj60T zm9Ca1huAHaYROwT_6|ZP94-B38FHI5^nH zBzjJEWHOm2*=+VHXMB^94{TPe_3-Zxo6SiRwzjs)Y6PpRs~b@J>~^~og>pY1m8eHR z=`1ZSF49C(e}DgZ^2gZN*qd78D=RDS=jP_teLkP7tENWn|2JV39EtQT?C=^D!o08n97E$WEQ919@#9S`- zF%SqmWP=KB0pW#(g(Vs@KR^Ep?F+m((TIQ|%K@C8n3#B^6t;LgzBD{M{0zj8$H&KC z6bgkR^`+D41gh;-jCb+s1tS81FBl5FGqjUbDz#QyO^d~1VP<9~hB23b;~Z_~ddsy! z(#bXdip%A?ryPmj?;pj#8^Af>C>s~me5;kE#8v@HOjLr?OZj~MGj+ydu}@HRAAI5D zD*q8ZbzGS;@5C}YJA1uUDjn7jErO-@ewIyyQ|A%dQV!{H6RYFf{Y)-7uY^5p^h z%Bp48=+dXcwTUe4g+9O`EL7EuMOg8LYhQbV**HZ}-$~nrp_> zzn*eKz!$FArJU>5gZf=?%A0IzIKRFzP7y=Z0;MIyNWfM~O9-VU|1VrF*Uin%+}s?8LKbO1RX7&%5EmC$QBmP=I1&;PqSXJ! zy1cwxSy{QhzK+P>laY}Tr9S`Q)G%quH>9Mb3=9mw+tbt2gM$OKK;68&JVj9=J59Vv zB$Af%Ar0gczCF+tP}@qY-}L0gDw$x`t0niXt!FeH8nMO#e1BB6PdJ>mi$a^ZZ2N; z_Vz-}2$XJYY`nO*@Or%v402+@+1J-6_GV^g;?-uep$C`@KYMz5Mn*cxw*Q!8g65miW<12q$D*pHE6-9pUv=l1&~=Qh5;&S zESvx4L=u7WnDZeIPz6bg(A(YJ)$c_B3S-@Fx3+@S$6zRF15-DUySqD45-%()guhof zL6S&o`XbVBbaVu@T3TAHR;zxm&1MrNwALcNq0u%2OIdx3cpOz)S{l?Xq(#i?+rxBA zA`8o7iGV-T)6-pDU8AF;J3BjY7>$XEiHP5^u`!Rw1EtH#%HS>D{89-@+HX@=ydEAN z*45SF69JpB6uFJl(Jgl2qAr)q>2xCD(X-gKy1MH3`?;p&nwI>)_VzZ^ZEbD+ts)wI zKA)JQsi~>9wzi?6A-spf-QC@jlaqg09xIB{-{0S*qOD^!pNEHs(Q`pTfp*29A5QWn zk*7S4ZfIx-^Ti;EAUQcXLQZ|VsA>OOw+Pa-w6t$~K&mGtCBfKGPr^vVLD>~uUtdpY z2{DkgERP8>Sb0oo2{9OymJp*QZ4@6262kJB5JG7QAzafEV$7s9aTEw)(h@?rrX_@E z(#FKZP+CHaf(aBA6>%U4F$#r+h0%!F_4W0$v$MCiH;xD)(qge#>~?#3dHEj!1^}BS V?WS+$cKrYV002ovPDHLkV1my|Rbl`D literal 0 HcmV?d00001 diff --git a/res/drawable/caution.png b/res/drawable/caution.png new file mode 100644 index 0000000000000000000000000000000000000000..eaef534254f1b5feef517949b559f5653b81fcba GIT binary patch literal 1100 zcmV-S1he~zP)XFTM0)1qJb- zAeG807Nkh4=!)^sjMQ}}lbs}!YN+BiCUmqpjx0>pjx0g z6i5hBnG;H>bzmE4>z~enmqLh9g+8PykWy*~7~~Wm2_X&_Rv@L+0N5$0b|{26S~!7} zQVrk{&?u-n1|AC`#xVqv5#!&`LL79R;X(yzrBoYuU@1^W(NiJB`9i#61%a6u0XrFi zG(8VXUj8H$MJdIg%}Cd#AA=m}2})5a1Z^hLMtTH!q9+(d(Sx*7Y8P1d)Z9o2ad2e> zQcCrKy`19Tz#Cu${M5g7fIGlVL$murh?A=#&>qmw5$8GZKIhVVz(!8li4bCc?t`?Z zr=L@NY!CyeQ*4J$ZwJJujEkoIdf@^;PpG&r#zCZ=^a4F`P?7N{XI7KodJ=Rl^ z3i_yCAPahIZr-L&P>Mnlv~5wR<*Cm0TnVJNQhOFv+ZJ^?7Ik{M&$%JUcD;0?pnL^b zjk!jXf#_*lR__$}u&PC}v33ZGWJG#w2x$V>Vy^UMM0zrTRvZI#P>N(kdb0kTjzK&q zMbaZZ!;&{-x~5yEJ?%?60_j7*vNPI_XMzB>v`@(pWP1oW&90Y>PbTwr*eE^GwmYg55MKS?;&|4ZU&qKTy-(>>yOdIOEfdrbFBAEa^(}wzXzAr4$5R=oy}0t-}l zZ?a(I>IZ(cPBG^Qz0+a^8##*-A7n&&0KRI9^6czVT#7=Gj7Sd!;$-EazZo@BWFn}F zPmqdc%q`3Zi{7?F$_Ui2z_GQ0er_|{*}TgverACh6*#s8+-LgP*nsLjq-&VA8Dd*k z&$Ev8sJ5h^=&cl{+bIYH7bmD2DXvFMuh@vivC+({c`kAc_bQ4-F>MU&>(_g>wV0kC z>|SA!#=wCP;>2aKnjH|XW0$!)4|b|wtGC(r_%jPsTP;v6P%Tg`P%TjM_GbVQLzTy8 S@WfmI00002HE+EP)d zNG%_Ns2q?uJVcM2+CQbIs?baS0j@nk)l>fndT&o$5xpP|v?1c7PvX!}D9}7R{^)MH z&YLW=Yv(nNdD5;laz31$`FUn`*N%2*9LFTjMkyUo!1U2v^+6z}JoE3!c-l}`o3l6> zVCWF<=?DyurT*e!ARP@1W+*&T&39>l7yx#RC8!wm87qM@f@BdH7K4&uWB{FzG%zP6 zPcX5-(Lz2~fsquDNO~P1pT~$NwH{J=#L6ftFro;tSTa0|5X4h)TFA*)-3CV6h^XLX zC=5oH5D_Z%5h(`=Fl<8z4q9U3GN~|`WKv~PXY$d~($f6#@$on9cKava_g}>$YP>Jr zC-0l<;JSp)s<5FVY$^#G2QFNXMFL7ZAj8y{e8^;WZEbDI^Ss~VoEz7{b#a|ScMXBE z0aTBrH?fLgTh134QoSp(u&^+3dV2b^>$=M)Cnw#5g9GpI@X)`$zK%vQi_Xr@S{oZ1 z<;~4acXf5O#GuYrR#v{axVY%BuLCAsDHJ1l(2#*(4mbd&C(UN_>*eL;Z#m4~-rmF2 z)m50s@?dUm&fePEn&ePtXJ_9v8jbG-Ocy`}QttJDEX4>Xdx^u9>-G9){Dl4e{Z3vm zyz#!d4*pu`EQ1SdO9RiqNa|>YYYV_|50xvG$_hWJ)oKNKFX9p%LT4En4WX_5iPljJ z*%k)G8c$F%s+`faM2FB>Muu_=fc0CJkn01H;#wID)!LA=QYKYff-0(&kQ}1e^2*Yz z6l5t#6S}8D=G#3@=A#9mNv*Zv_gq>X=kgW(eGHedXVOM0xsl1aZhlt{~ zp{Rzf++mR+M^kLnh8)p6-6_gLY0oJ# z_+9E>Ju4zRM47Yr3=jU+4O$MCbLK%j`|OBN`Bu$l%D(qR!E zlI=jD(sBrHLJtcB3W>T5!B8Qm+xkE5kc%{4(uN#X8lbmT`SJ1bPkxf?y1CC^i4LJN zAcK3qBbBGDlwon8zCpX)zTjV0DwW)~uO&K!PI*JSa#~S&2rJmoZM9m*{G^$gnF-c% z+wsNw<~sOmp|eY#?$F1;`sD}Ez28jU6T)j4y#E1fmzS46R;$%d9v&XLH#axl-QAt< zd0sTCFk^j}r>Cdg$;rtQ>-&%S`S~yZW{pQ5lYf}J7UB!gfpC<8V6}^+NCXF(5KxtR zy@SB*yFD;9FM0)$IPzzP`Txa&d9-Q|7oAqkv$J`0M=q{I{c{qhGhTw|}|6zrRz!$ll=+V?grGVi_t4 zzeFa4xI)U{cMf^F5fJ8Q0Isqx4E2QJ9RLEu48q8H)dO;XBC4271A=c=PK@#uFm?)1 zsDVlVItq_q!*=iJNFy9Ylv<)AiY!GEgFFNV+vbc-2N0?Y0A2$?UkWef1nZ1Q!U1F4#lEz+5Ln1zRrjFM=TMGK`Dnn&cps0|(223 Y0I&?vnCT{+761SM07*qoM6N<$f~r*2p#T5? literal 0 HcmV?d00001 diff --git a/res/drawable/ic_dialog_alert_large.png b/res/drawable/ic_dialog_alert_large.png new file mode 100644 index 0000000000000000000000000000000000000000..2d4a164a78de6e70dfafc70c7e5820601ac6db8d GIT binary patch literal 4089 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 literal 0 HcmV?d00001 diff --git a/res/drawable/ic_dialog_voice_input.png b/res/drawable/ic_dialog_voice_input.png new file mode 100644 index 0000000000000000000000000000000000000000..d2891413227855950e6113ec64319a4b8e49c468 GIT binary patch literal 1040 zcmV+r1n>KaP)LW$6+4hB_${a~hhQisvvPBDBQ`cRG63g{G8hwSYirZW%F2WS@i3Od z{6ygF?98ueT2jUB>+9>Ohlhu*?(S~7R;;Y7XvM|F@%Hw1m5rK#1Zrw(tUck)wgOyf z%`sR2Je&om@SAPyQxMI@67K}AuC5|3c6$PVpLVp}mQb`2v@!n?C@n1==TfK^Cvjtg zm==NU?QIEiEll0<@Q_FB7lIhC#?RPEJk?eisxJI2vOgb*RfRDz?3fN5<^w>6yB} zzZVFjj=_q3)S)iN{2GDk>S`;*o}Qkjd3-J}FF%D`wy}>o{Le8;1QEhj za4^jq5U!46oSqY&b+)mOI&9+@nO$OgQmItDp`k%`5;C{9w*ly-mzI`djg5^VTqdHZ zsK`pY9v>fdTxR0%@X+k*>kA(p9r>{Y(u)mx2_IOm*4Nj|2xwT}7y!Bmu(-H5ftilw zq-k{fbbo*U1avfj$1p?b#YSw8X_`7Di9xD)Ubw2ND(zswqa?+u1+TEuWj4i@=RhlE@eL-N?(!iv^D5GlqwUr=$-PkO(2jM4OtLwDR)uAAw(A zUyJ?y{S1N?!Q~H=tjx~N@=Qk&(}Q(&bwV*td^qRF$H(IQ{G3PC7#SH+f12gW%*>4S zI0XTnJDeVI@(O3m!jl35*5h<^bo6_V(=Uj)dY%JV>3RNFfB^s~l&09uu{kUN0000< KMNUMnLSTXrr0A6Z literal 0 HcmV?d00001 diff --git a/res/drawable/ic_dialog_wave_0_0.png b/res/drawable/ic_dialog_wave_0_0.png new file mode 100644 index 0000000000000000000000000000000000000000..9c3c28f37b79a696820fd971b3c660a94e9b31ef GIT binary patch literal 8471 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 FV1l7w^|1f| literal 0 HcmV?d00001 diff --git a/res/drawable/ic_dialog_wave_1_3.png b/res/drawable/ic_dialog_wave_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..d33bd0d9b534cb7107c8a770b57891349157ec59 GIT binary patch literal 9017 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 LNkvXXu0mjfjKUS# literal 0 HcmV?d00001 diff --git a/res/drawable/ic_dialog_wave_4_3.png b/res/drawable/ic_dialog_wave_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..af5a84c31a40b52848a7ebfd210d3ef2db3bd74e GIT binary patch literal 10514 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 U6Do96)&Kwi07*qoM6N<$g0@KcX8-^I literal 0 HcmV?d00001 diff --git a/res/drawable/mic_slash.png b/res/drawable/mic_slash.png new file mode 100644 index 0000000000000000000000000000000000000000..0b0fb5803a1afb80f5c02d58545d5c94e20144ca GIT binary patch literal 3098 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 literal 0 HcmV?d00001 diff --git a/res/drawable/ok_cancel.png b/res/drawable/ok_cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..0601d3231778e967cd376e048aa0f515a75ca1d0 GIT binary patch literal 8453 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 literal 0 HcmV?d00001 diff --git a/res/drawable/speak_now_level1.png b/res/drawable/speak_now_level1.png new file mode 100644 index 0000000000000000000000000000000000000000..67cb235bf22327b93e6c95e29bb611a8a72cc95f GIT binary patch literal 3572 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 literal 0 HcmV?d00001 diff --git a/res/drawable/speak_now_level5.png b/res/drawable/speak_now_level5.png new file mode 100644 index 0000000000000000000000000000000000000000..9034908f475a4006dad1bb7841a8818a5857947b GIT binary patch literal 4252 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 yLZ-eb7JdGiSI4Gv5@7@1B=YP(*=e`lo z^XRwW=JX-x+_L+0U(vh&q^+_^xh^b9bmateT>@(;L)IUO)Qb;@YZ5HQBQd$TMoyo^YGkCV%@ zu<$b3>>5Kuo61EE&YVe{w3F4Kw)PZ(2^JS$0`gsH&V#b@di{jTE2I&}r2)_YaG2HA zb2J)Lp};Y{(U@X&^_-g7KyLu#IKkaFFCU;v<*ANiyX}?AQx-tkgU>;oxg?{meVAJ9 zWGtjwtDOXfRc@wt0XlKQ5OiKAlaI;kwB_9&efOLf6J6mPUQEOqy@cb zVr_8ZHL)H7sGEmvN7fG^Kz$ABb5I|kJ_q$VsBdC@6YFcx!>2)hB3dkNFB_Xuv82R7 zW?Q9G`PxexAiI2QHm@@HRZmkcZax4~{LO%4HqlH8yNO?&H5Cw3woU~gvr}lQq@(y% zhO9nJ30TpG%OuP}8T`FzQ<;y-JgwGQUD@0gVMeKkJy>ru#G3<#XtmC6Rcr0;d9(NxkbKCwh9+sBpha>4 znsH1ystS0BtjDZD>k5!5D;?WWzDUj@?o_>)*=v@7iJzcd`E+rdxmW>moH^wbQ@K46 z0FV%I?>a0%tt~a*dE&<9I_h#a5h<&;i`vTSm726`|APU~;aSfbI-c2UGr?d3ky`;A zF|DpQt1G>M<6Mu0e;nsJu%U9zxufZT@we1bG{XjqPDt%>fjS}|1dJKSKg%Cco5P1QZ*Xy$??+HYn47kpJ zE*~J1IH&IBYx)4oz$M_@JB-T%-ve&zLoNerdhIWO&j8;7zM!GOxN6rXa2@yya0^(~ z?{W&xX_cD~c)m+|uX5NFV~gh_90Sg3!a50@0{+lJ-Isu00{^lyeG}vjT3aUeLGn%Q zRsC)dI0BpjeirDtd{Dlx=J=8Fkh>oMiB517_%!ex;71*K1YQUJrmMT5-UaSI%Hml8 z9;!9NTV@5%cK`?Acfg;3|LS%}HOhur)Pv;ai0@J0v%pV)uXPw-2QC8_f%muV)tCg- zqzCrN{6}>GzS_a80R9eK0B!<{n#H?OCKweUv*l0(jsu_572NFvy#eYHa6>0jw*bm3 z@F#(%y8s5@KfsUm^J6u&1`$u6NenO4nS5wO`RL2QuXZtm?VPc$8fDs}%5UA~ZcD%` zz*Xg)wW#DACqVYr=cg2;F9ARALX+ZXAL_mSshYDI)wL%9kXRs%;Gc${)>ZvVg5X>M zeyxQ3iE2(YN^+VMKsHF`)dQ2TKC7Om7$Y!c^@wk&NiA71Pi)}C4Ui3zA=wcH>bQEL zry~MYR${-X=Cq_*V@N($aFPJXChnY?+^_<5L}Qt6s@Y9<307Gn@hiZa8bhrpFdJ%8 zp|kb<0?5`T1Jsauro&3+6B-qN1Nh<&*S`n6t_l5a^p-aQML*tI5(Tx>7fB2Ar0 zm3A?2MJMS2vjNwaG(o*-#WhtmrNn_r1E8INvdh6v7bdn$`+e04`|yf*8UUI1;_U+l z_KPUHnW=dp#(s~!Y5lur0ou+%hcpB*2MtD*v^%vi)ttO)UR|}X^8dg=VrAl^v=0{? zvXaoDE&v*|lG=*?eOLQN(k7Rr7c<}-RWJ2ZV5W(fjtFO&YS;O)Pg b@9FkGl_8N?n0pY+00000NkvXXu0mjfoMRX$ literal 0 HcmV?d00001 diff --git a/res/drawable/voice_ime_background.9.png b/res/drawable/voice_ime_background.9.png new file mode 100644 index 0000000000000000000000000000000000000000..67802492aa3799dd0cdae8de0ac60ad7c8c3b639 GIT binary patch literal 20661 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 B^}_%F literal 0 HcmV?d00001 diff --git a/res/drawable/working.png b/res/drawable/working.png new file mode 100644 index 0000000000000000000000000000000000000000..6246a6d1cbcf1afabfa9af3dac348ab72100cd54 GIT binary patch literal 33111 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 Hu0mjfS#WwD literal 0 HcmV?d00001 diff --git a/res/layout/recognition_status.xml b/res/layout/recognition_status.xml new file mode 100644 index 000000000..ea23824a1 --- /dev/null +++ b/res/layout/recognition_status.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/voice_punctuation_hint.xml b/res/layout/voice_punctuation_hint.xml new file mode 100644 index 000000000..629a7f2b5 --- /dev/null +++ b/res/layout/voice_punctuation_hint.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + diff --git a/res/layout/voice_swipe_hint.xml b/res/layout/voice_swipe_hint.xml new file mode 100644 index 000000000..4e8859a71 --- /dev/null +++ b/res/layout/voice_swipe_hint.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 078e3001e..75bdda152 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -47,12 +47,6 @@ "Základní" "Pokročilé" - "0" - "1" - "2" - - - "%s : Uloženo" "áàâãäåæ" "éěèêë" @@ -63,7 +57,6 @@ "ňñ" "čç" "ýÿ" - "i" "Podržením klávesy zobrazíte diakritiku (ž, á atd.)" "Stisknutím klávesy Zpět ↶ můžete klávesnici kdykoli zavřít" "Přístup k číslům a symbolům" @@ -84,6 +77,30 @@ "123" "ABC" "Alt" + "Hlasový vstup" + "Pro váš jazyk aktuálně není hlasový vstup podporován, ale funguje v angličtině." + "Hlasový vstup je experimentální funkce, která využívá síťové rozpoznávání řeči společnosti Google." + "Chcete-li vypnout hlasový vstup, přejděte do nastavení klávesnice." + "Chcete-li použít hlasový vstup, stiskněte tlačítko mikrofonu nebo přejeďte prstem přes klávesnici na obrazovce." + "Mluvte" + "Probíhá zpracování" + + + "Chyba. Zkuste to prosím znovu." + "Připojení se nezdařilo." + "Chyba, řeč je příliš dlouhá." + "Problém se zvukem" + "Chyba serveru" + "Nebyla detekována žádná řeč." + "Nebyly nalezeny žádné shody" + "Hlasové vyhledávání není nainstalováno" + "Nápověda:"" Chcete-li aktivovat hlasový vstup, přejeďte prstem přes klávesnici." + "Nápověda:"" Příště zkuste vyslovit interpunkci, například „tečka“, „čárka“ nebo „otazník“." + "Zrušit" + "OK" + "Hlasový vstup" + "Po hlasovém vstupu automaticky odeslat" + "Při vyhledávání nebo přechodu na další pole automaticky stisknout Enter." "Otevřete klávesnici"\n\n"Dotkněte se jakéhokoli textového pole." "Zavřete klávesnici"\n\n"Stiskněte klávesu Zpět." "Přidržením klávesy zobrazte možnosti"\n\n"Použijte interpunkční znaménka a diakritiku." @@ -95,4 +112,5 @@ ".eu" + "Metoda zadávání dat" diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index acefb020b..70ba54729 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -47,12 +47,6 @@ "Grundlæggende" "Avanceret" - "0" - "1" - "2" - - - "%s: Gemt" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Hold en tast nede for at se accenter (ø, ö osv.)" "Tryk på tilbagetasten ↶ for når som helst at lukke for tastaturet" "Få adgang til tal og symboler" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Stemmeinput" + "Stemmeinput understøttes i øjeblikket ikke for dit sprog, men fungerer på engelsk." + "Stemme-input er en funktion på forsøgsbasis, som bruger Googles netværksstemmegenkendelse." + "Slå stemmeinput fra i indstillingerne for tastaturet." + "For at bruge stemme-input skal du trykke på knappen mikrofon eller lade glide fingeren hen over skærmtastaturet." + "Tal nu" + "Arbejder" + + + "Fejl. Prøv igen." + "Kunne ikke oprette forbindelse" + "Fejl. For meget tale." + "Lydproblem" + "Serverfejl" + "Der høres ingen tale" + "Der blev ikke fundet nogen matches" + "Stemmesøgning er ikke installeret" + "Tip:"" Glid hen over tastaturet for at tale" + "Tip:"" Næste gang kan du forsøge at sige tegnsætning, f.eks. \"punktum\", \"komma\" eller \"spørgsmålstegn\"." + "Annuller" + "OK" + "Stemmeinput" + "Send automatisk efter stemme" + "Tryk automatisk på enter, når du søger eller går til det næste felt." "Åbn tastaturet"\n\n"Tryk på et hvilket som helst tekstfelt." "Luk tastaturet"\n\n"Tryk på Tilbagetasten." "Tryk på og hold en tast nede for valgmuligheder"\n\n"Få adgang til tegnsætning og accenter." @@ -95,4 +112,5 @@ ".edu" + "Inputmetode" diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index c4e7c9d58..1d821899e 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -47,12 +47,6 @@ "Standard" "Erweitert" - "0" - "1" - "2" - - - "%s : Gespeichert" "ä" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Zur Anzeige von Umlauten (ä, ö usw.) Taste gedrückt halten" "Zum Schließen der Tastatur ↶ drücken" "Auf Zahlen und Symbole zugreifen" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Spracheingabe" + "Spracheingaben werden derzeit nicht für Ihre Sprache unterstützt, funktionieren jedoch in Englisch." + "Die Spracheingabe ist eine Funktion im Versuchsstadium, die die vernetzte Spracherkennung von Google verwendet." + "Wenn Sie die Spracheingabe deaktivieren möchten, rufen Sie die Tastatureinstellungen auf." + "Um die Spracheingabe zu verwenden, drücken Sie den Mikrofonknopf oder ziehen Sie Ihren Finger über die Bildschirmtastatur." + "Jetzt sprechen" + "Vorgang läuft" + + + "Fehler. Versuchen Sie es erneut.." + "Keine Verbindung" + "Fehler – Text zu lang" + "Audio-Problem" + "Serverfehler" + "Keine Sprache zu hören" + "Keine Übereinstimmungen gefunden" + "Sprach-Suche nicht installiert" + "Hinweis:"" Ziehen Sie zum Sprechen den Finger über die Tastatur." + "Hinweis:"" Versuchen Sie beim nächsten Mal, Satzzeichen wie \"Punkt\", \"Komma\" oder \"Fragezeichen\" per Sprachbefehl einzugeben." + "Abbrechen" + "OK" + "Spracheingabe" + "Nach Sprachaufnahme automatisch senden" + "Drücken Sie auf die Eingabetaste, wenn Sie einen Suchvorgang durchführen oder zum nächsten Feld wechseln." "Tastatur öffnen"\n\n"Berühren Sie ein beliebiges Textfeld." "Tastatur schließen"\n\n"Drücken Sie die Taste \"Zurück\"." "Eine Taste für Optionen berühren und gedrückt halten"\n\n"Greifen Sie auf Satzzeichen und Akzente zu." @@ -95,4 +112,5 @@ ".edu" + "Eingabemethode" diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 460929032..acbe2945b 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -47,12 +47,6 @@ "Βασική" "Σύνθετη" - "0" - "1" - "2" - - - "%s : Αποθηκεύτηκε" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Κρατήστε πατημένο ένα πλήκτρο για να δείτε τους τονισμένους χαρακτήρες (ø, ö, κ.τ.λ.)" "Πατήστε το πλήκτρο Πίσω ↶ για να κλείσετε το πληκτρολόγιο ανά πάσα στιγμή" "Πρόσβαση σε αριθμούς και σύμβολα" @@ -84,6 +77,30 @@ "123" "ΑΒΓ" "ALT" + "Φωνητική είσοδος" + "Η φωνητική είσοδος δεν υποστηρίζεται αυτή τη στιγμή για τη γλώσσα σας, ωστόσο λειτουργεί στα Αγγλικά." + "Οι φωνητικές εντολές είναι μια πειραματική λειτουργία, η οποία χρησιμοποιεί τη δικτυακή αναγνώριση ομιλίας της Google." + "Για να απενεργοποιήσετε τη φωνητική είσοδο, μεταβείτε στις ρυθμίσεις πληκτρολογίου." + "Για να χρησιμοποιήσετε τις φωνητικές εντολές, πιέστε το κουμπί μικροφώνου ή σύρετε το δάχτυλό σας κατά μήκος του πληκτρολογίου της οθόνης." + "Μιλήστε τώρα" + "Σε λειτουργία" + + + "Σφάλμα. Δοκιμάστε ξανά." + "Δεν ήταν δυνατή η σύνδεση" + "Σφάλμα, πολλές λέξεις." + "Πρόβλημα ήχου" + "Σφάλμα διακομιστή" + "Δεν ακούγεται ομιλία" + "Δεν βρέθηκε καμία αντιστοίχιση" + "Η Αναζήτηση με φωνή δεν εγκαταστάθηκε" + "Υπόδειξη:"" Σύρετε κατά μήκος του πληκτρολογίου για να μιλήσετε" + "Υπόδειξη:"" Την επόμενη φορά, προσπαθήστε να προφέρετε σημεία στίξης, όπως \"τελεία\", \"κόμμα\" ή \"ερωτηματικό\"." + "Ακύρωση" + "ΟΚ" + "Φωνητική είσοδος" + "Αυτόματη υποβολή μετά από ήχο" + "Πατήστε enter αυτόματα κατά την αναζήτηση ή τη μετάβαση στο επόμενο πεδίο." "Ανοίξτε το πληκτρολόγιο"\n\n"Αγγίξτε οποιοδήποτε πεδίο κειμένου." "Κλείστε το πληκτρολόγιο"\n\n"Πατήστε το πλήκτρο Πίσω." "Αγγίξτε και κρατήστε ένα πλήκτρο για ορισμό επιλογών"\n\n"Πρόσβαση στα σημεία στίξης και τονισμού." @@ -95,4 +112,5 @@ ".edu" + "Μέθοδος εισόδου" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index cb2f38399..8a8ded8f9 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -47,12 +47,6 @@ "Básico" "Avanzado" - "0" - "1" - "2" - - - "%s: guardada" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Mantén una tecla presionada para ver los acentos (ø, ö, etc.)" "Pulsa la tecla hacia atrás ↶ para cerrar el teclado en cualquier momento" "Acceder a números y símbolos" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Entrada por voz" + "La entrada por voz no está admitida en tu idioma, pero sí funciona en inglés." + "La entrada por voz es una característica experimental que utiliza la red de reconocimiento de voz de Google." + "Para desactivar la entrada por voz, ve a configuración del teclado." + "Para realizar entrada por voz, presiona el botón del micrófono o desliza tus dedos por el teclado en pantalla." + "Habla ahora" + "Procesando" + + + "Error. Vuelve a intentarlo." + "No se pudo establecer la conexión." + "Error, demasiado discurso." + "Problema de audio" + "Error del servidor" + "No se oyó la voz" + "No se encontraron coincidencias" + "Búsqueda por voz no instalada" + "Sugerencia:"" Deslizar en el teclado para hablar" + "Sugerencia:"" La próxima vez intenta decir la puntuación como \"punto\", \"coma\" o \"signo de pregunta\"." + "Cancelar" + "Aceptar" + "Entrada por voz" + "Enviar automáticamente después del audio" + "Presionar automáticamente Ingresar al buscar o ir al campo siguiente." "Abrir el teclado"\n\n"Tocar cualquier campo de texto." "Cerrar el teclado"\n\n"Presionar la tecla Atrás." "Tocar & y mantener presionada una tecla para las opciones"\n\n"Acceder a puntuación y acentos." @@ -95,4 +112,5 @@ ".edu" + "Método de entrada" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 0b96bea76..4977cbac5 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -47,12 +47,6 @@ "Básico" "Avanzado" - "0" - "1" - "2" - - - "%s : Guardada" "á" "é" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Mantén pulsada una tecla para ver los caracteres acentuados (ø, ö, etc.)." "Pulsa la tecla \"Atrás\" ↶ para cerrar el teclado en cualquier momento." "Acceso a números y símbolos" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Introducción de voz" + "Actualmente la introducción de voz no está disponible en tu idioma, pero se puede utilizar en inglés." + "La introducción de voz es una función en fase experimental que utiliza la tecnología de reconocimiento de voz en red de Google." + "Para desactivar la función de introducción de voz, accede a la configuración del teclado." + "Para utilizar la función de introducción de voz, pulsa el botón de micrófono o desliza el dedo por el teclado en pantalla." + "Hablar ahora" + "Trabajando" + + + "Se ha producido un error. Inténtalo de nuevo." + "No se ha podido establecer conexión." + "Se ha producido un error debido a un exceso de introducción de datos de voz." + "Problema de audio" + "Error del servidor" + "Ninguna conversación escuchada" + "No se ha encontrado ninguna coincidencia." + "La búsqueda por voz no está instalada." + "Sugerencia:"" muévete por el teclado para hablar." + "Sugerencia:"" la próxima vez, prueba a indicar signos de puntuación como, por ejemplo, \"punto\", \"coma\" o \"signo de interrogación\"." + "Cancelar" + "Aceptar" + "Introducción de voz" + "Enviar automáticamente después de la introducción de voz" + "Pulsar Intro automáticamente al buscar o al pasar al siguiente campo" "Abrir el teclado"\n\n"Pulsa cualquier campo de texto." "Cerrar el teclado"\n\n"Pulsa la tecla \"Atrás\"." "Mantén pulsada una tecla para acceder a las opciones."\n\n"Accede a los signos de puntuación y a los acentos." @@ -95,4 +112,5 @@ ".edu" + "Método de introducción de texto" diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 0bb70218c..f4834da13 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -47,12 +47,6 @@ "Simple" "Avancé" - "0" - "1" - "2" - - - "%s : enregistré" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Maintenir une touche enfoncée pour afficher les accents (à, é, etc.)" "Appuyez sur la touche Retour ↶ pour fermer le clavier à tout moment." "Accéder aux chiffres et symboles" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Saisie vocale" + "La saisie vocale n\'est pas encore prise en charge pour votre langue, mais elle fonctionne en anglais." + "La saisie vocale est une fonctionnalité expérimentale qui fait appel à la reconnaissance vocale en réseau de Google." + "Pour désactiver la saisie vocale, accédez aux paramètres du clavier." + "Pour utiliser la saisie vocale, appuyez sur la touche du microphone ou faites glisser votre doigt sur le clavier à l\'écran." + "Parlez maintenant" + "Traitement en cours" + + + "Erreur. Veuillez réessayer." + "Connexion impossible" + "Erreur, discours trop long." + "Problème audio" + "Erreur serveur" + "Aucune requête vocale détectée" + "Aucune correspondance n\'a été trouvée." + "Recherche vocale non installée" + "Astuce :"" Faites glisser votre doigt sur le clavier pour parler." + "Astuce :"" La prochaine fois, essayez de prononcer la ponctuation, en énonçant des termes tels que \"point\", \"virgule\" ou \"point d\'interrogation\"." + "Annuler" + "OK" + "Saisie vocale" + "Envoi automatique après la saisie vocale" + "Appuyez automatiquement sur Entrée pour effectuer une recherche ou accéder au champ suivant." "Ouvrir le clavier"\n\n"Appuyez sur un champ de texte." "Fermer le clavier"\n\n"Appuyez sur la touche Retour." "Appuyer sur une touche de manière prolongée pour accéder aux options"\n\n"Accédez aux signes de ponctuation et aux accents." @@ -95,4 +112,5 @@ ".edu" + "Mode de saisie" diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 5e3b0e3e1..94478ce88 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -47,12 +47,6 @@ "Base" "Avanzate" - "0" - "1" - "2" - - - "%s : parola salvata" "àá" "èé" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Tieni premuto un tasto per vedere le lettere con segni diacritici (ø, ö etc.)" "Premi il tasto Indietro ↶ per chiudere la tastiera" "Accedi a numeri e simboli" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Comandi vocali" + "I comandi vocali non sono attualmente supportati per la tua lingua ma funzionano in inglese." + "I comandi vocali sono una funzione sperimentale che utilizza il riconoscimento vocale in rete di Google." + "Per disattivare i comandi vocali, vai alle impostazioni della tastiera." + "Per utilizzare i comandi vocali, premi il pulsante del microfono o fai scorrere il dito sulla tastiera sullo schermo." + "Parla ora" + "Elaborazione in corso" + + + "Errore. Riprova più tardi." + "Impossibile connettersi." + "Errore: conversazione troppo lunga." + "Problema audio" + "Errore del server" + "Nessuna frase vocale rilevata" + "Nessuna corrispondenza trovata" + "Ricerca vocale non installata" + "Suggerimento."" Fai scorrere il dito sulla tastiera per parlare" + "Suggerimento."" La prossima volta, prova a pronunciare termini relativi alla punteggiatura come \"punto\", \"virgola\" o \"punto di domanda\"." + "Annulla" + "OK" + "Comandi vocali" + "Invia automaticamente dopo comando vocale" + "Premi automaticamente \"Invio\" durante una ricerca o un passaggio al campo successivo." "Apertura tastiera"\n\n"Tocca qualsiasi campo di testo." "Chiusura tastiera"\n\n"Premi il tasto Indietro." "Tocca e tieni premuto un tasto per le opzioni"\n\n"Accesso a punteggiatura e accenti." @@ -95,4 +112,5 @@ ".edu" + "Metodo inserimento" diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 133d64f2f..3f29eb96b 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -47,12 +47,6 @@ "基本" "高度" - "0" - "1" - "2" - - - "%s:保存しました" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "キー長押しでアクセント文字を表示(ø、öなど)" "戻るキーでキーボードを閉じます" "数字と記号" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "音声入力" + "音声入力は現在英語には対応していますが、日本語には対応していません。" + "音声入力はGoogleのネットワーク音声認識技術を利用した試験段階の機能です。" + "音声入力をOFFにするには、キーボードの設定を開きます。" + "音声入力するには、マイクボタンを押すか画面キーボードをスワイプしてください。" + "お話しください" + "処理中" + + + "エラーです。もう一度お試しください。" + "接続できませんでした" + "音声が長すぎてエラーになりました。" + "オーディオエラー" + "サーバーエラー" + "音声が聞き取れません" + "該当なし" + "Voice Searchはインストールされていません" + "ヒント:"" 音声入力するにはキーボードをスワイプします" + "ヒント:"" 次回は句読点として「period」、「comma」、「question mark」などの音声入力を試してみてください。" + "キャンセル" + "OK" + "音声入力" + "入力後に自動送信する" + "検索または次のフィールドに進む際、Enterキーが自動的に押されます。" "キーボードを開く"\n\n"テキストフィールドをタップします。" "キーボードを閉じる"\n\n"[戻る]キーを押します。" "キーを長押しして選択する"\n\n"句読点キーとアクセント文字を表示します。" @@ -95,4 +112,5 @@ ".edu" + "入力方法" diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index fe0da1767..1d9e0bd30 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -47,12 +47,6 @@ "기본" "고급" - "0" - "1" - "2" - - - "%s : 저장됨" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "키를 길게 누르면 악센트(ø, ö 등)가 표시됩니다." "키보드를 닫으려면 언제든지 뒤로 키(↶)를 누르세요." "숫자 및 기호 액세스" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "음성 입력" + "음성 입력은 현재 자국어로 지원되지 않으며 영어로 작동됩니다." + "음성 입력은 Google의 네트워크화된 음성 인식을 사용하는 실험적 기능입니다." + "음성 입력을 사용하지 않으려면 키보드 설정으로 이동하세요." + "음성 입력을 사용하려면 마이크 버튼을 누르거나 터치 키보드 위로 손가락을 미끄러지듯 움직이세요." + "지금 시작하세요." + "인식 중" + + + "오류가 발생했습니다. 다시 시도해 보세요." + "연결할 수 없습니다." + "음성을 너무 많이 입력했습니다." + "오디오 문제" + "서버 오류" + "음성이 인식되지 않았습니다." + "일치하는 항목 없음" + "음성 검색이 설치되지 않았습니다." + "도움말:"" 키보드를 스와이프하고 말하세요." + "도움말:"" 다음 번에는 \'마침표\', \'쉼표\', \'물음표\'와 같은 구두점을 말해 보세요." + "취소" + "확인" + "음성 입력" + "음성을 입력한 다음 자동 제출" + "검색하거나 다음 입력란으로 이동할 때 자동으로 Enter 키를 누릅니다." "키보드 열기"\n\n"아무 텍스트 입력란이나 터치하세요." "키보드 닫기"\n\n"\'뒤로\' 키를 누르세요." "키를 길게 터치하여 옵션 보기"\n\n"문장 부호 및 악센트 기호에 액세스하세요." @@ -95,4 +112,5 @@ ".edu" + "입력 방법" diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 28e84a504..971bc1445 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -47,12 +47,6 @@ "Grunnleggende" "Avansert" - "0" - "1" - "2" - - - "%s: Lagret" "åæáàâãä" "éèêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Hold en tast nede for å se aksenterte tegn (ø, ö, osv.)" "Trykk tilbakeknappen, ↶, for å lukke tastaturet" "Få tilgang til tall og symboler" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Stemmedata" + "Stemmedata håndteres foreløpig ikke på ditt språk, men fungerer på engelsk." + "Talekommandoer er en eksperimentell funksjon som bruker Googles nettverksbaserte talegjenkjenning." + "Gå til innstillinger for tastatur for å slå av stemmedata." + "Du bruker talekommandoer ved å trykke på mikrofonknappen eller skyve fingeren over tastaturet på skjermen." + "Snakk nå" + "Arbeider" + + + "Feil. Prøv på nytt." + "Kunne ikke koble til" + "Feil – for mye tale" + "Lydproblem" + "Tjenerfeil" + "Ingen tale høres" + "Ingen treff" + "Talesøk ikke installert" + "Hint:"" Sveip over tastaturet for å snakke" + "Hint:"" Neste gang kan du prøve å tale inn tegnsettingen ved for eksempel å si «punktum», «komma» eller «spørsmålstegn»." + "Avbryt" + "OK" + "Stemmedata" + "Send inn automatisk etter tale" + "Trykk Enter automatisk ved søk eller flytting til neste felt." "Åpne tastaturet"\n\n"Trykk på et tekstfelt." "Lukke tastaturet"\n\n"Trykk på tilbaketasten." "Trykk og hold nede en tast for flere valg"\n\n"Få tilgang til skilletegn og aksenter." @@ -95,4 +112,5 @@ ".info" + "Inndatametode" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 085d50ac9..beeb0af11 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -47,12 +47,6 @@ "Basis" "Geavanceerd" - "0" - "1" - "2" - - - "%s : Opgeslagen" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Houd een toets ingedrukt om diakritische tekens weer te geven (ø, ö, enzovoort)" "Druk op elk gewenst moment op de toets Terug ↶ om het toetsenbord te sluiten" "Toegang tot cijfers en symbolen" @@ -84,6 +77,30 @@ "123" "ABC" "Alt" + "Spraakinvoer" + "Spraakinvoer wordt momenteel niet ondersteund in uw taal, maar is wel beschikbaar in het Engels." + "Spraakinvoer is een experimentele functie met de spraakherkenning van het Google-netwerk." + "Als u spraakinvoer wilt uitschakelen, gaat u naar de toetsenbordinstellingen." + "Als u spraakinvoer gebruikt, drukt u op de microfoonknop of schuift u uw vinger over het schermtoetsenbord." + "Nu spreken" + "Wordt uitgevoerd" + + + "Fout. Probeer het opnieuw." + "Kan geen verbinding maken" + "Fout, te lange spraakinvoer." + "Audioprobleem" + "Serverfout" + "Geen spraak te horen" + "Geen resultaten gevonden" + "Voice Search is niet geïnstalleerd" + "Hint:"" schuif over het toetsenbord om te spreken" + "Hint:"" spreek de volgende keer interpunctie uit, zoals \'period\' (punt), \'comma\' (komma) of \'question mark\' (vraagteken)." + "Annuleren" + "OK" + "Spraakinvoer" + "Automatisch verzenden na spraak" + "Drukt automatisch op Enter tijdens het zoeken of wanneer u naar het volgende veld wilt gaan." "Het toetsenbord openen"\n\n"Raak een tekstveld aan." "Het toetsenbord sluiten"\n\n"Druk op de terugtoets." "Een toets blijven aanraken voor opties"\n\n"Toegang tot interpunctie en diakritische tekens." @@ -95,4 +112,5 @@ ".edu" + "Invoermethode" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index e3bac3d4c..2da020783 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -47,12 +47,6 @@ "Podstawowy" "Zaawansowany" - "0" - "1" - "2" - - - "%s : Zapisano" "ą" "ę" @@ -63,7 +57,6 @@ "ń" "ć" "ýÿ" - "i" "Przytrzymaj klawisz, aby wyświetlić znaki akcentowane (ą, ó itp.)" "Naciśnij klawisz cofania ↶, aby zamknąć klawiaturę w dowolnym momencie" "Przejdź do cyfr i symboli" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Wprowadzanie głosowe" + "Wprowadzanie głosowe obecnie nie jest obsługiwane w Twoim języku, ale działa w języku angielskim." + "Wprowadzanie głosowe to funkcja eksperymentalna wykorzystująca funkcję firmy Google umożliwiającą rozpoznawanie mowy przy użyciu sieci." + "Aby wyłączyć wprowadzanie głosowe, przejdź do ustawień klawiatury." + "Aby skorzystać z wprowadzania głosowego, naciśnij przycisk mikrofonu lub przesuń palcem po klawiaturze ekranowej." + "Mów teraz" + "Działa" + + + "Błąd. Spróbuj ponownie." + "Nie można nawiązać połączenia" + "Błąd, zbyt długa wypowiedź." + "Problem z dźwiękiem" + "Błąd serwera" + "Nie wykryto mowy" + "Nie znaleziono żadnych wyników" + "Wyszukiwanie głosowe nie jest zainstalowane" + "Wskazówka:"" przesuń palcem po klawiaturze, aby mówić." + "Wskazówka:"" następnym razem spróbuj wypowiadać nazwy znaków interpunkcyjnych: „kropka”, „przecinek” lub „pytajnik”." + "Anuluj" + "OK" + "Wprowadzanie głosowe" + "Automatyczne przesyłanie uruchamiane głosem" + "Podczas wyszukiwania lub przechodzenia do następnego pola automatycznie naciśnij klawisz Enter." "Otwórz klawiaturę"\n\n"Dotknij dowolnego pola tekstowego." "Zamknij klawiaturę"\n\n"Naciśnij klawisz Wróć." "Dotknij klawisza i przytrzymaj go, aby wyświetlić opcje"\n\n"Dostęp do znaków przestankowych i akcentowanych." @@ -95,4 +112,5 @@ ".edu" + "Metoda wprowadzania" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 9ad88f3f6..ec397b66f 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -47,12 +47,6 @@ "Básico" "Avançados" - "0" - "1" - "2" - - - "%s: Guardada" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Mantenha uma tecla premida para ver os acentos (ø, ö, etc.)" "Prima a tecla de retrocesso ↶ para fechar o teclado a qualquer momento" "Aceder a números e símbolos" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Entrada de voz" + "Actualmente, a entrada de voz não é suportada para o seu idioma, mas funciona em inglês." + "A entrada de voz é uma funcionalidade experimental que utiliza o reconhecimento de voz em rede da Google." + "Para desactivar a entrada de voz, aceda às definições do teclado." + "Para utilizar a entrada de voz, prima o botão do microfone ou deslize o dedo no teclado do ecrã." + "Falar agora" + "A executar" + + + "Erro. Tente novamente." + "Não foi possível ligar" + "Erro, discurso demasiado longo." + "Problema de áudio" + "Erro no servidor" + "Nenhuma voz ouvida" + "Não foram encontradas correspondências" + "Pesquisa de voz não instalada" + "Sugestão:"" Deslize no teclado para falar" + "Sugestão:"" Da próxima vez, experimente dizer a pontuação como \"ponto final\", \"vírgula\" ou \"ponto de interrogação\"." + "Cancelar" + "OK" + "Entrada de voz" + "Enviar automaticamente depois da voz" + "Premir automaticamente ENTER ao pesquisar ou avançar para o campo seguinte." "Abra o teclado"\n\n"Toque em qualquer campo de texto." "Feche o teclado"\n\n"Prima a tecla \"Anterior\"." "Mantenha premida uma tecla para as opções"\n\n"Aceder a pontuação e acentos." @@ -93,6 +110,7 @@ ".org" ".gov" ".edu" + "Método de entrada" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 895a1be01..64042b30b 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -47,12 +47,6 @@ "Básico" "Avançado" - "0" - "1" - "2" - - - "%s : Salvo" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Segure uma tecla pressionada para ver os acentos (ø, ö, etc.)" "Apertar a tecla voltar ↶ para fechar o teclado, em qualquer ponto" "Acessar números e símbolos" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Entrada de voz" + "A entrada de voz não é suportada no momento para o seu idioma, mas funciona em inglês." + "A entrada de voz é um recurso experimental que usa o reconhecimento de fala de rede do Google." + "Para desativar a entrada de voz, vá para as configurações do teclado." + "Para usar a entrada de voz, pressione o botão com o microfone ou deslize o dedo sobre o teclado na tela." + "Fale agora" + "Trabalhando" + + + "Erro. Tente novamente." + "Não foi possível conectar" + "Erro, fala muito longa." + "Problema com o áudio" + "Erro do servidor" + "Nenhuma fala ouvida" + "Não há resultados compatíveis" + "A pesquisa por voz não está instalada" + "Dica:"" Deslize sobre o teclado para falar" + "Dica:"" Da próxima vez, tente falar o nome da pontuação como \"ponto\", \"vírgula\" ou \"ponto de interrogação\"." + "Cancelar" + "OK" + "Entrada de voz" + "Enviar automaticamente depois de falar" + "Pressione Enter automaticamente ao pesquisar ou ir para o próximo campo." "Abra o teclado"\n\n"Toque em qualquer campo de texto." "Feche o teclado"\n\n"Pressione a tecla Voltar." "Toque e mantenha pressionada uma tecla para ver as opções"\n\n"Acesse a pontuação e os acentos." @@ -93,6 +110,7 @@ ".org" ".gov" ".edu" + "Método de entrada" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 7443114a3..6e81f7d03 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -47,12 +47,6 @@ "Основной" "Расширенный" - "0" - "1" - "2" - - - "%s : сохранено" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Удерживайте клавишу, чтобы увидеть варианты с диакритическими знаками (ø, ö и т.д.)" "Нажмите клавишу \"Назад\" ↶, чтобы закрыть клавиатуру в любой момент" "Открыть цифры и символы" @@ -84,6 +77,30 @@ "123" "АБВ" "ALT" + "Голосовой ввод" + "В настоящее время функция голосового ввода не поддерживает ваш язык, но вы можете пользоваться ей на английском." + "Голосовой ввод – экспериментальная функция на основе технологии сетевого распознавания речи от Google." + "Функция голосового ввода отключается в настройках клавиатуры." + "Чтобы использовать голосовой ввод, нажмите кнопку микрофона или проведите пальцем по экранной клавиатуре." + "Говорите" + "Выполняется обработка" + + + "Ошибка. Повторите попытку." + "Ошибка подключения" + "Слишком длинная фраза" + "Неполадка со звуком" + "Ошибка сервера" + "Речи не слышно" + "Соответствий не найдено" + "Голосовой поиск не установлен" + "Совет"". Проведите пальцем по клавиатуре для голосового ввода." + "Совет"". В следующий раз проговаривайте знаки препинания, например \"точка\", \"запятая\", \"вопросительный знак\"." + "Отмена" + "ОК" + "Голосовой ввод" + "Автоматически отправлять по окончании голосового ввода" + "Автоматически нажимать \"Ввод\" при поиске или переходе к следующему полю." "Откройте клавиатуру"\n\n"Нажмите на любое текстовое поле." "Закрытие клавиатуры"\n\n"Нажмите клавишу \"Назад\"." "Нажмите и удерживайте клавишу для вызова параметров"\n\n"Доступ к пунктуационным и диакритическим знакам." @@ -95,4 +112,5 @@ ".edu" + "Способ ввода" diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index b56a71806..8027eb3f7 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -47,12 +47,6 @@ "Grundinställningar" "Avancerade" - "0" - "1" - "2" - - - "%s: sparat" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Håll nere en tangent om du vill visa accenter (ø, ö, etc.)" "Tryck på Tillbaka ↶ om du vill stänga tangentbordet" "För siffror och symboler" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Röstindata" + "Röstindata stöds inte på ditt språk än, men tjänsten fungerar på engelska." + "Röstinmatning är en funktion på experimentstadiet som använder Googles nätverks taligenkänning." + "Om du vill stänga av röstindata öppnar du inställningarna för tangentbordet." + "Om du vill använda röstinmatning trycker du på mikrofonknappen eller drar fingret över tangentbordet på skärmen." + "Tala nu" + "Fungerar" + + + "Fel. Försök igen." + "Det gick inte att ansluta" + "Fel, för mycket tal." + "Ljudproblem" + "Serverfel" + "Hörde inget tal" + "Inga träffar hittades" + "Voice Search är inte installerat" + "Tips!"" Dra över tangentbordet om du vill tala" + "Tips!"" Nästa gång testar du att säga skiljetecknen, som \"punkt\", \"komma\" eller \"frågetecken\"." + "Avbryt" + "OK" + "Röstindata" + "Skicka automatiskt efter röst" + "Tryck automatiskt på retur vid sökning eller när du fortsätter till nästa fält." "Öppna tangentbordet"\n\n"Tryck på ett textfält." "Stäng tangentbordet"\n\n"Tryck på Tillbaka." "Tryck länge på en tangent om du vill se alternativ"\n\n"Använda skiljetecken och accenter." @@ -95,4 +112,5 @@ ".edu" + "Indatametod" diff --git a/res/values-tr/donottranslate.xml b/res/values-tr/donottranslate.xml index f206e4c43..2154c16bb 100644 --- a/res/values-tr/donottranslate.xml +++ b/res/values-tr/donottranslate.xml @@ -20,4 +20,4 @@ ğ - + \ No newline at end of file diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 6f17f69c4..069abeb14 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -47,12 +47,6 @@ "Temel" "Gelişmiş" - "0" - "1" - "2" - - - "%s : Kaydedildi" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "Vurguları görmek için bir tuşu basılı tutun (ø, ö, v.b.)" "Klavyeyi herhangi bir anda kapatmak için geri tuşuna ↶ basın" "Sayılara ve simgelere erişin" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "Ses girişi" + "Ses girişi, şu anda sizin diliniz için desteklenmiyor ama İngilizce dilinde kullanılabilir." + "Ses girişi, Google\'ın ağ bağlantılı ses tanıma işlevini kullanan deneysel bir özelliktir." + "Ses girişini kapatmak için klavye ayarlarına gidin." + "Ses girişini kullanmak için mikrofon düğmesine basın veya parmağınızı dokunmatik klavye üzerinde kaydırın." + "Şimdi konuşun" + "Çalışıyor" + + + "Hata. Lütfen tekrar deneyin." + "Bağlanamadı" + "Hata, çok uzun konuşma." + "Ses sorunu" + "Sunucu hatası" + "Konuşma duyulmadı" + "Eşleşme bulunamadı" + "Sesle arama yüklenmedi" + "İpucu:"" Konuşmak için parmağınızı klavye üzerinde kaydırın" + "İpucu:"" Sonraki sefer, \"nokta\", \"virgül\" veya \"soru işareti\" gibi noktalama işaretlerini telaffuz etmeyi deneyin." + "İptal" + "Tamam" + "Ses girişi" + "Sesten sonra otomatik gönder" + "Arama yaparken veya bir sonraki alana giderken enter tuşuna otomatik olarak basın." "Klavyeyi açın"\n\n"Herhangi bir metin alanına dokunun." "Klavyeyi kapatın"\n\n"Geri tuşuna basın." "Seçenekler için bir tuşa dokunun ve basılı tutun"\n\n"Noktalama ve vurgulama işaretlerine erişin." @@ -95,4 +112,5 @@ ".edu" + "Giriş yöntemi" diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index f1c041805..034f32739 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -47,12 +47,6 @@ "基本模式" "高级模式" - "0" - "1" - "2" - - - "%s:已保存" "àáâãäåæ" "èéêë" @@ -84,6 +78,30 @@ "123" "ABC" "ALT" + "语音输入" + "语音输入功能当前还不支持您的语言,您只能输入英语语音。" + "语音输入是一项试验性的功能,它采用了 Google 的网络语音识别功能。" + "要关闭语音输入功能,请转至键盘设置。" + "要使用语音输入,请按麦克风按钮或者在屏幕键盘上滑动手指。" + "请开始说话" + "正在处理" + + + "出错,请重试。" + "无法连接" + "出错,语音过长。" + "音频问题" + "服务器出错" + "未听到语音" + "未找到匹配项" + "未安装语音搜索" + "提示:""在键盘上滑动手指可激活语音功能" + "提示:""稍后,请尝试使用语音输入标点符号,如“句号”、“逗号”或“问号”。" + "取消" + "确定" + "语音输入" + "语音结束后自动提交" + "搜索或转到下一字段时自动按 Enter。" "打开键盘"\n\n"轻触任意文本字段。" "关闭键盘"\n\n"按“返回”键。" "按住某个键可开启其他字符选项"\n\n"访问标点和重音符号。" @@ -95,4 +113,5 @@ ".edu" + "输入法" diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 550a735df..9603c6b80 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -47,12 +47,6 @@ "基本模式" "進階模式" - "0" - "1" - "2" - - - "%s:已儲存" "àáâãäåæ" "èéêë" @@ -63,7 +57,6 @@ "ñ" "ç" "ýÿ" - "i" "按住按鍵可查看重音符號 (ø、ö 等)" "隨時可以透過按後退鍵 ↶ 關閉鍵盤" "使用數字和符號" @@ -84,6 +77,30 @@ "123" "ABC" "ALT" + "語音輸入" + "語音輸入目前不支援您的語言,但是可以辨識英文。" + "語音輸入這項實驗功能運用了 Google 的網路語音辨識系統。" + "請前往鍵盤設定來關閉語音輸入。" + "如要使用語音輸入,按下 [麥克風] 按鈕,或將手指滑過螢幕小鍵盤即可。" + "請說話" + "辨識中" + + + "發生錯誤,請再試一次。" + "無法連線" + "錯誤:語音內容過長。" + "音訊問題" + "伺服器錯誤" + "沒有聽到任何聲音" + "找不到相符的項目" + "未安裝語音搜尋" + "提示:""滑過鍵盤即可說話" + "提示:""下次可嘗試說出標點符號,例如「句號」、「逗號」或「問號」。" + "取消" + "確定" + "語音輸入" + "說話後自動提交" + "搜尋或前往下一個欄位時自動按下輸入。" "開啟鍵盤"\n\n"輕觸任何文字欄位。" "關閉鍵盤"\n\n"按下 Back 鍵。" \n"輕觸並按住按鍵開啟選項"\n"輸入標點與輕重音。" @@ -95,4 +112,5 @@ ".edu" + "輸入方式" diff --git a/res/values/bools.xml b/res/values/bools.xml index 3a951b271..ebe2f04e5 100644 --- a/res/values/bools.xml +++ b/res/values/bools.xml @@ -23,4 +23,6 @@ false + + true diff --git a/res/values/donottranslate.xml b/res/values/donottranslate.xml index c6941949e..d9649f3b1 100644 --- a/res/values/donottranslate.xml +++ b/res/values/donottranslate.xml @@ -32,6 +32,4 @@ - - diff --git a/res/values/keycodes.xml b/res/values/keycodes.xml index e46e4bc36..8156c0e07 100644 --- a/res/values/keycodes.xml +++ b/res/values/keycodes.xml @@ -20,5 +20,5 @@ - -102 + -103 diff --git a/res/values/strings.xml b/res/values/strings.xml index 3b3965e09..90cd6d429 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -93,13 +93,13 @@ - 0 + 0 - 1 + 1 - 2 + 2 - + @string/prediction_none @string/prediction_basic @string/prediction_full @@ -125,13 +125,7 @@ ç ýÿ - - - i - + Hold a key down to see accents (ø, ö, etc.) @@ -185,6 +179,85 @@ ALT + + + + Voice input + + + Voice input is not currently supported for your language, but does work in English. + + + Voice input is an experimental feature using Google\'s networked speech recognition. + + + To turn off voice input, go to keyboard settings. + + + To use voice input, press the microphone button or slide your finger across the on-screen keyboard. + + + Speak now + + + Working + + + + + + Error. Please try again. + + + Couldn\'t connect + + + Error, too much speech. + + + Audio problem + + + Server error + + + No speech heard + + + No matches found + + + Voice search not installed + + + Hint: Swipe across keyboard to speak + + + Hint: Next time, try speaking punctuation like \"period\", \"comma\", or \"question mark\". + + + Cancel + + + OK + + + Voice input + + + Auto submit after voice + + + Automatically press enter when searching or going to the next field. + Open the keyboard\n\nTouch any text field. @@ -197,7 +270,7 @@ Keyboard settings\n\nTouch \u0026 hold the \?123\ key. - + ".com" @@ -208,6 +281,9 @@ ".gov" ".edu" + + + Input method Select input languages diff --git a/res/xml-de/kbd_qwerty.xml b/res/xml-de/kbd_qwerty.xml index 2da609ca8..3fb8f5226 100755 --- a/res/xml-de/kbd_qwerty.xml +++ b/res/xml-de/kbd_qwerty.xml @@ -165,4 +165,81 @@ android:keyWidth="20%p" android:keyEdgeFlags="right"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/xml-fr/kbd_qwerty.xml b/res/xml-fr/kbd_qwerty.xml index 7c1b24bad..fef260d1d 100644 --- a/res/xml-fr/kbd_qwerty.xml +++ b/res/xml-fr/kbd_qwerty.xml @@ -166,5 +166,81 @@ android:popupKeyboard="@xml/popup_smileys" android:keyWidth="20%p" android:keyEdgeFlags="right"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/res/xml/kbd_qwerty.xml b/res/xml/kbd_qwerty.xml index d914f46d2..552e7e544 100755 --- a/res/xml/kbd_qwerty.xml +++ b/res/xml/kbd_qwerty.xml @@ -46,7 +46,7 @@ android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="@string/alternates_for_u" /> - @@ -70,14 +70,11 @@ android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="@string/alternates_for_d"/> - - /> + - @@ -126,6 +123,24 @@ android:keyWidth="20%p" android:keyEdgeFlags="right"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/xml/method.xml b/res/xml/method.xml index e5654e96d..4a807947b 100644 --- a/res/xml/method.xml +++ b/res/xml/method.xml @@ -21,6 +21,6 @@ diff --git a/res/xml/prefs.xml b/res/xml/prefs.xml index d5075c53a..74a2bcb20 100644 --- a/res/xml/prefs.xml +++ b/res/xml/prefs.xml @@ -37,6 +37,12 @@ android:defaultValue="true" /> + SPEAKABLE_PUNCTUATION + = new HashMap(); + static { + SPEAKABLE_PUNCTUATION.put(",", "comma"); + SPEAKABLE_PUNCTUATION.put(".", "period"); + SPEAKABLE_PUNCTUATION.put("?", "question mark"); + } + + public Hints(Context context, Display display) { + mContext = context; + mDisplay = display; + + ContentResolver cr = mContext.getContentResolver(); + mSwipeHintMaxDaysToShow = GoogleSettingsUtil.getGservicesInt( + cr, + GoogleSettingsUtil.LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS, + DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW); + mPunctuationHintMaxDisplays = GoogleSettingsUtil.getGservicesInt( + cr, + GoogleSettingsUtil.LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS, + DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS); + } + + public boolean showSwipeHintIfNecessary(boolean fieldRecommended) { + if (fieldRecommended && shouldShowSwipeHint()) { + showHint(R.layout.voice_swipe_hint); + return true; + } + + return false; + } + + public boolean showPunctuationHintIfNecessary(InputConnection ic) { + if (!mVoiceResultContainedPunctuation + && ic != null + && getAndIncrementPref(PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT) + < mPunctuationHintMaxDisplays) { + CharSequence charBeforeCursor = ic.getTextBeforeCursor(1, 0); + if (SPEAKABLE_PUNCTUATION.containsKey(charBeforeCursor)) { + showHint(R.layout.voice_punctuation_hint); + return true; + } + } + + return false; + } + + public void registerVoiceResult(String text) { + // Update the current time as the last time voice input was used. + SharedPreferences.Editor editor = + PreferenceManager.getDefaultSharedPreferences(mContext).edit(); + editor.putLong(PREF_VOICE_INPUT_LAST_TIME_USED, System.currentTimeMillis()); + editor.commit(); + + mVoiceResultContainedPunctuation = false; + for (CharSequence s : SPEAKABLE_PUNCTUATION.keySet()) { + if (text.indexOf(s.toString()) >= 0) { + mVoiceResultContainedPunctuation = true; + break; + } + } + } + + private boolean shouldShowSwipeHint() { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); + + int numUniqueDaysShown = sp.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0); + + // If we've already shown the hint for enough days, we'll return false. + if (numUniqueDaysShown < mSwipeHintMaxDaysToShow) { + + long lastTimeVoiceWasUsed = sp.getLong(PREF_VOICE_INPUT_LAST_TIME_USED, 0); + + // If the user has used voice today, we'll return false. (We don't show the hint on + // any day that the user has already used voice.) + if (!isFromToday(lastTimeVoiceWasUsed)) { + return true; + } + } + + return false; + } + + /** + * Determines whether the provided time is from some time today (i.e., this day, month, + * and year). + */ + private boolean isFromToday(long timeInMillis) { + if (timeInMillis == 0) return false; + + Calendar today = Calendar.getInstance(); + today.setTimeInMillis(System.currentTimeMillis()); + + Calendar timestamp = Calendar.getInstance(); + timestamp.setTimeInMillis(timeInMillis); + + return (today.get(Calendar.YEAR) == timestamp.get(Calendar.YEAR) && + today.get(Calendar.DAY_OF_MONTH) == timestamp.get(Calendar.DAY_OF_MONTH) && + today.get(Calendar.MONTH) == timestamp.get(Calendar.MONTH)); + } + + private void showHint(int hintViewResource) { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); + + int numUniqueDaysShown = sp.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0); + long lastTimeHintWasShown = sp.getLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, 0); + + // If this is the first time the hint is being shown today, increase the saved values + // to represent that. We don't need to increase the last time the hint was shown unless + // it is a different day from the current value. + if (!isFromToday(lastTimeHintWasShown)) { + SharedPreferences.Editor editor = sp.edit(); + editor.putInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, numUniqueDaysShown + 1); + editor.putLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, System.currentTimeMillis()); + editor.commit(); + } + + if (mDisplay != null) { + mDisplay.showHint(hintViewResource); + } + } + + private int getAndIncrementPref(String pref) { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); + int value = sp.getInt(pref, 0); + SharedPreferences.Editor editor = sp.edit(); + editor.putInt(pref, value + 1); + editor.commit(); + return value; + } +} diff --git a/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/src/com/android/inputmethod/latin/KeyboardSwitcher.java index 03b008e34..aa52c0381 100644 --- a/src/com/android/inputmethod/latin/KeyboardSwitcher.java +++ b/src/com/android/inputmethod/latin/KeyboardSwitcher.java @@ -48,6 +48,13 @@ public class KeyboardSwitcher { private static final int SYMBOLS_MODE_STATE_SYMBOL = 2; LatinKeyboardView mInputView; + private static final int[] ALPHABET_MODES = { + KEYBOARDMODE_NORMAL, + KEYBOARDMODE_URL, + KEYBOARDMODE_EMAIL, + KEYBOARDMODE_IM}; + + //LatinIME mContext; Context mContext; InputMethodService mInputMethodService; @@ -56,11 +63,17 @@ public class KeyboardSwitcher { private KeyboardId mCurrentId; private Map mKeyboards; - - private int mMode; + + /** + * Maps keyboard mode to the equivalent mode with voice. + */ + private Map mModeToVoice; + + private int mMode; /** One of the MODE_XXX values */ private int mImeOptions; private int mTextMode = MODE_TEXT_QWERTY; private boolean mIsSymbols; + private boolean mHasVoice; private boolean mPreferSymbols; private int mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; @@ -73,6 +86,11 @@ public class KeyboardSwitcher { mKeyboards = new HashMap(); mSymbolsId = new KeyboardId(R.xml.kbd_symbols); mSymbolsShiftedId = new KeyboardId(R.xml.kbd_symbols_shift); + mModeToVoice = new HashMap(); + mModeToVoice.put(R.id.mode_normal, R.id.mode_normal_voice); + mModeToVoice.put(R.id.mode_url, R.id.mode_url_voice); + mModeToVoice.put(R.id.mode_email, R.id.mode_email_voice); + mModeToVoice.put(R.id.mode_im, R.id.mode_im_voice); mInputMethodService = ims; } @@ -110,12 +128,12 @@ public class KeyboardSwitcher { */ private static class KeyboardId { public int mXml; - public int mMode; + public int mKeyboardMode; /** A KEYBOARDMODE_XXX value */ public boolean mEnableShiftLock; public KeyboardId(int xml, int mode, boolean enableShiftLock) { this.mXml = xml; - this.mMode = mode; + this.mKeyboardMode = mode; this.mEnableShiftLock = enableShiftLock; } @@ -128,27 +146,40 @@ public class KeyboardSwitcher { } public boolean equals(KeyboardId other) { - return other.mXml == this.mXml && other.mMode == this.mMode; + return other.mXml == this.mXml + && other.mKeyboardMode == this.mKeyboardMode + && other.mEnableShiftLock == this.mEnableShiftLock; } public int hashCode() { - return (mXml + 1) * (mMode + 1) * (mEnableShiftLock ? 2 : 1); + return (mXml + 1) * (mKeyboardMode + 1) * (mEnableShiftLock ? 2 : 1); } } - void setKeyboardMode(int mode, int imeOptions) { + void setVoiceMode(boolean enableVoice) { + setKeyboardMode(mMode, mImeOptions, enableVoice, mIsSymbols); + } + + void setKeyboardMode(int mode, int imeOptions, boolean enableVoice) { mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; mPreferSymbols = mode == MODE_SYMBOLS; - setKeyboardMode(mode == MODE_SYMBOLS ? MODE_TEXT : mode, imeOptions, + setKeyboardMode(mode == MODE_SYMBOLS ? MODE_TEXT : mode, imeOptions, enableVoice, mPreferSymbols); } - void setKeyboardMode(int mode, int imeOptions, boolean isSymbols) { + void setKeyboardMode(int mode, int imeOptions, + boolean enableVoice, boolean isSymbols) { mMode = mode; mImeOptions = imeOptions; + mHasVoice = enableVoice; mIsSymbols = isSymbols; + mInputView.setPreviewEnabled(true); KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); + + if (enableVoice && mModeToVoice.containsKey(id.mKeyboardMode)) { + id.mKeyboardMode = mModeToVoice.get(id.mKeyboardMode); + } LatinKeyboard keyboard = getKeyboard(id); if (mode == MODE_PHONE) { @@ -166,7 +197,6 @@ public class KeyboardSwitcher { keyboard.setShifted(false); keyboard.setShiftLocked(keyboard.isShiftLocked()); keyboard.setImeOptions(mContext.getResources(), mMode, imeOptions); - } private LatinKeyboard getKeyboard(KeyboardId id) { @@ -177,11 +207,16 @@ public class KeyboardSwitcher { conf.locale = mInputLocale; orig.updateConfiguration(conf, null); LatinKeyboard keyboard = new LatinKeyboard( - mContext, id.mXml, id.mMode); - if (id.mMode == KEYBOARDMODE_NORMAL - || id.mMode == KEYBOARDMODE_URL - || id.mMode == KEYBOARDMODE_IM - || id.mMode == KEYBOARDMODE_EMAIL) { + mContext, id.mXml, id.mKeyboardMode); + if (id.mKeyboardMode == KEYBOARDMODE_NORMAL + || id.mKeyboardMode == KEYBOARDMODE_URL + || id.mKeyboardMode == KEYBOARDMODE_IM + || id.mKeyboardMode == KEYBOARDMODE_EMAIL + || id.mKeyboardMode == R.id.mode_normal_voice + || id.mKeyboardMode == R.id.mode_url_voice + || id.mKeyboardMode == R.id.mode_im_voice + || id.mKeyboardMode == R.id.mode_email_voice + ) { keyboard.setExtension(R.xml.kbd_extension); } @@ -241,7 +276,7 @@ public class KeyboardSwitcher { mTextMode = position; } if (isTextMode()) { - setKeyboardMode(MODE_TEXT, mImeOptions); + setKeyboardMode(MODE_TEXT, mImeOptions, mHasVoice); } } @@ -250,11 +285,13 @@ public class KeyboardSwitcher { } boolean isAlphabetMode() { - KeyboardId current = mCurrentId; - return current.mMode == KEYBOARDMODE_NORMAL - || current.mMode == KEYBOARDMODE_URL - || current.mMode == KEYBOARDMODE_EMAIL - || current.mMode == KEYBOARDMODE_IM; + int currentMode = mCurrentId.mKeyboardMode; + for (Integer mode : ALPHABET_MODES) { + if (currentMode == mode || currentMode == mModeToVoice.get(mode)) { + return true; + } + } + return false; } void toggleShift() { @@ -278,7 +315,7 @@ public class KeyboardSwitcher { } void toggleSymbols() { - setKeyboardMode(mMode, mImeOptions, !mIsSymbols); + setKeyboardMode(mMode, mImeOptions, mHasVoice, !mIsSymbols); if (mIsSymbols && !mPreferSymbols) { mSymbolsModeState = SYMBOLS_MODE_STATE_BEGIN; } else { diff --git a/src/com/android/inputmethod/latin/LatinIME.java b/src/com/android/inputmethod/latin/LatinIME.java index 98f47c2c6..cbf3a4a52 100644 --- a/src/com/android/inputmethod/latin/LatinIME.java +++ b/src/com/android/inputmethod/latin/LatinIME.java @@ -16,13 +16,7 @@ package com.android.inputmethod.latin; -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import com.android.inputmethod.latin.UserDictionary; +import com.google.android.collect.Lists; import android.app.AlertDialog; import android.backup.BackupManager; @@ -53,23 +47,42 @@ import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; import android.view.KeyEvent; +import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.ExtractedText; +import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; +import com.android.inputmethod.voice.EditingUtil; +import com.android.inputmethod.voice.FieldContext; +import com.android.inputmethod.voice.GoogleSettingsUtil; +import com.android.inputmethod.voice.VoiceInput; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + /** * Input method implementation for Qwerty'ish keyboard. */ -public class LatinIME extends InputMethodService +public class LatinIME extends InputMethodService implements KeyboardView.OnKeyboardActionListener, - SharedPreferences.OnSharedPreferenceChangeListener { - + VoiceInput.UiListener, + SharedPreferences.OnSharedPreferenceChangeListener { + private static final String TAG = "LatinIME"; static final boolean DEBUG = false; static final boolean TRACE = false; + static final boolean VOICE_INSTALLED = true; + static final boolean ENABLE_VOICE_BUTTON = true; private static final String PREF_VIBRATE_ON = "vibrate_on"; private static final String PREF_SOUND_ON = "sound_on"; @@ -77,12 +90,53 @@ public class LatinIME extends InputMethodService private static final String PREF_QUICK_FIXES = "quick_fixes"; private static final String PREF_SHOW_SUGGESTIONS = "show_suggestions"; private static final String PREF_AUTO_COMPLETE = "auto_complete"; + private static final String PREF_ENABLE_VOICE = "enable_voice_input"; + private static final String PREF_VOICE_SERVER_URL = "voice_server_url"; + + // Whether or not the user has used voice input before (and thus, whether to show the + // first-run warning dialog or not). + private static final String PREF_HAS_USED_VOICE_INPUT = "has_used_voice_input"; + + // Whether or not the user has used voice input from an unsupported locale UI before. + // For example, the user has a Chinese UI but activates voice input. + private static final String PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE = + "has_used_voice_input_unsupported_locale"; + + // A list of locales which are supported by default for voice input, unless we get a + // different list from Gservices. + public static final String DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES = + "en " + + "en_US " + + "en_GB " + + "en_AU " + + "en_CA " + + "en_IE " + + "en_IN " + + "en_NZ " + + "en_SG " + + "en_ZA "; + + // The private IME option used to indicate that no microphone should be shown for a + // given text field. For instance this is specified by the search dialog when the + // dialog is already showing a voice search button. + private static final String IME_OPTION_NO_MICROPHONE = "nm"; + public static final String PREF_SELECTED_LANGUAGES = "selected_languages"; public static final String PREF_INPUT_LANGUAGE = "input_language"; private static final int MSG_UPDATE_SUGGESTIONS = 0; private static final int MSG_START_TUTORIAL = 1; private static final int MSG_UPDATE_SHIFT_STATE = 2; + private static final int MSG_VOICE_RESULTS = 3; + private static final int MSG_START_LISTENING_AFTER_SWIPE = 4; + + // If we detect a swipe gesture within N ms of typing, then swipe is + // ignored, since it may in fact be two key presses in quick succession. + private static final long MIN_MILLIS_AFTER_TYPING_BEFORE_SWIPE = 1000; + + // If we detect a swipe gesture, and the user types N ms later, cancel the + // swipe since it was probably a false trigger. + private static final long MIN_MILLIS_AFTER_SWIPE_TO_WAIT_FOR_TYPING = 500; // How many continuous deletes at which to start deleting at a higher speed. private static final int DELETE_ACCELERATE_AT = 20; @@ -102,7 +156,7 @@ public class LatinIME extends InputMethodService // Contextual menu positions private static final int POS_SETTINGS = 0; private static final int POS_METHOD = 1; - + private LatinKeyboardView mInputView; private CandidateViewContainer mCandidateViewContainer; private CandidateView mCandidateView; @@ -110,6 +164,7 @@ public class LatinIME extends InputMethodService private CompletionInfo[] mCompletions; private AlertDialog mOptionsDialog; + private AlertDialog mVoiceWarningDialog; KeyboardSwitcher mKeyboardSwitcher; @@ -117,6 +172,8 @@ public class LatinIME extends InputMethodService private ContactsDictionary mContactsDictionary; private ExpandableDictionary mAutoDictionary; + private Hints mHints; + Resources mResources; private String mLocale; @@ -125,6 +182,13 @@ public class LatinIME extends InputMethodService private WordComposer mWord = new WordComposer(); private int mCommittedLength; private boolean mPredicting; + private boolean mRecognizing; + private boolean mAfterVoiceInput; + private boolean mImmediatelyAfterVoiceInput; + private boolean mShowingVoiceSuggestions; + private boolean mImmediatelyAfterVoiceSuggestions; + private boolean mVoiceInputHighlighted; + private boolean mEnableVoiceButton; private CharSequence mBestWord; private boolean mPredictionOn; private boolean mCompletionOn; @@ -133,14 +197,22 @@ public class LatinIME extends InputMethodService private boolean mAutoCorrectEnabled; private boolean mAutoCorrectOn; private boolean mCapsLock; + private boolean mPasswordText; + private boolean mEmailText; private boolean mVibrateOn; private boolean mSoundOn; private boolean mAutoCap; private boolean mQuickFixes; + private boolean mHasUsedVoiceInput; + private boolean mHasUsedVoiceInputUnsupportedLocale; + private boolean mLocaleSupportedForVoiceInput; private boolean mShowSuggestions; + private boolean mSuggestionShouldReplaceCurrentWord; + private boolean mIsShowingHint; private int mCorrectionMode; + private boolean mEnableVoice = true; private int mOrientation; - + // Indicates whether the suggestion strip is to be on in landscape private boolean mJustAccepted; private CharSequence mJustRevertedSeparator; @@ -159,6 +231,17 @@ public class LatinIME extends InputMethodService private String mWordSeparators; private String mSentenceSeparators; + private VoiceInput mVoiceInput; + private VoiceResults mVoiceResults = new VoiceResults(); + private long mSwipeTriggerTimeMillis; + + // For each word, a list of potential replacements, usually from voice. + private Map> mWordToSuggestions = new HashMap(); + + private class VoiceResults { + List candidates; + Map> alternatives; + } private int mCurrentInputLocale = 0; private String mInputLanguage; private String[] mSelectedLanguageArray; @@ -186,6 +269,13 @@ public class LatinIME extends InputMethodService case MSG_UPDATE_SHIFT_STATE: updateShiftKeyState(getCurrentInputEditorInfo()); break; + case MSG_VOICE_RESULTS: + handleVoiceResults(); + break; + case MSG_START_LISTENING_AFTER_SWIPE: + if (mLastKeyTime < mSwipeTriggerTimeMillis) { + startListening(true); + } } } }; @@ -212,6 +302,19 @@ public class LatinIME extends InputMethodService // register to receive ringer mode changes for silent mode IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION); registerReceiver(mReceiver, filter); + if (VOICE_INSTALLED) { + mVoiceInput = new VoiceInput(this, this); + mHints = new Hints(this, new Hints.Display() { + public void showHint(int viewResource) { + LayoutInflater inflater = (LayoutInflater) getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + View view = inflater.inflate(viewResource, null); + setCandidatesView(view); + setCandidatesViewShown(true); + mIsShowingHint = true; + } + }); + } PreferenceManager.getDefaultSharedPreferences(this) .registerOnSharedPreferenceChangeListener(this); } @@ -228,7 +331,6 @@ public class LatinIME extends InputMethodService mSuggest.close(); } mSuggest = new Suggest(this, R.raw.main); - if (mUserDictionary != null) mUserDictionary.close(); mUserDictionary = new UserDictionary(this); if (mContactsDictionary == null) { mContactsDictionary = new ContactsDictionary(this); @@ -248,10 +350,14 @@ public class LatinIME extends InputMethodService orig.updateConfiguration(conf, orig.getDisplayMetrics()); } - @Override public void onDestroy() { + @Override + public void onDestroy() { mUserDictionary.close(); mContactsDictionary.close(); unregisterReceiver(mReceiver); + if (VOICE_INSTALLED) { + mVoiceInput.destroy(); + } super.onDestroy(); } @@ -262,7 +368,9 @@ public class LatinIME extends InputMethodService } // If orientation changed while predicting, commit the change if (conf.orientation != mOrientation) { - commitTyped(getCurrentInputConnection()); + InputConnection ic = getCurrentInputConnection(); + commitTyped(ic); + if (ic != null) ic.finishComposingText(); // For voice input mOrientation = conf.orientation; } reloadKeyboards(); @@ -276,10 +384,27 @@ public class LatinIME extends InputMethodService mKeyboardSwitcher.setInputView(mInputView); mKeyboardSwitcher.makeKeyboards(true); mInputView.setOnKeyboardActionListener(this); - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, 0); + mKeyboardSwitcher.setKeyboardMode( + KeyboardSwitcher.MODE_TEXT, 0, + shouldShowVoiceButton(makeFieldContext(), getCurrentInputEditorInfo())); return mInputView; } + @Override + public void onInitializeInterface() { + // Create a new view associated with voice input if the old + // view is stuck in another layout (e.g. if switching from + // portrait to landscape while speaking) + // NOTE: This must be done here because for some reason + // onCreateInputView isn't called after an orientation change while + // speech rec is in progress. + if (mVoiceInput != null && mVoiceInput.getView().getParent() != null) { + mVoiceInput.newView(); + } + + super.onInitializeInterface(); + } + @Override public View onCreateCandidatesView() { mKeyboardSwitcher.makeKeyboards(true); @@ -308,32 +433,54 @@ public class LatinIME extends InputMethodService TextEntryState.newSession(this); + // Most such things we decide below in the switch statement, but we need to know + // now whether this is a password text field, because we need to know now (before + // the switch statement) whether we want to enable the voice button. + mPasswordText = false; + int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION; + if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD || + variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) { + mPasswordText = true; + } + + mEnableVoiceButton = shouldShowVoiceButton(makeFieldContext(), attribute); + + mAfterVoiceInput = false; + mImmediatelyAfterVoiceInput = false; + mShowingVoiceSuggestions = false; + mImmediatelyAfterVoiceSuggestions = false; + mVoiceInputHighlighted = false; + boolean disableAutoCorrect = false; + mWordToSuggestions.clear(); mInputTypeNoAutoCorrect = false; mPredictionOn = false; mCompletionOn = false; mCompletions = null; mCapsLock = false; - switch (attribute.inputType&EditorInfo.TYPE_MASK_CLASS) { + mEmailText = false; + switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) { case EditorInfo.TYPE_CLASS_NUMBER: case EditorInfo.TYPE_CLASS_DATETIME: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_SYMBOLS, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); break; case EditorInfo.TYPE_CLASS_PHONE: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_PHONE, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); break; case EditorInfo.TYPE_CLASS_TEXT: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); //startPrediction(); mPredictionOn = true; // Make sure that passwords are not displayed in candidate view - int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION; if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD || variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ) { mPredictionOn = false; } + if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) { + mEmailText = true; + } if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS || variation == EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME) { mAutoSpace = false; @@ -343,14 +490,14 @@ public class LatinIME extends InputMethodService if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) { mPredictionOn = false; mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_EMAIL, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) { mPredictionOn = false; mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_URL, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_IM, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) { mPredictionOn = false; } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) { @@ -379,17 +526,25 @@ public class LatinIME extends InputMethodService break; default: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); updateShiftKeyState(attribute); } mInputView.closing(); mComposing.setLength(0); mPredicting = false; mDeleteCount = 0; - setCandidatesViewShown(false); - if (mCandidateView != null) mCandidateView.setSuggestions(null, false, false, false); loadSettings(); + setCandidatesViewShown(false); + setSuggestions(null, false, false, false); + + // Override auto correct + if (disableAutoCorrect) { + mAutoCorrectOn = false; + if (mCorrectionMode == Suggest.CORRECTION_FULL) { + mCorrectionMode = Suggest.CORRECTION_BASIC; + } + } // If the dictionary is not big enough, don't auto correct mHasDictionary = mSuggest.hasMainDictionary(); @@ -404,10 +559,31 @@ public class LatinIME extends InputMethodService @Override public void onFinishInput() { super.onFinishInput(); - + + if (mAfterVoiceInput) mVoiceInput.logInputEnded(); + + mVoiceInput.flushLogs(); + if (mInputView != null) { mInputView.closing(); } + if (VOICE_INSTALLED & mRecognizing) { + mVoiceInput.cancel(); + } + } + + @Override + public void onUpdateExtractedText(int token, ExtractedText text) { + super.onUpdateExtractedText(token, text); + InputConnection ic = getCurrentInputConnection(); + if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) { + mVoiceInput.logTextModified(); + + if (mHints.showPunctuationHintIfNecessary(ic)) { + mVoiceInput.logPunctuationHintDisplayed(); + } + } + mImmediatelyAfterVoiceInput = false; } @Override @@ -416,10 +592,22 @@ public class LatinIME extends InputMethodService int candidatesStart, int candidatesEnd) { super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd); + + if (DEBUG) { + Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart + + ", ose=" + oldSelEnd + + ", nss=" + newSelStart + + ", nse=" + newSelEnd + + ", cs=" + candidatesStart + + ", ce=" + candidatesEnd); + } + + mSuggestionShouldReplaceCurrentWord = false; // If the current selection in the text view changes, we should // clear whatever candidate text we have. - if (mComposing.length() > 0 && mPredicting && (newSelStart != candidatesEnd - || newSelEnd != candidatesEnd)) { + if ((((mComposing.length() > 0 && mPredicting) || mVoiceInputHighlighted) + && (newSelStart != candidatesEnd + || newSelEnd != candidatesEnd))) { mComposing.setLength(0); mPredicting = false; updateSuggestions(); @@ -428,25 +616,58 @@ public class LatinIME extends InputMethodService if (ic != null) { ic.finishComposingText(); } + mVoiceInputHighlighted = false; } else if (!mPredicting && !mJustAccepted && TextEntryState.getState() == TextEntryState.STATE_ACCEPTED_DEFAULT) { TextEntryState.reset(); } mJustAccepted = false; postUpdateShiftKeyState(); + + if (VOICE_INSTALLED) { + if (mShowingVoiceSuggestions) { + if (mImmediatelyAfterVoiceSuggestions) { + mImmediatelyAfterVoiceSuggestions = false; + } else { + updateSuggestions(); + mShowingVoiceSuggestions = false; + } + } + if (VoiceInput.ENABLE_WORD_CORRECTIONS) { + // If we have alternatives for the current word, then show them. + String word = EditingUtil.getWordAtCursor( + getCurrentInputConnection(), getWordSeparators()); + if (word != null && mWordToSuggestions.containsKey(word.trim())) { + mSuggestionShouldReplaceCurrentWord = true; + final List suggestions = mWordToSuggestions.get(word.trim()); + + setSuggestions(suggestions, false, true, true); + setCandidatesViewShown(true); + } + } + } } @Override public void hideWindow() { + if (mAfterVoiceInput) mVoiceInput.logInputEnded(); if (TRACE) Debug.stopMethodTracing(); if (mOptionsDialog != null && mOptionsDialog.isShowing()) { mOptionsDialog.dismiss(); mOptionsDialog = null; } + if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) { + mVoiceInput.logKeyboardWarningDialogDismissed(); + mVoiceWarningDialog.dismiss(); + mVoiceWarningDialog = null; + } if (mTutorial != null) { mTutorial.close(); mTutorial = null; } + if (VOICE_INSTALLED & mRecognizing) { + mVoiceInput.cancel(); + } super.hideWindow(); TextEntryState.endSession(); } @@ -462,7 +683,7 @@ public class LatinIME extends InputMethodService if (mCompletionOn) { mCompletions = completions; if (completions == null) { - mCandidateView.setSuggestions(null, false, false, false); + setSuggestions(null, false, false, false); return; } @@ -472,7 +693,7 @@ public class LatinIME extends InputMethodService if (ci != null) stringList.add(ci.getText()); } //CharSequence typedWord = mWord.getTypedWord(); - mCandidateView.setSuggestions(stringList, true, true, true); + setSuggestions(stringList, true, true, true); mBestWord = null; setCandidatesViewShown(isCandidateStripVisible() || mCompletionOn); } @@ -546,6 +767,20 @@ public class LatinIME extends InputMethodService return super.onKeyUp(keyCode, event); } + private void revertVoiceInput() { + InputConnection ic = getCurrentInputConnection(); + if (ic != null) ic.commitText("", 1); + updateSuggestions(); + mVoiceInputHighlighted = false; + } + + private void commitVoiceInput() { + InputConnection ic = getCurrentInputConnection(); + if (ic != null) ic.finishComposingText(); + updateSuggestions(); + mVoiceInputHighlighted = false; + } + private void reloadKeyboards() { if (mKeyboardSwitcher == null) { mKeyboardSwitcher = new KeyboardSwitcher(this, this); @@ -670,6 +905,11 @@ public class LatinIME extends InputMethodService case Keyboard.KEYCODE_MODE_CHANGE: changeKeyboardMode(); break; + case LatinKeyboardView.KEYCODE_VOICE: + if (VOICE_INSTALLED) { + startListening(false /* was a button press, was not a swipe */); + } + break; default: if (isWordSeparator(primaryCode)) { handleSeparator(primaryCode); @@ -698,6 +938,10 @@ public class LatinIME extends InputMethodService } private void handleBackspace() { + if (VOICE_INSTALLED && mVoiceInputHighlighted) { + revertVoiceInput(); + return; + } boolean deleteChar = false; InputConnection ic = getCurrentInputConnection(); if (ic == null) return; @@ -743,6 +987,9 @@ public class LatinIME extends InputMethodService } private void handleCharacter(int primaryCode, int[] keyCodes) { + if (VOICE_INSTALLED && mVoiceInputHighlighted) { + commitVoiceInput(); + } if (isAlphabet(primaryCode) && isPredictionOn() && !isCursorTouchingWord()) { if (!mPredicting) { mPredicting = true; @@ -778,6 +1025,9 @@ public class LatinIME extends InputMethodService } private void handleSeparator(int primaryCode) { + if (VOICE_INSTALLED && mVoiceInputHighlighted) { + commitVoiceInput(); + } boolean pickedDefault = false; // Handle separator InputConnection ic = getCurrentInputConnection(); @@ -816,9 +1066,12 @@ public class LatinIME extends InputMethodService ic.endBatchEdit(); } } - + private void handleClose() { commitTyped(getCurrentInputConnection()); + if (VOICE_INSTALLED & mRecognizing) { + mVoiceInput.cancel(); + } requestHideSelf(0); mInputView.closing(); TextEntryState.endSession(); @@ -852,14 +1105,205 @@ public class LatinIME extends InputMethodService return isPredictionOn() && mShowSuggestions; } - private void updateSuggestions() { - // Check if we have a suggestion engine attached. - if (mSuggest == null || !isPredictionOn()) { - return; + public void onCancelVoice() { + if (mRecognizing) { + switchToKeyboardView(); + } + } + + private void switchToKeyboardView() { + mHandler.post(new Runnable() { + public void run() { + mRecognizing = false; + if (mInputView != null) { + setInputView(mInputView); + } + updateInputViewShown(); + }}); + } + + private void switchToRecognitionStatusView() { + mHandler.post(new Runnable() { + public void run() { + mRecognizing = true; + setInputView(mVoiceInput.getView()); + updateInputViewShown(); + }}); + } + + private void startListening(boolean swipe) { + if (!mHasUsedVoiceInput || + (!mLocaleSupportedForVoiceInput && !mHasUsedVoiceInputUnsupportedLocale)) { + // Calls reallyStartListening if user clicks OK, does nothing if user clicks Cancel. + showVoiceWarningDialog(swipe); + } else { + reallyStartListening(swipe); + } + } + + private void reallyStartListening(boolean swipe) { + if (!mHasUsedVoiceInput) { + // The user has started a voice input, so remember that in the + // future (so we don't show the warning dialog after the first run). + SharedPreferences.Editor editor = + PreferenceManager.getDefaultSharedPreferences(this).edit(); + editor.putBoolean(PREF_HAS_USED_VOICE_INPUT, true); + editor.commit(); + mHasUsedVoiceInput = true; } + if (!mLocaleSupportedForVoiceInput && !mHasUsedVoiceInputUnsupportedLocale) { + // The user has started a voice input from an unsupported locale, so remember that + // in the future (so we don't show the warning dialog the next time they do this). + SharedPreferences.Editor editor = + PreferenceManager.getDefaultSharedPreferences(this).edit(); + editor.putBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, true); + editor.commit(); + mHasUsedVoiceInputUnsupportedLocale = true; + } + + // Clear N-best suggestions + setSuggestions(null, false, false, true); + + FieldContext context = new FieldContext( + getCurrentInputConnection(), getCurrentInputEditorInfo()); + mVoiceInput.startListening(context, swipe); + switchToRecognitionStatusView(); + } + + private void showVoiceWarningDialog(final boolean swipe) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setCancelable(true); + builder.setIcon(R.drawable.ic_mic_dialog); + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + mVoiceInput.logKeyboardWarningDialogOk(); + reallyStartListening(swipe); + } + }); + builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + mVoiceInput.logKeyboardWarningDialogCancel(); + } + }); + + if (mLocaleSupportedForVoiceInput) { + String message = getString(R.string.voice_warning_may_not_understand) + "\n\n" + + getString(R.string.voice_warning_how_to_turn_off); + builder.setMessage(message); + } else { + String message = getString(R.string.voice_warning_locale_not_supported) + "\n\n" + + getString(R.string.voice_warning_may_not_understand) + "\n\n" + + getString(R.string.voice_warning_how_to_turn_off); + builder.setMessage(message); + } + + builder.setTitle(R.string.voice_warning_title); + mVoiceWarningDialog = builder.create(); + + Window window = mVoiceWarningDialog.getWindow(); + WindowManager.LayoutParams lp = window.getAttributes(); + lp.token = mInputView.getWindowToken(); + lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; + window.setAttributes(lp); + window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + mVoiceInput.logKeyboardWarningDialogShown(); + mVoiceWarningDialog.show(); + } + + public void onVoiceResults(List candidates, + Map> alternatives) { + if (!mRecognizing) { + return; + } + mVoiceResults.candidates = candidates; + mVoiceResults.alternatives = alternatives; + mHandler.sendMessage(mHandler.obtainMessage(MSG_VOICE_RESULTS)); + } + + private void handleVoiceResults() { + mAfterVoiceInput = true; + mImmediatelyAfterVoiceInput = true; + + InputConnection ic = getCurrentInputConnection(); + if (!isFullscreenMode()) { + // Start listening for updates to the text from typing, etc. + if (ic != null) { + ExtractedTextRequest req = new ExtractedTextRequest(); + ic.getExtractedText(req, InputConnection.GET_EXTRACTED_TEXT_MONITOR); + } + } + + vibrate(); + switchToKeyboardView(); + + final List nBest = new ArrayList(); + boolean capitalizeFirstWord = preferCapitalization() + || (mKeyboardSwitcher.isAlphabetMode() && mInputView.isShifted()); + for (String c : mVoiceResults.candidates) { + if (capitalizeFirstWord) { + c = Character.toUpperCase(c.charAt(0)) + c.substring(1, c.length()); + } + nBest.add(c); + } + + if (nBest.size() == 0) { + return; + } + + String bestResult = nBest.get(0).toString(); + + mVoiceInput.logVoiceInputDelivered(); + + mHints.registerVoiceResult(bestResult); + + if (ic != null) ic.beginBatchEdit(); // To avoid extra updates on committing older text + + commitTyped(ic); + EditingUtil.appendText(ic, bestResult); + + if (ic != null) ic.endBatchEdit(); + + // Show N-Best alternates, if there is more than one choice. + if (nBest.size() > 1) { + mImmediatelyAfterVoiceSuggestions = true; + mShowingVoiceSuggestions = true; + setSuggestions(nBest.subList(1, nBest.size()), false, true, true); + setCandidatesViewShown(true); + } + mVoiceInputHighlighted = true; + mWordToSuggestions.putAll(mVoiceResults.alternatives); + + } + + private void setSuggestions( + List suggestions, + boolean completions, + + boolean typedWordValid, + boolean haveMinimalSuggestion) { + + if (mIsShowingHint) { + setCandidatesView(mCandidateViewContainer); + mIsShowingHint = false; + } + + if (mCandidateView != null) { + mCandidateView.setSuggestions( + suggestions, completions, typedWordValid, haveMinimalSuggestion); + } + } + + private void updateSuggestions() { + mSuggestionShouldReplaceCurrentWord = false; + + // Check if we have a suggestion engine attached. + if ((mSuggest == null || !isPredictionOn()) && !mVoiceInputHighlighted) { + return; + } + if (!mPredicting) { - mCandidateView.setSuggestions(null, false, false, false); + setSuggestions(null, false, false, false); return; } @@ -876,7 +1320,7 @@ public class LatinIME extends InputMethodService // Don't auto-correct words with multiple capital letter correctionAvailable &= !mWord.isMostlyCaps(); - mCandidateView.setSuggestions(stringList, false, typedWordValid, correctionAvailable); + setSuggestions(stringList, false, typedWordValid, correctionAvailable); if (stringList.size() > 0) { if (correctionAvailable && !typedWordValid && stringList.size() > 1) { mBestWord = stringList.get(1); @@ -903,6 +1347,8 @@ public class LatinIME extends InputMethodService } public void pickSuggestionManually(int index, CharSequence suggestion) { + if (mAfterVoiceInput && mShowingVoiceSuggestions) mVoiceInput.logNBestChoose(index); + if (mCompletionOn && mCompletions != null && index >= 0 && index < mCompletions.length) { CompletionInfo ci = mCompletions[index]; @@ -937,7 +1383,12 @@ public class LatinIME extends InputMethodService } InputConnection ic = getCurrentInputConnection(); if (ic != null) { - ic.commitText(suggestion, 1); + if (mSuggestionShouldReplaceCurrentWord) { + EditingUtil.deleteWordAtCursor(ic, getWordSeparators()); + } + if (!VoiceInput.DELETE_SYMBOL.equals(suggestion)) { + ic.commitText(suggestion, 1); + } } // Add the word to the auto dictionary if it's not a known word if (mAutoDictionary.isValidWord(suggestion) || !mSuggest.isValidWord(suggestion)) { @@ -945,9 +1396,7 @@ public class LatinIME extends InputMethodService } mPredicting = false; mCommittedLength = suggestion.length(); - if (mCandidateView != null) { - mCandidateView.setSuggestions(null, false, false, false); - } + setSuggestions(null, false, false, false); updateShiftKeyState(getCurrentInputEditorInfo()); } @@ -1016,6 +1465,11 @@ public class LatinIME extends InputMethodService } public void swipeRight() { + if (userHasNotTypedRecently() && VOICE_INSTALLED && mEnableVoice && + fieldCanDoVoice(makeFieldContext())) { + startListening(true /* was a swipe */); + } + if (LatinKeyboardView.DEBUG_AUTO_PLAY) { ClipboardManager cm = ((ClipboardManager)getSystemService(CLIPBOARD_SERVICE)); CharSequence text = cm.getText(); @@ -1035,7 +1489,7 @@ public class LatinIME extends InputMethodService int currentKeyboardMode = mKeyboardSwitcher.getKeyboardMode(); reloadKeyboards(); mKeyboardSwitcher.makeKeyboards(true); - mKeyboardSwitcher.setKeyboardMode(currentKeyboardMode, 0); + mKeyboardSwitcher.setKeyboardMode(currentKeyboardMode, 0, mEnableVoiceButton); initSuggest(mInputLanguage); persistInputLanguage(mInputLanguage); updateShiftKeyState(getCurrentInputEditorInfo()); @@ -1068,7 +1522,30 @@ public class LatinIME extends InputMethodService public void onRelease(int primaryCode) { //vibrate(); } + + private FieldContext makeFieldContext() { + return new FieldContext(getCurrentInputConnection(), getCurrentInputEditorInfo()); + } + + private boolean fieldCanDoVoice(FieldContext fieldContext) { + return !mPasswordText + && mVoiceInput != null + && !mVoiceInput.isBlacklistedField(fieldContext); + } + private boolean fieldIsRecommendedForVoice(FieldContext fieldContext) { + // TODO: Move this logic into the VoiceInput method. + return !mPasswordText && !mEmailText && mVoiceInput.isRecommendedField(fieldContext); + } + + private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo attribute) { + return ENABLE_VOICE_BUTTON + && mEnableVoice + && fieldCanDoVoice(fieldContext) + && !(attribute != null && attribute.privateImeOptions != null + && attribute.privateImeOptions.equals(IME_OPTION_NO_MICROPHONE)); + } + // receive ringer mode changes to detect silent mode private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -1087,6 +1564,26 @@ public class LatinIME extends InputMethodService } } + private boolean userHasNotTypedRecently() { + return (SystemClock.uptimeMillis() - mLastKeyTime) + > MIN_MILLIS_AFTER_TYPING_BEFORE_SWIPE; + } + + /* + * Only trigger a swipe action if the user hasn't typed X millis before + * now, and if they don't type Y millis after the swipe is detected. This + * delays the onset of the swipe action by Y millis. + */ + private void conservativelyTriggerSwipeAction(final Runnable action) { + if (userHasNotTypedRecently()) { + mSwipeTriggerTimeMillis = System.currentTimeMillis(); + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_START_LISTENING_AFTER_SWIPE), + MIN_MILLIS_AFTER_SWIPE_TO_WAIT_FOR_TYPING); + } + } + + private void playKeyClick(int primaryCode) { // if mAudioManager is null, we don't have the ringer state yet // mAudioManager will be set by updateRingerMode @@ -1162,10 +1659,14 @@ public class LatinIME extends InputMethodService } } - private void launchSettings() { + protected void launchSettings() { + launchSettings(LatinIMESettings.class); + } + + protected void launchSettings(Class settingsClass) { handleClose(); Intent intent = new Intent(); - intent.setClass(LatinIME.this, LatinIMESettings.class); + intent.setClass(LatinIME.this, settingsClass); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } @@ -1177,10 +1678,37 @@ public class LatinIME extends InputMethodService mSoundOn = sp.getBoolean(PREF_SOUND_ON, false); mAutoCap = sp.getBoolean(PREF_AUTO_CAP, true); mQuickFixes = sp.getBoolean(PREF_QUICK_FIXES, true); + mHasUsedVoiceInput = sp.getBoolean(PREF_HAS_USED_VOICE_INPUT, false); + mHasUsedVoiceInputUnsupportedLocale = + sp.getBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, false); + + // Get the current list of supported locales and check the current locale against that + // list. We cache this value so as not to check it every time the user starts a voice + // input. Because this method is called by onStartInputView, this should mean that as + // long as the locale doesn't change while the user is keeping the IME open, the + // value should never be stale. + String supportedLocalesString = GoogleSettingsUtil.getGservicesString( + getContentResolver(), + GoogleSettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES, + DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES); + ArrayList voiceInputSupportedLocales = + Lists.newArrayList(supportedLocalesString.split("\\s+")); + + mLocaleSupportedForVoiceInput = voiceInputSupportedLocales.contains(mLocale); + // If there is no auto text data, then quickfix is forced to "on", so that the other options // will continue to work + if (AutoText.getSize(mInputView) < 1) mQuickFixes = true; mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, true) & mQuickFixes; + + if (VOICE_INSTALLED) { + boolean enableVoice = sp.getBoolean(PREF_ENABLE_VOICE, true); + if (enableVoice != mEnableVoice && mKeyboardSwitcher != null) { + mKeyboardSwitcher.setVoiceMode(enableVoice); + } + mEnableVoice = enableVoice; + } mAutoCorrectEnabled = sp.getBoolean(PREF_AUTO_COMPLETE, mResources.getBoolean(R.bool.enable_autocorrect)) & mShowSuggestions; updateCorrectionMode(); @@ -1219,7 +1747,7 @@ public class LatinIME extends InputMethodService builder.setIcon(R.drawable.ic_dialog_keyboard); builder.setNegativeButton(android.R.string.cancel, null); CharSequence itemSettings = getString(R.string.english_ime_settings); - CharSequence itemInputMethod = getString(com.android.internal.R.string.inputMethod); + CharSequence itemInputMethod = getString(R.string.inputMethod); builder.setItems(new CharSequence[] { itemSettings, itemInputMethod}, new DialogInterface.OnClickListener() { @@ -1327,6 +1855,3 @@ public class LatinIME extends InputMethodService } } } - - - diff --git a/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java b/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java index c454f120e..b6a800ebd 100644 --- a/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java +++ b/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java @@ -26,6 +26,6 @@ public class LatinIMEBackupAgent extends BackupHelperAgent { public void onCreate() { addHelper("shared_pref", new SharedPreferencesBackupHelper(this, - "com.android.inputmethod.latin_preferences")); + getPackageName() + "_preferences")); } } diff --git a/src/com/android/inputmethod/latin/LatinIMESettings.java b/src/com/android/inputmethod/latin/LatinIMESettings.java index c8ea309e3..4c221b905 100644 --- a/src/com/android/inputmethod/latin/LatinIMESettings.java +++ b/src/com/android/inputmethod/latin/LatinIMESettings.java @@ -16,23 +16,53 @@ package com.android.inputmethod.latin; +import com.google.android.collect.Lists; + +import android.app.AlertDialog; +import android.app.Dialog; import android.backup.BackupManager; +import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.CheckBoxPreference; +import android.preference.ListPreference; +import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceGroup; +import android.preference.Preference.OnPreferenceClickListener; import android.text.AutoText; +import android.util.Log; + +import com.android.inputmethod.voice.GoogleSettingsUtil; +import com.android.inputmethod.voice.VoiceInput; +import com.android.inputmethod.voice.VoiceInputLogger; + +import java.util.ArrayList; +import java.util.Locale; public class LatinIMESettings extends PreferenceActivity - implements SharedPreferences.OnSharedPreferenceChangeListener { + implements SharedPreferences.OnSharedPreferenceChangeListener, + OnPreferenceClickListener, + DialogInterface.OnDismissListener { private static final String QUICK_FIXES_KEY = "quick_fixes"; private static final String SHOW_SUGGESTIONS_KEY = "show_suggestions"; private static final String PREDICTION_SETTINGS_KEY = "prediction_settings"; + private static final String VOICE_SETTINGS_KEY = "enable_voice_input"; + private static final String VOICE_SERVER_KEY = "voice_server_url"; + + private static final String TAG = "LatinIMESettings"; + + // Dialog ids + private static final int VOICE_INPUT_CONFIRM_DIALOG = 0; private CheckBoxPreference mQuickFixes; private CheckBoxPreference mShowSuggestions; + private CheckBoxPreference mVoicePreference; + + private VoiceInputLogger mLogger; + + private boolean mOkClicked = false; @Override protected void onCreate(Bundle icicle) { @@ -40,8 +70,16 @@ public class LatinIMESettings extends PreferenceActivity addPreferencesFromResource(R.xml.prefs); mQuickFixes = (CheckBoxPreference) findPreference(QUICK_FIXES_KEY); mShowSuggestions = (CheckBoxPreference) findPreference(SHOW_SUGGESTIONS_KEY); - getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener( - this); + mVoicePreference = (CheckBoxPreference) findPreference(VOICE_SETTINGS_KEY); + + SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); + prefs.registerOnSharedPreferenceChangeListener(this); + + mVoicePreference.setOnPreferenceClickListener(this); + mVoicePreference.setChecked(prefs.getBoolean( + VOICE_SETTINGS_KEY, getResources().getBoolean(R.bool.voice_input_default))); + + mLogger = VoiceInputLogger.getLogger(this); } @Override @@ -50,10 +88,17 @@ public class LatinIMESettings extends PreferenceActivity int autoTextSize = AutoText.getSize(getListView()); if (autoTextSize < 1) { ((PreferenceGroup) findPreference(PREDICTION_SETTINGS_KEY)) - .removePreference(mQuickFixes); + .removePreference(mQuickFixes); } else { mShowSuggestions.setDependency(QUICK_FIXES_KEY); } + if (!LatinIME.VOICE_INSTALLED + || !VoiceInput.voiceIsAvailable(this)) { + getPreferenceScreen().removePreference(mVoicePreference); + } + + mVoicePreference.setChecked( + getPreferenceManager().getSharedPreferences().getBoolean(VOICE_SETTINGS_KEY, true)); } @Override @@ -67,4 +112,91 @@ public class LatinIMESettings extends PreferenceActivity String key) { (new BackupManager(this)).dataChanged(); } + + public boolean onPreferenceClick(Preference preference) { + if (preference == mVoicePreference) { + if (mVoicePreference.isChecked()) { + mOkClicked = false; + showDialog(VOICE_INPUT_CONFIRM_DIALOG); + } else { + updateVoicePreference(); + } + } + return false; + } + + @Override + protected Dialog onCreateDialog(int id) { + switch (id) { + case VOICE_INPUT_CONFIRM_DIALOG: + DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + if (whichButton == DialogInterface.BUTTON_NEGATIVE) { + mVoicePreference.setChecked(false); + mLogger.settingsWarningDialogCancel(); + } else if (whichButton == DialogInterface.BUTTON_POSITIVE) { + mOkClicked = true; + mLogger.settingsWarningDialogOk(); + } + updateVoicePreference(); + } + }; + AlertDialog.Builder builder = new AlertDialog.Builder(this) + .setTitle(R.string.voice_warning_title) + .setPositiveButton(android.R.string.ok, listener) + .setNegativeButton(android.R.string.cancel, listener); + + // Get the current list of supported locales and check the current locale against + // that list, to decide whether to put a warning that voice input will not work in + // the current language as part of the pop-up confirmation dialog. + String supportedLocalesString = GoogleSettingsUtil.getGservicesString( + getContentResolver(), + GoogleSettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES, + LatinIME.DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES); + ArrayList voiceInputSupportedLocales = + Lists.newArrayList(supportedLocalesString.split("\\s+")); + boolean localeSupported = voiceInputSupportedLocales.contains( + Locale.getDefault().toString()); + + if (localeSupported) { + String message = getString(R.string.voice_warning_may_not_understand) + "\n\n" + + getString(R.string.voice_hint_dialog_message); + builder.setMessage(message); + } else { + String message = getString(R.string.voice_warning_locale_not_supported) + + "\n\n" + getString(R.string.voice_warning_may_not_understand) + "\n\n" + + getString(R.string.voice_hint_dialog_message); + builder.setMessage(message); + } + + AlertDialog dialog = builder.create(); + dialog.setOnDismissListener(this); + mLogger.settingsWarningDialogShown(); + return dialog; + default: + Log.e(TAG, "unknown dialog " + id); + return null; + } + } + + public void onDismiss(DialogInterface dialog) { + mLogger.settingsWarningDialogDismissed(); + if (!mOkClicked) { + // This assumes that onPreferenceClick gets called first, and this if the user + // agreed after the warning, we set the mOkClicked value to true. + mVoicePreference.setChecked(false); + } + } + + private void updateVoicePreference() { + SharedPreferences.Editor editor = getPreferenceManager().getSharedPreferences().edit(); + boolean isChecked = mVoicePreference.isChecked(); + if (isChecked) { + mLogger.voiceInputSettingEnabled(); + } else { + mLogger.voiceInputSettingDisabled(); + } + editor.putBoolean(VOICE_SETTINGS_KEY, isChecked); + editor.commit(); + } } diff --git a/src/com/android/inputmethod/latin/LatinKeyboardView.java b/src/com/android/inputmethod/latin/LatinKeyboardView.java index 163d824e0..ea9ccf0b6 100644 --- a/src/com/android/inputmethod/latin/LatinKeyboardView.java +++ b/src/com/android/inputmethod/latin/LatinKeyboardView.java @@ -35,8 +35,8 @@ public class LatinKeyboardView extends KeyboardView { static final int KEYCODE_OPTIONS = -100; static final int KEYCODE_SHIFT_LONGPRESS = -101; - static final int KEYCODE_F1 = -102; - + static final int KEYCODE_VOICE = -102; + static final int KEYCODE_F1 = -103; private Keyboard mPhoneKeyboard; public LatinKeyboardView(Context context, AttributeSet attrs) { diff --git a/src/com/android/inputmethod/voice/EditingUtil.java b/src/com/android/inputmethod/voice/EditingUtil.java new file mode 100644 index 000000000..6316d8ccf --- /dev/null +++ b/src/com/android/inputmethod/voice/EditingUtil.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.view.inputmethod.ExtractedText; +import android.view.inputmethod.ExtractedTextRequest; +import android.view.inputmethod.InputConnection; + +/** + * Utility methods to deal with editing text through an InputConnection. + */ +public class EditingUtil { + private EditingUtil() {}; + + /** + * Append newText to the text field represented by connection. + * The new text becomes selected. + */ + public static void appendText(InputConnection connection, String newText) { + if (connection == null) { + return; + } + + // Commit the composing text + connection.finishComposingText(); + + // Add a space if the field already has text. + CharSequence charBeforeCursor = connection.getTextBeforeCursor(1, 0); + if (charBeforeCursor != null + && !charBeforeCursor.equals(" ") + && (charBeforeCursor.length() > 0)) { + newText = " " + newText; + } + + connection.setComposingText(newText, 1); + } + + private static int getCursorPosition(InputConnection connection) { + ExtractedText extracted = connection.getExtractedText( + new ExtractedTextRequest(), 0); + if (extracted == null) { + return -1; + } + return extracted.startOffset + extracted.selectionStart; + } + + private static int getSelectionEnd(InputConnection connection) { + ExtractedText extracted = connection.getExtractedText( + new ExtractedTextRequest(), 0); + if (extracted == null) { + return -1; + } + return extracted.startOffset + extracted.selectionEnd; + } + + /** + * @param connection connection to the current text field. + * @param sep characters which may separate words + * @return the word that surrounds the cursor, including up to one trailing + * separator. For example, if the field contains "he|llo world", where | + * represents the cursor, then "hello " will be returned. + */ + public static String getWordAtCursor( + InputConnection connection, String separators) { + Range range = getWordRangeAtCursor(connection, separators); + return (range == null) ? null : range.word; + } + + /** + * Removes the word surrounding the cursor. Parameters are identical to + * getWordAtCursor. + */ + public static void deleteWordAtCursor( + InputConnection connection, String separators) { + + Range range = getWordRangeAtCursor(connection, separators); + if (range == null) return; + + connection.finishComposingText(); + // Move cursor to beginning of word, to avoid crash when cursor is outside + // of valid range after deleting text. + int newCursor = getCursorPosition(connection) - range.charsBefore; + connection.setSelection(newCursor, newCursor); + connection.deleteSurroundingText(0, range.charsBefore + range.charsAfter); + } + + /** + * Represents a range of text, relative to the current cursor position. + */ + private static class Range { + /** Characters before selection start */ + int charsBefore; + + /** + * Characters after selection start, including one trailing word + * separator. + */ + int charsAfter; + + /** The actual characters that make up a word */ + String word; + + public Range(int charsBefore, int charsAfter, String word) { + if (charsBefore < 0 || charsAfter < 0) { + throw new IndexOutOfBoundsException(); + } + this.charsBefore = charsBefore; + this.charsAfter = charsAfter; + this.word = word; + } + } + + private static Range getWordRangeAtCursor( + InputConnection connection, String sep) { + if (connection == null || sep == null) { + return null; + } + CharSequence before = connection.getTextBeforeCursor(1000, 0); + CharSequence after = connection.getTextAfterCursor(1000, 0); + if (before == null || after == null) { + return null; + } + + // Find first word separator before the cursor + int start = before.length(); + while (--start > 0 && !isWhitespace(before.charAt(start - 1), sep)); + + // Find last word separator after the cursor + int end = -1; + while (++end < after.length() && !isWhitespace(after.charAt(end), sep)); + if (end < after.length() - 1) { + end++; // Include trailing space, if it exists, in word + } + + int cursor = getCursorPosition(connection); + if (start >= 0 && cursor + end <= after.length() + before.length()) { + String word = before.toString().substring(start, before.length()) + + after.toString().substring(0, end); + return new Range(before.length() - start, end, word); + } + + return null; + } + + private static boolean isWhitespace(int code, String whitespace) { + return whitespace.contains(String.valueOf((char) code)); + } +} diff --git a/src/com/android/inputmethod/voice/FieldContext.java b/src/com/android/inputmethod/voice/FieldContext.java new file mode 100644 index 000000000..0578af732 --- /dev/null +++ b/src/com/android/inputmethod/voice/FieldContext.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.os.Bundle; +import android.util.Log; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.ExtractedText; +import android.view.inputmethod.ExtractedTextRequest; +import android.view.inputmethod.InputConnection; + +/** + * Represents information about a given text field, which can be passed + * to the speech recognizer as context information. + */ +public class FieldContext { + static final String LABEL = "label"; + static final String HINT = "hint"; + static final String PACKAGE_NAME = "packageName"; + static final String FIELD_ID = "fieldId"; + static final String FIELD_NAME = "fieldName"; + static final String SINGLE_LINE = "singleLine"; + static final String INPUT_TYPE = "inputType"; + static final String IME_OPTIONS = "imeOptions"; + + Bundle mFieldInfo; + + public FieldContext(InputConnection conn, EditorInfo info) { + this.mFieldInfo = new Bundle(); + addEditorInfoToBundle(info, mFieldInfo); + addInputConnectionToBundle(conn, mFieldInfo); + Log.i("FieldContext", "Bundle = " + mFieldInfo.toString()); + } + + private static String safeToString(Object o) { + if (o == null) { + return ""; + } + return o.toString(); + } + + private static void addEditorInfoToBundle(EditorInfo info, Bundle bundle) { + if (info == null) { + return; + } + + + bundle.putString(LABEL, safeToString(info.label)); + bundle.putString(HINT, safeToString(info.hintText)); + bundle.putString(PACKAGE_NAME, safeToString(info.packageName)); + bundle.putInt(FIELD_ID, info.fieldId); + bundle.putString(FIELD_NAME, safeToString(info.fieldName)); + bundle.putInt(INPUT_TYPE, info.inputType); + bundle.putInt(IME_OPTIONS, info.imeOptions); + } + + private static void addInputConnectionToBundle( + InputConnection conn, Bundle bundle) { + if (conn == null) { + return; + } + + ExtractedText et = conn.getExtractedText(new ExtractedTextRequest(), 0); + if (et == null) { + return; + } + bundle.putBoolean(SINGLE_LINE, (et.flags & et.FLAG_SINGLE_LINE) > 0); + } + + public Bundle getBundle() { + return mFieldInfo; + } + + public String toString() { + return mFieldInfo.toString(); + } +} diff --git a/src/com/android/inputmethod/voice/GoogleSettingsUtil.java b/src/com/android/inputmethod/voice/GoogleSettingsUtil.java new file mode 100644 index 000000000..d238579ba --- /dev/null +++ b/src/com/android/inputmethod/voice/GoogleSettingsUtil.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.content.ContentResolver; +import android.database.Cursor; +import android.net.Uri; +import android.util.Log; + +/** + * Utility for getting Google-specific settings from GoogleSettings.Partner or + * Gservices. Retrieving such settings may fail on a non-Google Experience + * Device (GED) + */ +public class GoogleSettingsUtil { + /** + * A whitespace-separated list of supported locales for voice input from the keyboard. + */ + public static final String LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES = + "latin_ime_voice_input_supported_locales"; + + /** + * A whitespace-separated list of recommended app packages for voice input from the + * keyboard. + */ + public static final String LATIN_IME_VOICE_INPUT_RECOMMENDED_PACKAGES = + "latin_ime_voice_input_recommended_packages"; + + /** + * The maximum number of unique days to show the swipe hint for voice input. + */ + public static final String LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS = + "latin_ime_voice_input_swipe_hint_max_days"; + + /** + * The maximum number of times to show the punctuation hint for voice input. + */ + public static final String LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS = + "latin_ime_voice_input_punctuation_hint_max_displays"; + + /** + * Endpointer parameters for voice input from the keyboard. + */ + public static final String LATIN_IME_SPEECH_MINIMUM_LENGTH_MILLIS = + "latin_ime_speech_minimum_length_millis"; + public static final String LATIN_IME_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS = + "latin_ime_speech_input_complete_silence_length_millis"; + public static final String LATIN_IME_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS = + "latin_ime_speech_input_possibly_complete_silence_length_millis"; + + /** + * Min and max volume levels that can be displayed on the "speak now" screen. + */ + public static final String LATIN_IME_MIN_MICROPHONE_LEVEL = + "latin_ime_min_microphone_level"; + public static final String LATIN_IME_MAX_MICROPHONE_LEVEL = + "latin_ime_max_microphone_level"; + + /** + * The number of sentence-level alternates to request of the server. + */ + public static final String LATIN_IME_MAX_VOICE_RESULTS = "latin_ime_max_voice_results"; + + /** + * Uri to use to access gservices settings + */ + private static final Uri GSERVICES_URI = Uri.parse("content://settings/gservices"); + + private static final String TAG = GoogleSettingsUtil.class.getSimpleName(); + + private static final boolean DBG = false; + + /** + * Safely query for a Gservices string setting, which may not be available if this + * is not a Google Experience Device. + * + * @param cr The content resolver to use + * @param key The setting to look up + * @param defaultValue The default value to use if none can be found + * @return The value of the setting, or defaultValue if it couldn't be found + */ + public static String getGservicesString(ContentResolver cr, String key, String defaultValue) { + return getSettingString(GSERVICES_URI, cr, key, defaultValue); + } + + /** + * Safely query for a Gservices int setting, which may not be available if this + * is not a Google Experience Device. + * + * @param cr The content resolver to use + * @param key The setting to look up + * @param defaultValue The default value to use if the setting couldn't be found or parsed + * @return The value of the setting, or defaultValue if it couldn't be found or parsed + */ + public static int getGservicesInt(ContentResolver cr, String key, int defaultValue) { + try { + return Integer.parseInt(getGservicesString(cr, key, String.valueOf(defaultValue))); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + /** + * Safely query for a Gservices float setting, which may not be available if this + * is not a Google Experience Device. + * + * @param cr The content resolver to use + * @param key The setting to look up + * @param defaultValue The default value to use if the setting couldn't be found or parsed + * @return The value of the setting, or defaultValue if it couldn't be found or parsed + */ + public static float getGservicesFloat(ContentResolver cr, String key, float defaultValue) { + try { + return Float.parseFloat(getGservicesString(cr, key, String.valueOf(defaultValue))); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + /** + * A safe way to query for a setting on both Google Experience and + * non-Google Experience devices, (code adapted from maps application + * examples) + * + * @param uri The uri to provide to the content resolver + * @param cr The content resolver to use + * @param key The setting to look up + * @param defaultValue The default value to use if none can be found + * @return The value of the setting, or defaultValue if it couldn't be found + */ + private static String getSettingString(Uri uri, ContentResolver cr, String key, + String defaultValue) { + String value = null; + + Cursor cursor = null; + try { + cursor = cr.query(uri, new String[] { + "value" + }, "name='" + key + "'", null, null); + if ((cursor != null) && cursor.moveToFirst()) { + value = cursor.getString(cursor.getColumnIndexOrThrow("value")); + } + } catch (Throwable t) { + // This happens because we're probably running a non Type 1 aka + // Google Experience device which doesn't have the Google libraries. + if (DBG) { + Log.d(TAG, "Error getting setting from " + uri + " for key " + key + ": " + t); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + if (DBG && value == null) { + Log.i(TAG, "no setting found from " + uri + " for key " + key + ", returning default"); + } + + return (value != null) ? value : defaultValue; + } +} diff --git a/src/com/android/inputmethod/voice/LatinIMEWithVoice.java b/src/com/android/inputmethod/voice/LatinIMEWithVoice.java new file mode 100644 index 000000000..ccbf5b6bc --- /dev/null +++ b/src/com/android/inputmethod/voice/LatinIMEWithVoice.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.content.Intent; + +import com.android.inputmethod.latin.LatinIME; + +public class LatinIMEWithVoice extends LatinIME { + @Override + protected void launchSettings() { + launchSettings(LatinIMEWithVoiceSettings.class); + } +} diff --git a/src/com/android/inputmethod/voice/LatinIMEWithVoiceSettings.java b/src/com/android/inputmethod/voice/LatinIMEWithVoiceSettings.java new file mode 100644 index 000000000..13a58e14d --- /dev/null +++ b/src/com/android/inputmethod/voice/LatinIMEWithVoiceSettings.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import com.android.inputmethod.latin.LatinIMESettings; + +public class LatinIMEWithVoiceSettings extends LatinIMESettings {} diff --git a/src/com/android/inputmethod/voice/LoggingEvents.java b/src/com/android/inputmethod/voice/LoggingEvents.java new file mode 100644 index 000000000..b63229186 --- /dev/null +++ b/src/com/android/inputmethod/voice/LoggingEvents.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +/** + * Logging event constants used for Voice Search and VoiceIME. These are the keys and values of + * extras to be specified in logging broadcast intents to the {@link LoggingReceiver}. + * + * This class is duplicated between VoiceSearch and LatinIME. Please keep both versions + * in sync. + */ +public class LoggingEvents { + // The name of the broadcast intent for logging. + public static final String ACTION_LOG_EVENT = "com.google.android.voicesearch.LOG_EVENT"; + + // The extra key used for the name of the app being logged. + public static final String EXTRA_APP_NAME = "app_name"; + + // The extra key used for the event value. The possible event values depend on the + // app being logged for, and are defined in the subclasses below. + public static final String EXTRA_EVENT = "extra_event"; + + // The extra key used (with a boolean value of 'true') as a way to trigger a flush + // of the log events to the server. + public static final String EXTRA_FLUSH = "flush"; + + /** + * Logging event constants for VoiceIME. Below are the extra values for + * {@link LoggingEvents#EXTRA_EVENT}, clustered with keys to additional extras + * for some events that need to be included as additional fields in the event. + */ + public class VoiceIme { + // The app name to be used for logging VoiceIME events. + public static final String APP_NAME = "voiceime"; + + public static final int KEYBOARD_WARNING_DIALOG_SHOWN = 0; + + public static final int KEYBOARD_WARNING_DIALOG_DISMISSED = 1; + + public static final int KEYBOARD_WARNING_DIALOG_OK = 2; + + public static final int KEYBOARD_WARNING_DIALOG_CANCEL = 3; + + public static final int SETTINGS_WARNING_DIALOG_SHOWN = 4; + + public static final int SETTINGS_WARNING_DIALOG_DISMISSED = 5; + + public static final int SETTINGS_WARNING_DIALOG_OK = 6; + + public static final int SETTINGS_WARNING_DIALOG_CANCEL = 7; + + public static final int SWIPE_HINT_DISPLAYED = 8; + + public static final int PUNCTUATION_HINT_DISPLAYED = 9; + + public static final int CANCEL_DURING_LISTENING = 10; + + public static final int CANCEL_DURING_WORKING = 11; + + public static final int CANCEL_DURING_ERROR = 12; + + public static final int ERROR = 13; + public static final String EXTRA_ERROR_CODE = "code"; // value should be int + + public static final int START = 14; + public static final String EXTRA_START_LOCALE = "locale"; // value should be String + public static final String EXTRA_START_SWIPE = "swipe"; // value should be boolean + + public static final int VOICE_INPUT_DELIVERED = 15; + + public static final int N_BEST_CHOOSE = 16; + public static final String EXTRA_N_BEST_CHOOSE_INDEX = "index"; // value should be int + + public static final int TEXT_MODIFIED = 17; + + public static final int INPUT_ENDED = 18; + + public static final int VOICE_INPUT_SETTING_ENABLED = 19; + + public static final int VOICE_INPUT_SETTING_DISABLED = 20; + } +} diff --git a/src/com/android/inputmethod/voice/RecognitionView.java b/src/com/android/inputmethod/voice/RecognitionView.java new file mode 100644 index 000000000..97acb1152 --- /dev/null +++ b/src/com/android/inputmethod/voice/RecognitionView.java @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.CornerPathEffect; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PathEffect; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup.MarginLayoutParams; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.inputmethod.latin.R; +import com.android.inputmethod.voice.GoogleSettingsUtil; + +import java.io.ByteArrayOutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.ShortBuffer; +import java.util.ArrayList; +import java.util.List; + +/** + * The user interface for the "Speak now" and "working" states. + * Displays a recognition dialog (with waveform, voice meter, etc.), + * plays beeps, shows errors, etc. + */ +public class RecognitionView { + private static final String TAG = "RecognitionView"; + + // If there's a significant delay between starting up voice search and the + // onset of audio recording, show the "initializing" screen first. If not, + // jump directly to the "speak now" screen to avoid flashing "initializing" + // quickly. + private static final boolean EXPECT_RECORDING_DELAY = true; + + private Handler mUiHandler; // Reference to UI thread + private View mView; + private Context mContext; + + private ImageView mImage; + private TextView mText; + private View mButton; + private TextView mButtonText; + private View mProgress; + + private Drawable mInitializing; + private Drawable mError; + private List mSpeakNow; + + private float mVolume = 0.0f; + private int mLevel = 0; + + private enum State {LISTENING, WORKING, READY} + private State mState = State.READY; + + private float mMinMicrophoneLevel; + private float mMaxMicrophoneLevel; + + /** Updates the microphone icon to show user their volume.*/ + private Runnable mUpdateVolumeRunnable = new Runnable() { + public void run() { + if (mState != State.LISTENING) { + return; + } + + final float min = mMinMicrophoneLevel; + final float max = mMaxMicrophoneLevel; + final int maxLevel = mSpeakNow.size() - 1; + + int index = (int) ((mVolume - min) / (max - min) * maxLevel); + final int level = Math.min(Math.max(0, index), maxLevel); + + if (level != mLevel) { + mImage.setImageDrawable(mSpeakNow.get(level)); + mLevel = level; + } + mUiHandler.postDelayed(mUpdateVolumeRunnable, 50); + } + }; + + public RecognitionView(Context context, OnClickListener clickListener) { + mUiHandler = new Handler(); + + LayoutInflater inflater = (LayoutInflater) context.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + mView = inflater.inflate(R.layout.recognition_status, null); + + ContentResolver cr = context.getContentResolver(); + mMinMicrophoneLevel = GoogleSettingsUtil.getGservicesFloat( + cr, GoogleSettingsUtil.LATIN_IME_MIN_MICROPHONE_LEVEL, 15.f); + mMaxMicrophoneLevel = GoogleSettingsUtil.getGservicesFloat( + cr, GoogleSettingsUtil.LATIN_IME_MAX_MICROPHONE_LEVEL, 30.f); + + // Pre-load volume level images + Resources r = context.getResources(); + + mSpeakNow = new ArrayList(); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level0)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level1)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level2)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level3)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level4)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level5)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level6)); + + mInitializing = r.getDrawable(R.drawable.mic_slash); + mError = r.getDrawable(R.drawable.caution); + + mImage = (ImageView) mView.findViewById(R.id.image); + mButton = mView.findViewById(R.id.button); + mButton.setOnClickListener(clickListener); + mText = (TextView) mView.findViewById(R.id.text); + mButtonText = (TextView) mView.findViewById(R.id.button_text); + mProgress = mView.findViewById(R.id.progress); + + mContext = context; + } + + public View getView() { + return mView; + } + + public void showInitializing() { + mUiHandler.post(new Runnable() { + public void run() { + mText.setText(R.string.voice_initializing); + mImage.setImageDrawable(mInitializing); + mButtonText.setText(mContext.getText(R.string.cancel)); + } + }); + } + + public void showStartState() { + if (EXPECT_RECORDING_DELAY) { + showInitializing(); + } else { + showListening(); + } + } + + public void showListening() { + mState = State.LISTENING; + mUiHandler.post(new Runnable() { + public void run() { + mText.setText(R.string.voice_listening); + mImage.setImageDrawable(mSpeakNow.get(0)); + mButtonText.setText(mContext.getText(R.string.cancel)); + } + }); + mUiHandler.postDelayed(mUpdateVolumeRunnable, 50); + } + + public void updateVoiceMeter(final float rmsdB) { + mVolume = rmsdB; + } + + public void showError(final String message) { + mState = State.READY; + mUiHandler.post(new Runnable() { + public void run() { + exitWorking(); + mText.setText(message); + mImage.setImageDrawable(mError); + mButtonText.setText(mContext.getText(R.string.ok)); + } + }); + } + + public void showWorking( + final ByteArrayOutputStream waveBuffer, + final int speechStartPosition, + final int speechEndPosition) { + + mState = State.WORKING; + + mUiHandler.post(new Runnable() { + public void run() { + mText.setText(R.string.voice_working); + mImage.setVisibility(View.GONE); + mProgress.setVisibility(View.VISIBLE); + final ShortBuffer buf = ByteBuffer.wrap(waveBuffer.toByteArray()) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + buf.position(0); + waveBuffer.reset(); + showWave(buf, speechStartPosition / 2, speechEndPosition / 2); + } + }); + } + + /** + * @return an average abs of the specified buffer. + */ + private static int getAverageAbs(ShortBuffer buffer, int start, int i, int npw) { + int from = start + i * npw; + int end = from + npw; + int total = 0; + for (int x = from; x < end; x++) { + total += Math.abs(buffer.get(x)); + } + return total / npw; + } + + + /** + * Shows waveform of input audio. + * + * Copied from version in VoiceSearch's RecognitionActivity. + * + * TODO: adjust stroke width based on the size of data. + * TODO: use dip rather than pixels. + */ + private void showWave(ShortBuffer waveBuffer, int startPosition, int endPosition) { + final int w = ((View) mImage.getParent()).getWidth(); + final int h = mImage.getHeight(); + if (w <= 0 || h <= 0) { + // view is not visible this time. Skip drawing. + return; + } + final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + final Canvas c = new Canvas(b); + final Paint paint = new Paint(); + paint.setColor(0xFFFFFFFF); // 0xAARRGGBB + paint.setAntiAlias(true); + paint.setStyle(Paint.Style.STROKE); + paint.setAlpha(0x90); + + final PathEffect effect = new CornerPathEffect(3); + paint.setPathEffect(effect); + + final int numSamples = waveBuffer.remaining(); + int endIndex; + if (endPosition == 0) { + endIndex = numSamples; + } else { + endIndex = Math.min(endPosition, numSamples); + } + + int startIndex = startPosition - 2000; // include 250ms before speech + if (startIndex < 0) { + startIndex = 0; + } + final int numSamplePerWave = 200; // 8KHz 25ms = 200 samples + final float scale = 10.0f / 65536.0f; + + final int count = (endIndex - startIndex) / numSamplePerWave; + final float deltaX = 1.0f * w / count; + int yMax = h / 2 - 10; + Path path = new Path(); + c.translate(0, yMax); + float x = 0; + path.moveTo(x, 0); + yMax -= 10; + for (int i = 0; i < count; i++) { + final int avabs = getAverageAbs(waveBuffer, startIndex, i , numSamplePerWave); + int sign = ( (i & 01) == 0) ? -1 : 1; + final float y = Math.min(yMax, avabs * h * scale) * sign; + path.lineTo(x, y); + x += deltaX; + path.lineTo(x, y); + } + if (deltaX > 4) { + paint.setStrokeWidth(3); + } else { + paint.setStrokeWidth(Math.max(1, (int) (deltaX -.05))); + } + c.drawPath(path, paint); + mImage.setImageBitmap(b); + mImage.setVisibility(View.VISIBLE); + MarginLayoutParams mProgressParams = (MarginLayoutParams)mProgress.getLayoutParams(); + mProgressParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + -h / 2 - 18, mContext.getResources().getDisplayMetrics()); + + // Tweak the padding manually to fill out the whole view horizontally. + // TODO: Do this in the xml layout instead. + ((View) mImage.getParent()).setPadding(4, ((View) mImage.getParent()).getPaddingTop(), 3, + ((View) mImage.getParent()).getPaddingBottom()); + mProgress.setLayoutParams(mProgressParams); + } + + + public void finish() { + mState = State.READY; + mUiHandler.post(new Runnable() { + public void run() { + exitWorking(); + } + }); + showStartState(); + } + + private void exitWorking() { + mProgress.setVisibility(View.GONE); + mImage.setVisibility(View.VISIBLE); + } +} diff --git a/src/com/android/inputmethod/voice/VoiceInput.java b/src/com/android/inputmethod/voice/VoiceInput.java new file mode 100644 index 000000000..2f45b654a --- /dev/null +++ b/src/com/android/inputmethod/voice/VoiceInput.java @@ -0,0 +1,551 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; +import android.speech.IRecognitionListener; +import android.speech.RecognitionServiceUtil; +import android.speech.RecognizerIntent; +import android.speech.RecognitionResult; +import android.view.View; +import android.view.View.OnClickListener; +import com.android.inputmethod.latin.R; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Speech recognition input, including both user interface and a background + * process to stream audio to the network recognizer. This class supplies a + * View (getView()), which it updates as recognition occurs. The user of this + * class is responsible for making the view visible to the user, as well as + * handling various events returned through UiListener. + */ +public class VoiceInput implements OnClickListener { + private static final String TAG = "VoiceInput"; + private static final String EXTRA_RECOGNITION_CONTEXT = + "android.speech.extras.RECOGNITION_CONTEXT"; + private static final String EXTRA_CALLING_PACKAGE = "calling_package"; + + private static final String DEFAULT_RECOMMENDED_PACKAGES = + "com.android.mms " + + "com.google.android.gm " + + "com.google.android.talk " + + "com.google.android.apps.googlevoice " + + "com.android.email " + + "com.android.browser "; + + // WARNING! Before enabling this, fix the problem with calling getExtractedText() in + // landscape view. It causes Extracted text updates to be rejected due to a token mismatch + public static boolean ENABLE_WORD_CORRECTIONS = false; + + private static Boolean sVoiceIsAvailable = null; + + // Dummy word suggestion which means "delete current word" + public static final String DELETE_SYMBOL = " \u00D7 "; // times symbol + + private Whitelist mRecommendedList; + private Whitelist mBlacklist; + + private VoiceInputLogger mLogger; + + // Names of a few intent extras defined in VoiceSearch's RecognitionService. + // These let us tweak the endpointer parameters. + private static final String EXTRA_SPEECH_MINIMUM_LENGTH_MILLIS = + "android.speech.extras.SPEECH_INPUT_MINIMUM_LENGTH_MILLIS"; + private static final String EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS = + "android.speech.extras.SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS"; + private static final String EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS = + "android.speech.extras.SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS"; + + // The usual endpointer default value for input complete silence length is 0.5 seconds, + // but that's used for things like voice search. For dictation-like voice input like this, + // we go with a more liberal value of 1 second. This value will only be used if a value + // is not provided from Gservices. + private static final String INPUT_COMPLETE_SILENCE_LENGTH_DEFAULT_VALUE_MILLIS = "1000"; + + // Used to record part of that state for logging purposes. + public static final int DEFAULT = 0; + public static final int LISTENING = 1; + public static final int WORKING = 2; + public static final int ERROR = 3; + + private int mState = DEFAULT; + + /** + * Events relating to the recognition UI. You must implement these. + */ + public interface UiListener { + + /** + * @param recognitionResults a set of transcripts for what the user + * spoke, sorted by likelihood. + */ + public void onVoiceResults( + List recognitionResults, + Map> alternatives); + + /** + * Called when the user cancels speech recognition. + */ + public void onCancelVoice(); + } + + private RecognitionServiceUtil.Connection mRecognitionConnection; + private IRecognitionListener mRecognitionListener; + private RecognitionView mRecognitionView; + private UiListener mUiListener; + private Context mContext; + private ScheduledThreadPoolExecutor mExecutor; + + /** + * @param context the service or activity in which we're runing. + * @param uiHandler object to receive events from VoiceInput. + */ + public VoiceInput(Context context, UiListener uiHandler) { + mLogger = VoiceInputLogger.getLogger(context); + mRecognitionListener = new IMERecognitionListener(); + mRecognitionConnection = new RecognitionServiceUtil.Connection() { + public synchronized void onServiceConnected( + ComponentName name, IBinder service) { + super.onServiceConnected(name, service); + } + }; + mUiListener = uiHandler; + mContext = context; + newView(); + + String recommendedPackages = GoogleSettingsUtil.getGservicesString( + context.getContentResolver(), + GoogleSettingsUtil.LATIN_IME_VOICE_INPUT_RECOMMENDED_PACKAGES, + DEFAULT_RECOMMENDED_PACKAGES); + + mRecommendedList = new Whitelist(); + for (String recommendedPackage : recommendedPackages.split("\\s+")) { + mRecommendedList.addApp(recommendedPackage); + } + + mBlacklist = new Whitelist(); + mBlacklist.addApp("com.android.setupwizard"); + + mExecutor = new ScheduledThreadPoolExecutor(1); + bindIfNecessary(); + } + + /** + * @return true if field is blacklisted for voice + */ + public boolean isBlacklistedField(FieldContext context) { + return mBlacklist.matches(context); + } + + /** + * Used to decide whether to show voice input hints for this field, etc. + * + * @return true if field is recommended for voice + */ + public boolean isRecommendedField(FieldContext context) { + return mRecommendedList.matches(context); + } + + /** + * @return true if the speech service is available on the platform. + */ + public static boolean voiceIsAvailable(Context context) { + if (sVoiceIsAvailable != null) { + return sVoiceIsAvailable; + } + + RecognitionServiceUtil.Connection recognitionConnection = + new RecognitionServiceUtil.Connection(); + boolean bound = context.bindService( + makeIntent(), recognitionConnection, Context.BIND_AUTO_CREATE); + context.unbindService(recognitionConnection); + sVoiceIsAvailable = bound; + return bound; + } + + /** + * Start listening for speech from the user. This will grab the microphone + * and start updating the view provided by getView(). It is the caller's + * responsibility to ensure that the view is visible to the user at this stage. + * + * @param context the same FieldContext supplied to voiceIsEnabled() + * @param swipe whether this voice input was started by swipe, for logging purposes + */ + public void startListening(FieldContext context, boolean swipe) { + mState = DEFAULT; + + Locale locale = Locale.getDefault(); + String localeString = locale.getLanguage() + "-" + locale.getCountry(); + + mLogger.start(localeString, swipe); + + mState = LISTENING; + + if (mRecognitionConnection.mService == null) { + mRecognitionView.showInitializing(); + } else { + mRecognitionView.showStartState(); + } + + if (!bindIfNecessary()) { + mState = ERROR; + + // We use CLIENT_ERROR to signify voice search is not available on the device. + onError(RecognitionResult.CLIENT_ERROR, false); + cancel(); + } + + if (mRecognitionConnection.mService != null) { + try { + Intent intent = makeIntent(); + intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, ""); + intent.putExtra(EXTRA_RECOGNITION_CONTEXT, context.getBundle()); + intent.putExtra(EXTRA_CALLING_PACKAGE, "VoiceIME"); + intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, + GoogleSettingsUtil.getGservicesInt( + mContext.getContentResolver(), + GoogleSettingsUtil.LATIN_IME_MAX_VOICE_RESULTS, + 1)); + + // Get endpointer params from Gservices. + // TODO: Consider caching these values for improved performance on slower devices. + ContentResolver cr = mContext.getContentResolver(); + putEndpointerExtra( + cr, + intent, + GoogleSettingsUtil.LATIN_IME_SPEECH_MINIMUM_LENGTH_MILLIS, + EXTRA_SPEECH_MINIMUM_LENGTH_MILLIS, + null /* rely on endpointer default */); + putEndpointerExtra( + cr, + intent, + GoogleSettingsUtil.LATIN_IME_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, + EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, + INPUT_COMPLETE_SILENCE_LENGTH_DEFAULT_VALUE_MILLIS + /* our default value is different from the endpointer's */); + putEndpointerExtra( + cr, + intent, + GoogleSettingsUtil. + LATIN_IME_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, + EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, + null /* rely on endpointer default */); + + mRecognitionConnection.mService.startListening( + intent, mRecognitionListener); + } catch (RemoteException e) { + Log.e(TAG, "Could not start listening", e); + onError(-1 /* no specific error, just show default error */, false); + } + } + } + + /** + * Gets the value of the provided Gservices key, attempts to parse it into a long, + * and if successful, puts the long value as an extra in the provided intent. + */ + private void putEndpointerExtra(ContentResolver cr, Intent i, + String gservicesKey, String intentExtraKey, String defaultValue) { + long l = -1; + String s = GoogleSettingsUtil.getGservicesString(cr, gservicesKey, defaultValue); + if (s != null) { + try { + l = Long.valueOf(s); + } catch (NumberFormatException e) { + Log.e(TAG, "could not parse value for " + gservicesKey + ": " + s); + } + } + + if (l != -1) i.putExtra(intentExtraKey, l); + } + + public void destroy() { + if (mRecognitionConnection.mService != null) { + //mContext.unbindService(mRecognitionConnection); + } + } + + /** + * Creates a new instance of the view that is returned by {@link #getView()} + * Clients should use this when a previously returned view is stuck in a + * layout that is being thrown away and a new one is need to show to the + * user. + */ + public void newView() { + mRecognitionView = new RecognitionView(mContext, this); + } + + /** + * @return a view that shows the recognition flow--e.g., "Speak now" and + * "working" dialogs. + */ + public View getView() { + return mRecognitionView.getView(); + } + + /** + * Handle the cancel button. + */ + public void onClick(View view) { + switch(view.getId()) { + case R.id.button: + cancel(); + break; + } + } + + public void logTextModified() { + mLogger.textModified(); + } + + public void logKeyboardWarningDialogShown() { + mLogger.keyboardWarningDialogShown(); + } + + public void logKeyboardWarningDialogDismissed() { + mLogger.keyboardWarningDialogDismissed(); + } + + public void logKeyboardWarningDialogOk() { + mLogger.keyboardWarningDialogOk(); + } + + public void logKeyboardWarningDialogCancel() { + mLogger.keyboardWarningDialogCancel(); + } + + public void logSwipeHintDisplayed() { + mLogger.swipeHintDisplayed(); + } + + public void logPunctuationHintDisplayed() { + mLogger.punctuationHintDisplayed(); + } + + public void logVoiceInputDelivered() { + mLogger.voiceInputDelivered(); + } + + public void logNBestChoose(int index) { + mLogger.nBestChoose(index); + } + + public void logInputEnded() { + mLogger.inputEnded(); + } + + public void flushLogs() { + mLogger.flush(); + } + + private static Intent makeIntent() { + Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); + + // On Cupcake, use VoiceIMEHelper since VoiceSearch doesn't support. + // On Donut, always use VoiceSearch, since VoiceIMEHelper and + // VoiceSearch may conflict. + if (Build.VERSION.RELEASE.equals("1.5")) { + intent = intent.setClassName( + "com.google.android.voiceservice", + "com.google.android.voiceservice.IMERecognitionService"); + } else { + intent = intent.setClassName( + "com.google.android.voicesearch", + "com.google.android.voicesearch.RecognitionService"); + } + + return intent; + } + + /** + * Bind to the recognition service if necessary. + * @return true if we are bound or binding to the service, false if + * the recognition service is unavailable. + */ + private boolean bindIfNecessary() { + if (mRecognitionConnection.mService != null) { + return true; + } + return mContext.bindService( + makeIntent(), mRecognitionConnection, Context.BIND_AUTO_CREATE); + } + + /** + * Cancel in-progress speech recognition. + */ + public void cancel() { + switch (mState) { + case LISTENING: + mLogger.cancelDuringListening(); + break; + case WORKING: + mLogger.cancelDuringWorking(); + break; + case ERROR: + mLogger.cancelDuringError(); + break; + } + mState = DEFAULT; + + // Remove all pending tasks (e.g., timers to cancel voice input) + for (Runnable runnable : mExecutor.getQueue()) { + mExecutor.remove(runnable); + } + + if (mRecognitionConnection.mService != null) { + try { + mRecognitionConnection.mService.cancel(); + } catch (RemoteException e) { + Log.e(TAG, "Exception on cancel", e); + } + } + mUiListener.onCancelVoice(); + mRecognitionView.finish(); + } + + private int getErrorStringId(int errorType, boolean endpointed) { + switch (errorType) { + // We use CLIENT_ERROR to signify that voice search is not available on the device. + case RecognitionResult.CLIENT_ERROR: + return R.string.voice_not_installed; + case RecognitionResult.NETWORK_ERROR: + return R.string.voice_network_error; + case RecognitionResult.NETWORK_TIMEOUT: + return endpointed ? + R.string.voice_network_error : R.string.voice_too_much_speech; + case RecognitionResult.AUDIO_ERROR: + return R.string.voice_audio_error; + case RecognitionResult.SERVER_ERROR: + return R.string.voice_server_error; + case RecognitionResult.SPEECH_TIMEOUT: + return R.string.voice_speech_timeout; + case RecognitionResult.NO_MATCH: + return R.string.voice_no_match; + default: return R.string.voice_error; + } + } + + private void onError(int errorType, boolean endpointed) { + Log.i(TAG, "error " + errorType); + mLogger.error(errorType); + onError(mContext.getString(getErrorStringId(errorType, endpointed))); + } + + private void onError(String error) { + mState = ERROR; + mRecognitionView.showError(error); + // Wait a couple seconds and then automatically dismiss message. + mExecutor.schedule(new Runnable() { + public void run() { + cancel(); + }}, 2000, TimeUnit.MILLISECONDS); + } + + private class IMERecognitionListener extends IRecognitionListener.Stub { + // Waveform data + final ByteArrayOutputStream mWaveBuffer = new ByteArrayOutputStream(); + int mSpeechStart; + private boolean mEndpointed = false; + + public void onReadyForSpeech(Bundle noiseParams) { + mRecognitionView.showListening(); + } + + public void onBeginningOfSpeech() { + mEndpointed = false; + mSpeechStart = mWaveBuffer.size(); + } + + public void onRmsChanged(float rmsdB) { + mRecognitionView.updateVoiceMeter(rmsdB); + } + + public void onBufferReceived(byte[] buf) { + try { + mWaveBuffer.write(buf); + } catch (IOException e) {} + } + + public void onEndOfSpeech() { + mEndpointed = true; + mState = WORKING; + mRecognitionView.showWorking(mWaveBuffer, mSpeechStart, mWaveBuffer.size()); + } + + public void onError(int errorType) { + mState = ERROR; + VoiceInput.this.onError(errorType, mEndpointed); + } + + public void onResults(List results, long token) { + mState = DEFAULT; + List resultsAsText = new ArrayList(); + for (RecognitionResult result : results) { + resultsAsText.add(result.mText); + } + + Map> alternatives = + new HashMap>(); + if (resultsAsText.size() >= 2 && ENABLE_WORD_CORRECTIONS) { + String[][] words = new String[resultsAsText.size()][]; + for (int i = 0; i < words.length; i++) { + words[i] = resultsAsText.get(i).split(" "); + } + + for (int key = 0; key < words[0].length; key++) { + alternatives.put(words[0][key], new ArrayList()); + for (int alt = 1; alt < words.length; alt++) { + int keyBegin = key * words[alt].length / words[0].length; + int keyEnd = (key + 1) * words[alt].length / words[0].length; + + for (int i = keyBegin; i < Math.min(words[alt].length, keyEnd); i++) { + List altList = alternatives.get(words[0][key]); + if (!altList.contains(words[alt][i]) && altList.size() < 6) { + altList.add(words[alt][i]); + } + } + } + } + } + + if (resultsAsText.size() > 5) { + resultsAsText = resultsAsText.subList(0, 5); + } + mUiListener.onVoiceResults(resultsAsText, alternatives); + mRecognitionView.finish(); + + destroy(); + } + } +} diff --git a/src/com/android/inputmethod/voice/VoiceInputLogger.java b/src/com/android/inputmethod/voice/VoiceInputLogger.java new file mode 100644 index 000000000..07d4d1c8c --- /dev/null +++ b/src/com/android/inputmethod/voice/VoiceInputLogger.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.content.Context; +import android.content.Intent; + +/** + * Provides the logging facility for voice input events. This fires broadcasts back to + * the voice search app which then logs on our behalf. + * + * Note that debug console logging does not occur in this class. If you want to + * see console output of these logging events, there is a boolean switch to turn + * on on the VoiceSearch side. + */ +public class VoiceInputLogger { + private static final String TAG = VoiceInputLogger.class.getSimpleName(); + + private static VoiceInputLogger sVoiceInputLogger; + + private final Context mContext; + + // The base intent used to form all broadcast intents to the logger + // in VoiceSearch. + private final Intent mBaseIntent; + + /** + * Returns the singleton of the logger. + * + * @param contextHint a hint context used when creating the logger instance. + * Ignored if the singleton instance already exists. + */ + public static synchronized VoiceInputLogger getLogger(Context contextHint) { + if (sVoiceInputLogger == null) { + sVoiceInputLogger = new VoiceInputLogger(contextHint); + } + return sVoiceInputLogger; + } + + public VoiceInputLogger(Context context) { + mContext = context; + + mBaseIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT); + mBaseIntent.putExtra(LoggingEvents.EXTRA_APP_NAME, LoggingEvents.VoiceIme.APP_NAME); + } + + private Intent newLoggingBroadcast(int event) { + Intent i = new Intent(mBaseIntent); + i.putExtra(LoggingEvents.EXTRA_EVENT, event); + return i; + } + + public void flush() { + Intent i = new Intent(mBaseIntent); + i.putExtra(LoggingEvents.EXTRA_FLUSH, true); + mContext.sendBroadcast(i); + } + + public void keyboardWarningDialogShown() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_SHOWN)); + } + + public void keyboardWarningDialogDismissed() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_DISMISSED)); + } + + public void keyboardWarningDialogOk() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_OK)); + } + + public void keyboardWarningDialogCancel() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_CANCEL)); + } + + public void settingsWarningDialogShown() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_SHOWN)); + } + + public void settingsWarningDialogDismissed() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_DISMISSED)); + } + + public void settingsWarningDialogOk() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_OK)); + } + + public void settingsWarningDialogCancel() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_CANCEL)); + } + + public void swipeHintDisplayed() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.SWIPE_HINT_DISPLAYED)); + } + + public void cancelDuringListening() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_LISTENING)); + } + + public void cancelDuringWorking() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_WORKING)); + } + + public void cancelDuringError() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_ERROR)); + } + + public void punctuationHintDisplayed() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.PUNCTUATION_HINT_DISPLAYED)); + } + + public void error(int code) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.ERROR); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_ERROR_CODE, code); + mContext.sendBroadcast(i); + } + + public void start(String locale, boolean swipe) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.START); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_START_LOCALE, locale); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_START_SWIPE, swipe); + mContext.sendBroadcast(i); + } + + public void voiceInputDelivered() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.VOICE_INPUT_DELIVERED)); + } + + public void textModified() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED)); + } + + public void nBestChoose(int index) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.N_BEST_CHOOSE); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_N_BEST_CHOOSE_INDEX, index); + mContext.sendBroadcast(i); + } + + public void inputEnded() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.INPUT_ENDED)); + } + + public void voiceInputSettingEnabled() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.VOICE_INPUT_SETTING_ENABLED)); + } + + public void voiceInputSettingDisabled() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.VOICE_INPUT_SETTING_DISABLED)); + } +} diff --git a/src/com/android/inputmethod/voice/WaveformImage.java b/src/com/android/inputmethod/voice/WaveformImage.java new file mode 100644 index 000000000..08d87c8f3 --- /dev/null +++ b/src/com/android/inputmethod/voice/WaveformImage.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2008-2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; + +import java.io.ByteArrayOutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.ShortBuffer; + +/** + * Utility class to draw a waveform into a bitmap, given a byte array + * that represents the waveform as a sequence of 16-bit integers. + * Adapted from RecognitionActivity.java. + */ +public class WaveformImage { + private static final int SAMPLING_RATE = 8000; + + private WaveformImage() {} + + public static Bitmap drawWaveform( + ByteArrayOutputStream waveBuffer, int w, int h, int start, int end) { + final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + final Canvas c = new Canvas(b); + final Paint paint = new Paint(); + paint.setColor(0xFFFFFFFF); // 0xRRGGBBAA + paint.setAntiAlias(true); + paint.setStrokeWidth(0); + + final ShortBuffer buf = ByteBuffer + .wrap(waveBuffer.toByteArray()) + .order(ByteOrder.nativeOrder()) + .asShortBuffer(); + buf.position(0); + + final int numSamples = waveBuffer.size() / 2; + final int delay = (SAMPLING_RATE * 100 / 1000); + int endIndex = end / 2 + delay; + if (end == 0 || endIndex >= numSamples) { + endIndex = numSamples; + } + int index = start / 2 - delay; + if (index < 0) { + index = 0; + } + final int size = endIndex - index; + int numSamplePerPixel = 32; + int delta = size / (numSamplePerPixel * w); + if (delta == 0) { + numSamplePerPixel = size / w; + delta = 1; + } + + final float scale = 3.5f / 65536.0f; + // do one less column to make sure we won't read past + // the buffer. + try { + for (int i = 0; i < w - 1 ; i++) { + final float x = i; + for (int j = 0; j < numSamplePerPixel; j++) { + final short s = buf.get(index); + final float y = (h / 2) - (s * h * scale); + c.drawPoint(x, y, paint); + index += delta; + } + } + } catch (IndexOutOfBoundsException e) { + // this can happen, but we don't care + } + + return b; + } +} diff --git a/src/com/android/inputmethod/voice/Whitelist.java b/src/com/android/inputmethod/voice/Whitelist.java new file mode 100644 index 000000000..167b688ca --- /dev/null +++ b/src/com/android/inputmethod/voice/Whitelist.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.os.Bundle; +import java.util.ArrayList; +import java.util.List; + +/** + * A set of text fields where speech has been explicitly enabled. + */ +public class Whitelist { + private List mConditions; + + public Whitelist() { + mConditions = new ArrayList(); + } + + public Whitelist(List conditions) { + this.mConditions = conditions; + } + + public void addApp(String app) { + Bundle bundle = new Bundle(); + bundle.putString("packageName", app); + mConditions.add(bundle); + } + + /** + * @return true if the field is a member of the whitelist. + */ + public boolean matches(FieldContext context) { + for (Bundle condition : mConditions) { + if (matches(condition, context.getBundle())) { + return true; + } + } + return false; + } + + /** + * @return true of all values in condition are matched by a value + * in target. + */ + private boolean matches(Bundle condition, Bundle target) { + for (String key : condition.keySet()) { + if (!condition.getString(key).equals(target.getString(key))) { + return false; + } + } + return true; + } +} diff --git a/src/com/google/android/voicesearch/LatinIMEWithVoice.java b/src/com/google/android/voicesearch/LatinIMEWithVoice.java new file mode 100644 index 000000000..8a339d14a --- /dev/null +++ b/src/com/google/android/voicesearch/LatinIMEWithVoice.java @@ -0,0 +1,29 @@ +/* + * + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations under +* the License. +*/ + +package com.google.android.voicesearch; + +import android.content.Intent; + +import com.android.inputmethod.latin.LatinIME; + +public class LatinIMEWithVoice extends LatinIME { + @Override + protected void launchSettings() { + launchSettings(LatinIMEWithVoiceSettings.class); + } +} diff --git a/src/com/google/android/voicesearch/LatinIMEWithVoiceSettings.java b/src/com/google/android/voicesearch/LatinIMEWithVoiceSettings.java new file mode 100644 index 000000000..a53cebfd9 --- /dev/null +++ b/src/com/google/android/voicesearch/LatinIMEWithVoiceSettings.java @@ -0,0 +1,5 @@ +package com.google.android.voicesearch; + +import com.android.inputmethod.latin.LatinIMESettings; + +public class LatinIMEWithVoiceSettings extends LatinIMESettings {}