17898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project/* 27898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 37898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 47898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 57898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * you may not use this file except in compliance with the License. 67898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * You may obtain a copy of the License at 77898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 87898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 97898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * See the License for the specific language governing permissions and 147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * limitations under the License. 157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectpackage com.android.inputmethod.pinyin; 187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.content.Context; 207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.content.res.Resources; 217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.inputmethodservice.InputMethodService; 227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.os.Handler; 237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.os.SystemClock; 247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.os.SystemProperties; 257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.util.AttributeSet; 267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.GestureDetector; 277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.Gravity; 287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.MotionEvent; 297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.View; 307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.View.OnTouchListener; 317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.widget.PopupWindow; 327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.widget.RelativeLayout; 337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.widget.ViewFlipper; 347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project/** 367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The top container to host soft keyboard view(s). 377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectpublic class SkbContainer extends RelativeLayout implements OnTouchListener { 397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * For finger touch, user tends to press the bottom part of the target key, 417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * or he/she even presses the area out of it, so it is necessary to make a 427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * simple bias correction. If the input method runs on emulator, no bias 437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * correction will be used. 447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private static final int Y_BIAS_CORRECTION = -10; 467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Used to skip these move events whose position is too close to the 497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * previous touch events. 507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private static final int MOVE_TOLERANCE = 6; 527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * If this member is true, PopupWindow is used to show on-key highlight 557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * effect. 567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private static boolean POPUPWINDOW_FOR_PRESSED_UI = false; 587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The current soft keyboard layout. 617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * @see com.android.inputmethod.pinyin.InputModeSwitcher for detailed layout 637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * definitions. 647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mSkbLayout = 0; 667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The input method service. 697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private InputMethodService mService; 717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Input mode switcher used to switch between different modes like Chinese, 747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * English, etc. 757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private InputModeSwitcher mInputModeSwitcher; 777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The gesture detector. 807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private GestureDetector mGestureDetector; 827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private Environment mEnvironment; 847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private ViewFlipper mSkbFlipper; 867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The popup balloon hint for key press/release. 897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private BalloonHint mBalloonPopup; 917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The on-key balloon hint for key press/release. 947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private BalloonHint mBalloonOnKey = null; 967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** The major sub soft keyboard. */ 987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private SoftKeyboardView mMajorView; 997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The last parameter when function {@link #toggleCandidateMode(boolean)} 1027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * was called. 1037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private boolean mLastCandidatesShowing; 1057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** Used to indicate whether a popup soft keyboard is shown. */ 1077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private boolean mPopupSkbShow = false; 1087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Used to indicate whether a popup soft keyboard is just shown, and waits 1117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * for the touch event to release. After the release, the popup window can 1127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * response to touch events. 1137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project **/ 1147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private boolean mPopupSkbNoResponse = false; 1157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** Popup sub keyboard. */ 1177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private PopupWindow mPopupSkb; 1187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** The view of the popup sub soft keyboard. */ 1207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private SoftKeyboardView mPopupSkbView; 1217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mPopupX; 1237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mPopupY; 1257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * When user presses a key, a timer is started, when it times out, it is 1287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * necessary to detect whether user still holds the key. 1297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private volatile boolean mWaitForTouchUp = false; 1317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * When user drags on the soft keyboard and the distance is enough, this 1347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * drag will be recognized as a gesture and a gesture-based action will be 1357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * taken, in this situation, ignore the consequent events. 1367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private volatile boolean mDiscardEvent = false; 1387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * For finger touch, user tends to press the bottom part of the target key, 1417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * or he/she even presses the area out of it, so it is necessary to make a 1427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * simple bias correction in Y. 1437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mYBiasCorrection = 0; 1457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The x coordination of the last touch event. 1487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mXLast; 1507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The y coordination of the last touch event. 1537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mYLast; 1557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The soft keyboard view. 1587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private SoftKeyboardView mSkv; 1607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The position of the soft keyboard view in the container. 1637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mSkvPosInContainer[] = new int[2]; 1657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The key pressed by user. 1687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private SoftKey mSoftKeyDown = null; 1707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Used to timeout a press if user holds the key for a long time. 1737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private LongPressTimer mLongPressTimer; 1757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * For temporary use. 1787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mXyPosTmp[] = new int[2]; 1807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public SkbContainer(Context context, AttributeSet attrs) { 1827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project super(context, attrs); 1837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mEnvironment = Environment.getInstance(); 1857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mLongPressTimer = new LongPressTimer(this); 1877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // If it runs on an emulator, no bias correction 1897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if ("1".equals(SystemProperties.get("ro.kernel.qemu"))) { 1907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mYBiasCorrection = 0; 1917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 1927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mYBiasCorrection = Y_BIAS_CORRECTION; 1937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonPopup = new BalloonHint(context, this, MeasureSpec.AT_MOST); 1957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (POPUPWINDOW_FOR_PRESSED_UI) { 1967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonOnKey = new BalloonHint(context, this, MeasureSpec.AT_MOST); 1977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkb = new PopupWindow(mContext); 2007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkb.setBackgroundDrawable(null); 2017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkb.setClippingEnabled(false); 2027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void setService(InputMethodService service) { 2057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mService = service; 2067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void setInputModeSwitcher(InputModeSwitcher inputModeSwitcher) { 2097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mInputModeSwitcher = inputModeSwitcher; 2107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void setGestureDetector(GestureDetector gestureDetector) { 2137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mGestureDetector = gestureDetector; 2147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public boolean isCurrentSkbSticky() { 2177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == mMajorView) return true; 2187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SoftKeyboard skb = mMajorView.getSoftKeyboard(); 2197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null != skb) { 2207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return skb.getStickyFlag(); 2217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 2237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void toggleCandidateMode(boolean candidatesShowing) { 2267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == mMajorView || !mInputModeSwitcher.isChineseText() 2277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project || mLastCandidatesShowing == candidatesShowing) return; 2287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mLastCandidatesShowing = candidatesShowing; 2297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SoftKeyboard skb = mMajorView.getSoftKeyboard(); 2317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == skb) return; 2327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int state = mInputModeSwitcher.getTooggleStateForCnCand(); 2347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (!candidatesShowing) { 2357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project skb.disableToggleState(state, false); 2367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project skb.enableToggleStates(mInputModeSwitcher.getToggleStates()); 2377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 2387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project skb.enableToggleState(state, false); 2397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mMajorView.invalidate(); 2427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void updateInputMode() { 2457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int skbLayout = mInputModeSwitcher.getSkbLayout(); 2467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mSkbLayout != skbLayout) { 2477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSkbLayout = skbLayout; 2487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project updateSkbLayout(); 2497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mLastCandidatesShowing = false; 2527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == mMajorView) return; 2547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SoftKeyboard skb = mMajorView.getSoftKeyboard(); 2567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == skb) return; 2577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project skb.enableToggleStates(mInputModeSwitcher.getToggleStates()); 2587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project invalidate(); 2597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return; 2607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private void updateSkbLayout() { 2637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int screenWidth = mEnvironment.getScreenWidth(); 2647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int keyHeight = mEnvironment.getKeyHeight(); 2657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int skbHeight = mEnvironment.getSkbHeight(); 2667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project Resources r = mContext.getResources(); 2687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == mSkbFlipper) { 2697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSkbFlipper = (ViewFlipper) findViewById(R.id.alpha_floatable); 2707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mMajorView = (SoftKeyboardView) mSkbFlipper.getChildAt(0); 2727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SoftKeyboard majorSkb = null; 2747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SkbPool skbPool = SkbPool.getInstance(); 2757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project switch (mSkbLayout) { 2777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case R.xml.skb_qwerty: 2787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project majorSkb = skbPool.getSoftKeyboard(R.xml.skb_qwerty, 2797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project R.xml.skb_qwerty, screenWidth, skbHeight, mContext); 2807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 2817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case R.xml.skb_sym1: 2837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym1, R.xml.skb_sym1, 2847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project screenWidth, skbHeight, mContext); 2857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 2867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case R.xml.skb_sym2: 2887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym2, R.xml.skb_sym2, 2897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project screenWidth, skbHeight, mContext); 2907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 2917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case R.xml.skb_smiley: 2937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project majorSkb = skbPool.getSoftKeyboard(R.xml.skb_smiley, 2947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project R.xml.skb_smiley, screenWidth, skbHeight, mContext); 2957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 2967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case R.xml.skb_phone: 2987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project majorSkb = skbPool.getSoftKeyboard(R.xml.skb_phone, 2997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project R.xml.skb_phone, screenWidth, skbHeight, mContext); 3007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 3017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project default: 3027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == majorSkb || !mMajorView.setSoftKeyboard(majorSkb)) { 3057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return; 3067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mMajorView.setBalloonHint(mBalloonOnKey, mBalloonPopup, false); 3087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mMajorView.invalidate(); 3097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private void responseKeyEvent(SoftKey sKey) { 3127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == sKey) return; 3137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project ((PinyinIME) mService).responseSoftKeyEvent(sKey); 3147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return; 3157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private SoftKeyboardView inKeyboardView(int x, int y, 3187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int positionInParent[]) { 3197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mPopupSkbShow) { 3207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mPopupX <= x && mPopupX + mPopupSkb.getWidth() > x 3217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project && mPopupY <= y && mPopupY + mPopupSkb.getHeight() > y) { 3227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project positionInParent[0] = mPopupX; 3237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project positionInParent[1] = mPopupY; 3247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkbView.setOffsetToSkbContainer(positionInParent); 3257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mPopupSkbView; 3267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return null; 3287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mMajorView; 3317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private void popupSymbols() { 3347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int popupResId = mSoftKeyDown.getPopupResId(); 3357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (popupResId > 0) { 3367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int skbContainerWidth = getWidth(); 3377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int skbContainerHeight = getHeight(); 3387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // The paddings of the background are not included. 3397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int miniSkbWidth = (int) (skbContainerWidth * 0.8); 3407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int miniSkbHeight = (int) (skbContainerHeight * 0.23); 3417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SkbPool skbPool = SkbPool.getInstance(); 3437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SoftKeyboard skb = skbPool.getSoftKeyboard(popupResId, popupResId, 3447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project miniSkbWidth, miniSkbHeight, mContext); 3457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == skb) return; 3467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupX = (skbContainerWidth - skb.getSkbTotalWidth()) / 2; 3487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupY = (skbContainerHeight - skb.getSkbTotalHeight()) / 2; 3497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == mPopupSkbView) { 3517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkbView = new SoftKeyboardView(mContext, null); 3527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkbView.onMeasure(LayoutParams.WRAP_CONTENT, 3537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project LayoutParams.WRAP_CONTENT); 3547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkbView.setOnTouchListener(this); 3567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkbView.setSoftKeyboard(skb); 3577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkbView.setBalloonHint(mBalloonOnKey, mBalloonPopup, true); 3587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkb.setContentView(mPopupSkbView); 3607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkb.setWidth(skb.getSkbCoreWidth() 3617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + mPopupSkbView.getPaddingLeft() 3627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + mPopupSkbView.getPaddingRight()); 3637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkb.setHeight(skb.getSkbCoreHeight() 3647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + mPopupSkbView.getPaddingTop() 3657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + mPopupSkbView.getPaddingBottom()); 3667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project getLocationInWindow(mXyPosTmp); 3687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkb.showAtLocation(this, Gravity.NO_GRAVITY, mPopupX, mPopupY 3697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + mXyPosTmp[1]); 3707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkbShow = true; 3717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkbNoResponse = true; 3727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Invalidate itself to dim the current soft keyboards. 3737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project dimSoftKeyboard(true); 3747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project resetKeyPress(0); 3757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private void dimSoftKeyboard(boolean dimSkb) { 3797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mMajorView.dimSoftKeyboard(dimSkb); 3807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private void dismissPopupSkb() { 3837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkb.dismiss(); 3847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkbShow = false; 3857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project dimSoftKeyboard(false); 3867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project resetKeyPress(0); 3877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private void resetKeyPress(long delay) { 3907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mLongPressTimer.removeTimer(); 3917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null != mSkv) { 3937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSkv.resetKeyPress(delay); 3947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public boolean handleBack(boolean realAction) { 3987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mPopupSkbShow) { 3997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (!realAction) return true; 4007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project dismissPopupSkb(); 4027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mDiscardEvent = true; 4037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 4047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 4067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void dismissPopups() { 4097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project handleBack(true); 4107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project resetKeyPress(0); 4117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project @Override 4147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 4157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project Environment env = Environment.getInstance(); 4167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int measuredWidth = env.getScreenWidth(); 4177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int measuredHeight = getPaddingTop(); 4187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project measuredHeight += env.getSkbHeight(); 4197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project widthMeasureSpec = MeasureSpec.makeMeasureSpec(measuredWidth, 4207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project MeasureSpec.EXACTLY); 4217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project heightMeasureSpec = MeasureSpec.makeMeasureSpec(measuredHeight, 4227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project MeasureSpec.EXACTLY); 4237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project super.onMeasure(widthMeasureSpec, heightMeasureSpec); 4247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project @Override 4277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 4287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project super.onTouchEvent(event); 4297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mSkbFlipper.isFlipping()) { 4317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project resetKeyPress(0); 4327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 4337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int x = (int) event.getX(); 4367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int y = (int) event.getY(); 4377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Bias correction 4387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project y = y + mYBiasCorrection; 4397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Ignore short-distance movement event to get better performance. 4417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (event.getAction() == MotionEvent.ACTION_MOVE) { 4427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (Math.abs(x - mXLast) <= MOVE_TOLERANCE 4437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project && Math.abs(y - mYLast) <= MOVE_TOLERANCE) { 4447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 4457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mXLast = x; 4497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mYLast = y; 4507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (!mPopupSkbShow) { 4527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mGestureDetector.onTouchEvent(event)) { 4537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project resetKeyPress(0); 4547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mDiscardEvent = true; 4557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 4567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project switch (event.getAction()) { 4607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case MotionEvent.ACTION_DOWN: 4617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project resetKeyPress(0); 4627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mWaitForTouchUp = true; 4647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mDiscardEvent = false; 4657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSkv = null; 4677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSoftKeyDown = null; 4687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSkv = inKeyboardView(x, y, mSkvPosInContainer); 4697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null != mSkv) { 4707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y 4717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project - mSkvPosInContainer[1], mLongPressTimer, false); 4727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 4747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case MotionEvent.ACTION_MOVE: 4767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) { 4777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 4787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mDiscardEvent) { 4807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project resetKeyPress(0); 4817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 4827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mPopupSkbShow && mPopupSkbNoResponse) { 4857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 4867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SoftKeyboardView skv = inKeyboardView(x, y, mSkvPosInContainer); 4897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null != skv) { 4907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (skv != mSkv) { 4917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSkv = skv; 4927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y 4937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project - mSkvPosInContainer[1], mLongPressTimer, true); 4947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (null != skv) { 4957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null != mSkv) { 4967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSoftKeyDown = mSkv.onKeyMove( 4977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project x - mSkvPosInContainer[0], y 4987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project - mSkvPosInContainer[1]); 4997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == mSoftKeyDown) { 5007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mDiscardEvent = true; 5017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 5067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case MotionEvent.ACTION_UP: 5087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mDiscardEvent) { 5097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project resetKeyPress(0); 5107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 5117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mWaitForTouchUp = false; 5147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // The view which got the {@link MotionEvent#ACTION_DOWN} event is 5167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // always used to handle this event. 5177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null != mSkv) { 5187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSkv.onKeyRelease(x - mSkvPosInContainer[0], y 5197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project - mSkvPosInContainer[1]); 5207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (!mPopupSkbShow || !mPopupSkbNoResponse) { 5237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project responseKeyEvent(mSoftKeyDown); 5247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mSkv == mPopupSkbView && !mPopupSkbNoResponse) { 5277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project dismissPopupSkb(); 5287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPopupSkbNoResponse = false; 5307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 5317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case MotionEvent.ACTION_CANCEL: 5337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 5347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null == mSkv) { 5377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 5387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 5417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Function for interface OnTouchListener, it is used to handle touch events 5447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // which will be delivered to the popup soft keyboard view. 5457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public boolean onTouch(View v, MotionEvent event) { 5467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Translate the event to fit to the container. 5477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project MotionEvent newEv = MotionEvent.obtain(event.getDownTime(), event 5487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project .getEventTime(), event.getAction(), event.getX() + mPopupX, 5497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project event.getY() + mPopupY, event.getPressure(), event.getSize(), 5507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project event.getMetaState(), event.getXPrecision(), event 5517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project .getYPrecision(), event.getDeviceId(), event 5527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project .getEdgeFlags()); 5537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project boolean ret = onTouchEvent(newEv); 5547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return ret; 5557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project class LongPressTimer extends Handler implements Runnable { 5587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 5597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * When user presses a key for a long time, the timeout interval to 5607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * generate first {@link #LONG_PRESS_KEYNUM1} key events. 5617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 5627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public static final int LONG_PRESS_TIMEOUT1 = 500; 5637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 5657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * When user presses a key for a long time, after the first 5667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * {@link #LONG_PRESS_KEYNUM1} key events, this timeout interval will be 5677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * used. 5687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 5697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private static final int LONG_PRESS_TIMEOUT2 = 100; 5707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 5727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * When user presses a key for a long time, after the first 5737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * {@link #LONG_PRESS_KEYNUM2} key events, this timeout interval will be 5747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * used. 5757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 5767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private static final int LONG_PRESS_TIMEOUT3 = 100; 5777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 5797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * When user presses a key for a long time, after the first 5807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * {@link #LONG_PRESS_KEYNUM1} key events, timeout interval 5817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * {@link #LONG_PRESS_TIMEOUT2} will be used instead. 5827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 5837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public static final int LONG_PRESS_KEYNUM1 = 1; 5847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 5867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * When user presses a key for a long time, after the first 5877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * {@link #LONG_PRESS_KEYNUM2} key events, timeout interval 5887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * {@link #LONG_PRESS_TIMEOUT3} will be used instead. 5897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 5907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public static final int LONG_PRESS_KEYNUM2 = 3; 5917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SkbContainer mSkbContainer; 5937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mResponseTimes = 0; 5957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public LongPressTimer(SkbContainer skbContainer) { 5977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSkbContainer = skbContainer; 5987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void startTimer() { 6017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project postAtTime(this, SystemClock.uptimeMillis() + LONG_PRESS_TIMEOUT1); 6027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mResponseTimes = 0; 6037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public boolean removeTimer() { 6067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project removeCallbacks(this); 6077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 6087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void run() { 6117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mWaitForTouchUp) { 6127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mResponseTimes++; 6137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mSoftKeyDown.repeatable()) { 6147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mSoftKeyDown.isUserDefKey()) { 6157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (1 == mResponseTimes) { 6167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mInputModeSwitcher 6177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project .tryHandleLongPressSwitch(mSoftKeyDown.mKeyCode)) { 6187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mDiscardEvent = true; 6197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project resetKeyPress(0); 6207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 6237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project responseKeyEvent(mSoftKeyDown); 6247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project long timeout; 6257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mResponseTimes < LONG_PRESS_KEYNUM1) { 6267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project timeout = LONG_PRESS_TIMEOUT1; 6277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (mResponseTimes < LONG_PRESS_KEYNUM2) { 6287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project timeout = LONG_PRESS_TIMEOUT2; 6297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 6307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project timeout = LONG_PRESS_TIMEOUT3; 6317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project postAtTime(this, SystemClock.uptimeMillis() + timeout); 6337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 6357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (1 == mResponseTimes) { 6367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project popupSymbols(); 6377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 643