Android输入法之输入系统

来源:互联网 发布:淘宝网动漫口罩 编辑:程序博客网 时间:2024/04/29 10:35

 

 

Android通过 KeyInputQ在WindowMangerService中建立一个独立的线程InputDeviceReader,使用Native函数readEvent来读取Linux Driver的数据构建RawEvent,并放入到KeyQ消息队列中。

 

KeyInputQueue.java

 

Java代码
  1. Thread mThread = new Thread("InputDeviceReader") {  
  2.      public void run() {  
  3.          if (DEBUG) Log.v(TAG, "InputDeviceReader.run()");  
  4.          android.os.Process.setThreadPriority(  
  5.                  android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);  
  6.            
  7.          RawInputEvent ev = new RawInputEvent();  
  8.          while (true) {  
  9.              try {  
  10.                  InputDevice di;  
  11.   
  12.                  // block, doesn't release the monitor  
  13.                  readEvent(ev);  
  14.   
  15.                  boolean send = false;  
  16.                  boolean configChanged = false;  
  17.                    
  18.                  if (false) {  
  19.                      Log.i(TAG, "Input event: dev=0x"  
  20.                              + Integer.toHexString(ev.deviceId)  
  21.                              + " type=0x" + Integer.toHexString(ev.type)  
  22.                              + " scancode=" + ev.scancode  
  23.                              + " keycode=" + ev.keycode  
  24.                              + " value=" + ev.value);  
  25.                  }  
  26.                    
  27.                  if (ev.type == RawInputEvent.EV_DEVICE_ADDED) {  
  28.                      synchronized (mFirst) {  
  29.                          di = newInputDevice(ev.deviceId);  
  30.                          if (di.classes != 0) {  
  31.                              // If this device is some kind of input class,  
  32.                              // we care about it.  
  33.                              mDevices.put(ev.deviceId, di);  
  34.                              if ((di.classes & RawInputEvent.CLASS_TOUCHSCREEN) != 0) {  
  35.                                  readVirtualKeys(di.name);  
  36.                              }  
  37.                              // The configuration may have changed because  
  38.                              // of this device.  
  39.                              configChanged = true;  
  40.                          } else {  
  41.                              // We won't do anything with this device.  
  42.                              mIgnoredDevices.put(ev.deviceId, di);  
  43.                              Log.i(TAG, "Ignoring non-input device: id=0x"  
  44.                                      + Integer.toHexString(di.id)  
  45.                                      + ", name=" + di.name);  
  46.                          }  
  47.                      }  
  48.                  } else if (ev.type == RawInputEvent.EV_DEVICE_REMOVED) {  
  49.                      synchronized (mFirst) {  
  50.                          if (false) {  
  51.                              Log.i(TAG, "Device removed: id=0x"  
  52.                                      + Integer.toHexString(ev.deviceId));  
  53.                          }  
  54.                          di = mDevices.get(ev.deviceId);  
  55.                          if (di != null) {  
  56.                              mDevices.delete(ev.deviceId);  
  57.                              // The configuration may have changed because  
  58.                              // of this device.  
  59.                              configChanged = true;  
  60.                          } else if ((di=mIgnoredDevices.get(ev.deviceId)) != null) {  
  61.                              mIgnoredDevices.remove(ev.deviceId);  
  62.                          } else {  
  63.                              Log.w(TAG, "Removing bad device id: "  
  64.                                      + Integer.toHexString(ev.deviceId));  
  65.                              continue;  
  66.                          }  
  67.                      }  
  68.                  } else {  
  69.                      di = getInputDevice(ev.deviceId);  
  70.                      if (di == null) {  
  71.                          // This may be some junk from an ignored device.  
  72.                          continue;  
  73.                      }  
  74.                        
  75.                      // first crack at it  
  76.                      send = preprocessEvent(di, ev);  
  77.   
  78.                      if (ev.type == RawInputEvent.EV_KEY) {  
  79.                          di.mMetaKeysState = makeMetaState(ev.keycode,  
  80.                                  ev.value != 0, di.mMetaKeysState);  
  81.                          mHaveGlobalMetaState = false;  
  82.                      }  
  83.                  }  
  84.   
  85.                  if (configChanged) {  
  86.                      synchronized (mFirst) {  
  87.                          addLocked(di, System.nanoTime(), 0,  
  88.                                  RawInputEvent.CLASS_CONFIGURATION_CHANGED,  
  89.                                  null);  
  90.                      }  
  91.                  }  
  92.                    
  93.                  if (!send) {  
  94.                      continue;  
  95.                  }  
  96.                    
  97.                  synchronized (mFirst) {  
  98.                      // NOTE: The event timebase absolutely must be the same  
  99.                      // timebase as SystemClock.uptimeMillis().  
  100.                      //curTime = gotOne ? ev.when : SystemClock.uptimeMillis();  
  101.                      final long curTime = SystemClock.uptimeMillis();  
  102.                      final long curTimeNano = System.nanoTime();  
  103.                      //Log.i(TAG, "curTime=" + curTime + ", systemClock=" + SystemClock.uptimeMillis());  
  104.                        
  105.                      final int classes = di.classes;  
  106.                      final int type = ev.type;  
  107.                      final int scancode = ev.scancode;  
  108.                      send = false;  
  109.                        
  110.                      // Is it a key event?  
  111.                      if (type == RawInputEvent.EV_KEY &&  
  112.                              (classes&RawInputEvent.CLASS_KEYBOARD) != 0 &&  
  113.                              (scancode < RawInputEvent.BTN_FIRST ||  
  114.                                      scancode > RawInputEvent.BTN_LAST)) {  
  115.                          boolean down;  
  116.                          if (ev.value != 0) {  
  117.                              down = true;  
  118.                              di.mKeyDownTime = curTime;  
  119.                          } else {  
  120.                              down = false;  
  121.                          }  
  122.                          int keycode = rotateKeyCodeLocked(ev.keycode);  
  123.                          addLocked(di, curTimeNano, ev.flags,  
  124.                                  RawInputEvent.CLASS_KEYBOARD,  
  125.                                  newKeyEvent(di, di.mKeyDownTime, curTime, down,  
  126.                                          keycode, 0, scancode,  
  127.                                          ((ev.flags & WindowManagerPolicy.FLAG_WOKE_HERE) != 0)  
  128.                                           ? KeyEvent.FLAG_WOKE_HERE : 0));  
  129.                            
  130.                      } else if (ev.type == RawInputEvent.EV_KEY) {  
  131.                          // Single touch protocol: touch going down or up.  
  132.                          if (ev.scancode == RawInputEvent.BTN_TOUCH &&  
  133.                                  (classes&(RawInputEvent.CLASS_TOUCHSCREEN  
  134.                                          |RawInputEvent.CLASS_TOUCHSCREEN_MT))  
  135.                                          == RawInputEvent.CLASS_TOUCHSCREEN) {  
  136.                              di.mAbs.changed = true;  
  137.                              di.mAbs.mDown[0] = ev.value != 0;  
  138.                            
  139.                          // Trackball (mouse) protocol: press down or up.  
  140.                          } else if (ev.scancode == RawInputEvent.BTN_MOUSE &&  
  141.                                  (classes&RawInputEvent.CLASS_TRACKBALL) != 0) {  
  142.                              di.mRel.changed = true;  
  143.                              di.mRel.mNextNumPointers = ev.value != 0 ? 1 : 0;  
  144.                              send = true;  
  145.                          }  
  146.    
  147.                      // Process position events from multitouch protocol.  
  148.                      } else if (ev.type == RawInputEvent.EV_ABS &&  
  149.                              (classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) {  
  150.                          if (ev.scancode == RawInputEvent.ABS_MT_TOUCH_MAJOR) {  
  151.                              di.mAbs.changed = true;  
  152.                              di.mAbs.mNextData[di.mAbs.mAddingPointerOffset  
  153.                                      + MotionEvent.SAMPLE_PRESSURE] = ev.value;  
  154.                          } else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_X) {  
  155.                              di.mAbs.changed = true;  
  156.                              di.mAbs.mNextData[di.mAbs.mAddingPointerOffset  
  157.                                  + MotionEvent.SAMPLE_X] = ev.value;  
  158.                              if (DEBUG_POINTERS) Log.v(TAG, "MT @"  
  159.                                      + di.mAbs.mAddingPointerOffset  
  160.                                      + " X:" + ev.value);  
  161.                          } else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_Y) {  
  162.                              di.mAbs.changed = true;  
  163.                              di.mAbs.mNextData[di.mAbs.mAddingPointerOffset  
  164.                                  + MotionEvent.SAMPLE_Y] = ev.value;  
  165.                              if (DEBUG_POINTERS) Log.v(TAG, "MT @"  
  166.                                      + di.mAbs.mAddingPointerOffset  
  167.                                      + " Y:" + ev.value);  
  168.                          } else if (ev.scancode == RawInputEvent.ABS_MT_WIDTH_MAJOR) {  
  169.                              di.mAbs.changed = true;  
  170.                              di.mAbs.mNextData[di.mAbs.mAddingPointerOffset  
  171.                                  + MotionEvent.SAMPLE_SIZE] = ev.value;  
  172.                          }  
  173.                        
  174.                      // Process position events from single touch protocol.  
  175.                      } else if (ev.type == RawInputEvent.EV_ABS &&  
  176.                              (classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {  
  177.                          if (ev.scancode == RawInputEvent.ABS_X) {  
  178.                              di.mAbs.changed = true;  
  179.                              di.curTouchVals[MotionEvent.SAMPLE_X] = ev.value;  
  180.                          } else if (ev.scancode == RawInputEvent.ABS_Y) {  
  181.                              di.mAbs.changed = true;  
  182.                              di.curTouchVals[MotionEvent.SAMPLE_Y] = ev.value;  
  183.                          } else if (ev.scancode == RawInputEvent.ABS_PRESSURE) {  
  184.                              di.mAbs.changed = true;  
  185.                              di.curTouchVals[MotionEvent.SAMPLE_PRESSURE] = ev.value;  
  186.                              di.curTouchVals[MotionEvent.NUM_SAMPLE_DATA  
  187.                                               + MotionEvent.SAMPLE_PRESSURE] = ev.value;  
  188.                          } else if (ev.scancode == RawInputEvent.ABS_TOOL_WIDTH) {  
  189.                              di.mAbs.changed = true;  
  190.                              di.curTouchVals[MotionEvent.SAMPLE_SIZE] = ev.value;  
  191.                              di.curTouchVals[MotionEvent.NUM_SAMPLE_DATA  
  192.                                               + MotionEvent.SAMPLE_SIZE] = ev.value;  
  193.                          }  
  194.    
  195.                      // Process movement events from trackball (mouse) protocol.  
  196.                      } else if (ev.type == RawInputEvent.EV_REL &&  
  197.                              (classes&RawInputEvent.CLASS_TRACKBALL) != 0) {  
  198.                          // Add this relative movement into our totals.  
  199.                          if (ev.scancode == RawInputEvent.REL_X) {  
  200.                              di.mRel.changed = true;  
  201.                              di.mRel.mNextData[MotionEvent.SAMPLE_X] += ev.value;  
  202.                          } else if (ev.scancode == RawInputEvent.REL_Y) {  
  203.                              di.mRel.changed = true;  
  204.                              di.mRel.mNextData[MotionEvent.SAMPLE_Y] += ev.value;  
  205.                          }  
  206.                      }  
  207.                        
  208.                      // Handle multitouch protocol sync: tells us that the  
  209.                      // driver has returned all data for -one- of the pointers  
  210.                      // that is currently down.  
  211.                      if (ev.type == RawInputEvent.EV_SYN  
  212.                              && ev.scancode == RawInputEvent.SYN_MT_REPORT  
  213.                              && di.mAbs != null) {  
  214.                          di.mAbs.changed = true;  
  215.                          if (di.mAbs.mNextData[MotionEvent.SAMPLE_PRESSURE] > 0) {  
  216.                              // If the value is <= 0, the pointer is not  
  217.                              // down, so keep it in the count.  
  218.                                
  219.                              if (di.mAbs.mNextData[di.mAbs.mAddingPointerOffset  
  220.                                                    + MotionEvent.SAMPLE_PRESSURE] != 0) {  
  221.                                  final int num = di.mAbs.mNextNumPointers+1;  
  222.                                  di.mAbs.mNextNumPointers = num;  
  223.                                  if (DEBUG_POINTERS) Log.v(TAG,  
  224.                                          "MT_REPORT: now have " + num + " pointers");  
  225.                                  final int newOffset = (num <= InputDevice.MAX_POINTERS)  
  226.                                          ? (num * MotionEvent.NUM_SAMPLE_DATA)  
  227.                                          : (InputDevice.MAX_POINTERS *  
  228.                                                  MotionEvent.NUM_SAMPLE_DATA);  
  229.                                  di.mAbs.mAddingPointerOffset = newOffset;  
  230.                                  di.mAbs.mNextData[newOffset  
  231.                                          + MotionEvent.SAMPLE_PRESSURE] = 0;  
  232.                              } else {  
  233.                                  if (DEBUG_POINTERS) Log.v(TAG, "MT_REPORT: no pointer");  
  234.                              }  
  235.                          }  
  236.                        
  237.                      // Handle general event sync: all data for the current  
  238.                      // event update has been delivered.  
  239.                      } else if (send || (ev.type == RawInputEvent.EV_SYN  
  240.                              && ev.scancode == RawInputEvent.SYN_REPORT)) {  
  241.                          if (mDisplay != null) {  
  242.                              if (!mHaveGlobalMetaState) {  
  243.                                  computeGlobalMetaStateLocked();  
  244.                              }  
  245.                                
  246.                              MotionEvent me;  
  247.                                
  248.                              InputDevice.MotionState ms = di.mAbs;  
  249.                              if (ms.changed) {  
  250.                                  ms.changed = false;  
  251.                                    
  252.                                  if ((classes&(RawInputEvent.CLASS_TOUCHSCREEN  
  253.                                          |RawInputEvent.CLASS_TOUCHSCREEN_MT))  
  254.                                          == RawInputEvent.CLASS_TOUCHSCREEN) {  
  255.                                      ms.mNextNumPointers = 0;  
  256.                                      if (ms.mDown[0]) {  
  257.                                          System.arraycopy(di.curTouchVals, 0,  
  258.                                                  ms.mNextData, 0,  
  259.                                                  MotionEvent.NUM_SAMPLE_DATA);  
  260.                                          ms.mNextNumPointers++;  
  261.                                      }  
  262.                                  }  
  263.                                    
  264.                                  if (BAD_TOUCH_HACK) {  
  265.                                      ms.dropBadPoint(di);  
  266.                                  }  
  267.                                    
  268.                                  boolean doMotion = !monitorVirtualKey(di,  
  269.                                          ev, curTime, curTimeNano);  
  270.                                    
  271.                                  if (doMotion && ms.mNextNumPointers > 0  
  272.                                          && (ms.mLastNumPointers == 0  
  273.                                                  || ms.mSkipLastPointers)) {  
  274.                                      doMotion = !generateVirtualKeyDown(di,  
  275.                                              ev, curTime, curTimeNano);  
  276.                                  }  
  277.                                    
  278.                                  if (doMotion) {  
  279.                                      // XXX Need to be able to generate  
  280.                                      // multiple events here, for example  
  281.                                      // if two fingers change up/down state  
  282.                                      // at the same time.  
  283.                                      do {  
  284.                                          me = ms.generateAbsMotion(di, curTime,  
  285.                                                  curTimeNano, mDisplay,  
  286.                                                  mOrientation, mGlobalMetaState);  
  287.                                          if (DEBUG_POINTERS) Log.v(TAG, "Absolute: x="  
  288.                                                  + di.mAbs.mNextData[MotionEvent.SAMPLE_X]  
  289.                                                  + " y="  
  290.                                                  + di.mAbs.mNextData[MotionEvent.SAMPLE_Y]  
  291.                                                  + " ev=" + me);  
  292.                                          if (me != null) {  
  293.                                              if (WindowManagerPolicy.WATCH_POINTER) {  
  294.                                                  Log.i(TAG, "Enqueueing: " + me);  
  295.                                              }  
  296.                                              addLocked(di, curTimeNano, ev.flags,  
  297.                                                      RawInputEvent.CLASS_TOUCHSCREEN, me);  
  298.                                          }  
  299.                                      } while (ms.hasMore());  
  300.                                  } else {  
  301.                                      // We are consuming movement in the  
  302.                                      // virtual key area...  but still  
  303.                                      // propagate this to the previous  
  304.                                      // data for comparisons.  
  305.                                      int num = ms.mNextNumPointers;  
  306.                                      if (num > InputDevice.MAX_POINTERS) {  
  307.                                          num = InputDevice.MAX_POINTERS;  
  308.                                      }  
  309.                                      System.arraycopy(ms.mNextData, 0,  
  310.                                              ms.mLastData, 0,  
  311.                                              num * MotionEvent.NUM_SAMPLE_DATA);  
  312.                                      ms.mLastNumPointers = num;  
  313.                                      ms.mSkipLastPointers = true;  
  314.                                  }  
  315.                                    
  316.                                  ms.finish();  
  317.                              }  
  318.                                
  319.                              ms = di.mRel;  
  320.                              if (ms.changed) {  
  321.                                  ms.changed = false;  
  322.                                    
  323.                                  me = ms.generateRelMotion(di, curTime,  
  324.                                          curTimeNano,  
  325.                                          mOrientation, mGlobalMetaState);  
  326.                                  if (false) Log.v(TAG, "Relative: x="  
  327.                                          + di.mRel.mNextData[MotionEvent.SAMPLE_X]  
  328.                                          + " y="  
  329.                                          + di.mRel.mNextData[MotionEvent.SAMPLE_Y]  
  330.                                          + " ev=" + me);  
  331.                                  if (me != null) {  
  332.                                      addLocked(di, curTimeNano, ev.flags,  
  333.                                              RawInputEvent.CLASS_TRACKBALL, me);  
  334.                                  }  
  335.                                    
  336.                                  ms.finish();  
  337.                              }  
  338.                          }  
  339.                      }  
  340.                  }  
  341.                
  342.              } catch (RuntimeException exc) {  
  343.                  Log.e(TAG, "InputReaderThread uncaught exception", exc);  
  344.              }  
  345.          }  
  346.      }  
  347.  };  

 

Java代码
  1. private static native boolean readEvent(RawInputEvent outEvent);  

 framworks.base.server.jni

Cpp代码
  1. static jboolean  
  2. android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz,  
  3.                                           jobject event)  
  4. {  
  5.     gLock.lock();  
  6.     sp<EventHub> hub = gHub;  
  7.     if (hub == NULL) {  
  8.         hub = new EventHub;  
  9.         gHub = hub;  
  10.     }  
  11.     gLock.unlock();  
  12.   
  13.     int32_t deviceId;  
  14.     int32_t type;  
  15.     int32_t scancode, keycode;  
  16.     uint32_t flags;  
  17.     int32_t value;  
  18.     nsecs_t when;  
  19.     bool res = hub->getEvent(&deviceId, &type, &scancode, &keycode,  
  20.             &flags, &value, &when);  
  21.   
  22.     env->SetIntField(event, gInputOffsets.mDeviceId, (jint)deviceId);  
  23.     env->SetIntField(event, gInputOffsets.mType, (jint)type);  
  24.     env->SetIntField(event, gInputOffsets.mScancode, (jint)scancode);  
  25.     env->SetIntField(event, gInputOffsets.mKeycode, (jint)keycode);  
  26.     env->SetIntField(event, gInputOffsets.mFlags, (jint)flags);  
  27.     env->SetIntField(event, gInputOffsets.mValue, value);  
  28.     env->SetLongField(event, gInputOffsets.mWhen,  
  29.                         (jlong)(nanoseconds_to_milliseconds(when)));  
  30.   
  31.     return res;  
  32. }  

 


InputDispatcherThread从KeyQ中读取Events,找到Window Manager中的Focus Window,通过Focus Window记录的mClient接口,将Events专递到Client端。Client端在根据自己的Focus Path传递事件,直到事件被处理。

 

Java代码
  1. private final class InputDispatcherThread extends Thread {  
  2.     // Time to wait when there is nothing to do: 9999 seconds.  
  3.     static final int LONG_WAIT=9999*1000;  
  4.   
  5.     public InputDispatcherThread() {  
  6.         super("InputDispatcher");  
  7.     }  
  8.   
  9.     @Override  
  10.     public void run() {  
  11.         while (true) {  
  12.             try {  
  13.                 process();  
  14.             } catch (Exception e) {  
  15.                 Log.e(TAG, "Exception in input dispatcher", e);  
  16.             }  
  17.         }  
  18.     }  
  19.   
  20.     private void process() {  
  21.         android.os.Process.setThreadPriority(  
  22.                 android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);  
  23.   
  24.         // The last key event we saw  
  25.         KeyEvent lastKey = null;  
  26.   
  27.         // Last keydown time for auto-repeating keys  
  28.         long lastKeyTime = SystemClock.uptimeMillis();  
  29.         long nextKeyTime = lastKeyTime+LONG_WAIT;  
  30.         long downTime = 0;  
  31.   
  32.         // How many successive repeats we generated  
  33.         int keyRepeatCount = 0;  
  34.   
  35.         // Need to report that configuration has changed?  
  36.         boolean configChanged = false;  
  37.   
  38.         while (true) {  
  39.             long curTime = SystemClock.uptimeMillis();  
  40.   
  41.             if (DEBUG_INPUT) Log.v(  
  42.                 TAG, "Waiting for next key: now=" + curTime  
  43.                 + ", repeat @ " + nextKeyTime);  
  44.   
  45.             // Retrieve next event, waiting only as long as the next  
  46.             // repeat timeout.  If the configuration has changed, then  
  47.             // don't wait at all -- we'll report the change as soon as  
  48.             // we have processed all events.  
  49.             QueuedEvent ev = mQueue.getEvent(  
  50.                 (int)((!configChanged && curTime < nextKeyTime)  
  51.                         ? (nextKeyTime-curTime) : 0));  
  52.   
  53.             if (DEBUG_INPUT && ev != null) Log.v(  
  54.                     TAG, "Event: type=" + ev.classType + " data=" + ev.event);  
  55.   
  56.             if (MEASURE_LATENCY) {  
  57.                 lt.sample("2 got event              ", System.nanoTime() - ev.whenNano);  
  58.             }  
  59.   
  60.             if (lastKey != null && !mPolicy.allowKeyRepeat()) {  
  61.                 // cancel key repeat at the request of the policy.  
  62.                 lastKey = null;  
  63.                 downTime = 0;  
  64.                 lastKeyTime = curTime;  
  65.                 nextKeyTime = curTime + LONG_WAIT;  
  66.             }  
  67.             try {  
  68.                 if (ev != null) {  
  69.                     curTime = SystemClock.uptimeMillis();  
  70.                     int eventType;  
  71.                     if (ev.classType == RawInputEvent.CLASS_TOUCHSCREEN) {  
  72.                         eventType = eventType((MotionEvent)ev.event);  
  73.                     } else if (ev.classType == RawInputEvent.CLASS_KEYBOARD ||  
  74.                                 ev.classType == RawInputEvent.CLASS_TRACKBALL) {  
  75.                         eventType = LocalPowerManager.BUTTON_EVENT;  
  76.                     } else {  
  77.                         eventType = LocalPowerManager.OTHER_EVENT;  
  78.                     }  
  79.                     try {  
  80.                         if ((curTime - mLastBatteryStatsCallTime)  
  81.                                 >= MIN_TIME_BETWEEN_USERACTIVITIES) {  
  82.                             mLastBatteryStatsCallTime = curTime;  
  83.                             mBatteryStats.noteInputEvent();  
  84.                         }  
  85.                     } catch (RemoteException e) {  
  86.                         // Ignore  
  87.                     }  
  88.   
  89.                     if (eventType != TOUCH_EVENT  
  90.                             && eventType != LONG_TOUCH_EVENT  
  91.                             && eventType != CHEEK_EVENT) {  
  92.                         mPowerManager.userActivity(curTime, false,  
  93.                                 eventType, false);  
  94.                     } else if (mLastTouchEventType != eventType  
  95.                             || (curTime - mLastUserActivityCallTime)  
  96.                             >= MIN_TIME_BETWEEN_USERACTIVITIES) {  
  97.                         mLastUserActivityCallTime = curTime;  
  98.                         mLastTouchEventType = eventType;  
  99.                         mPowerManager.userActivity(curTime, false,  
  100.                                 eventType, false);  
  101.                     }  
  102.   
  103.                     switch (ev.classType) {  
  104.                         case RawInputEvent.CLASS_KEYBOARD:  
  105.                             KeyEvent ke = (KeyEvent)ev.event;  
  106.                             if (ke.isDown()) {  
  107.                                 lastKey = ke;  
  108.                                 downTime = curTime;  
  109.                                 keyRepeatCount = 0;  
  110.                                 lastKeyTime = curTime;  
  111.                                 nextKeyTime = lastKeyTime  
  112.                                         + ViewConfiguration.getLongPressTimeout();  
  113.     //a21966,Creekside: if it is a SLIDER close event do not wait the key up event  
  114.                                 if (ke.getScanCode() == 254){  
  115.         lastKey = null;  
  116.     downTime = 0;  
  117.     lastKeyTime = curTime;  
  118.     nextKeyTime = curTime + LONG_WAIT;  
  119.     }     
  120.   
  121.                                 if (DEBUG_INPUT) Log.v(  
  122.                                     TAG, "Received key down: first repeat @ "  
  123.                                     + nextKeyTime);  
  124.                             } else {  
  125.                                 lastKey = null;  
  126.                                 downTime = 0;  
  127.                                 // Arbitrary long timeout.  
  128.                                 lastKeyTime = curTime;  
  129.                                 nextKeyTime = curTime + LONG_WAIT;  
  130.                                 if (DEBUG_INPUT) Log.v(  
  131.                                     TAG, "Received key up: ignore repeat @ "  
  132.                                     + nextKeyTime);  
  133.                             }  
  134.                             dispatchKey((KeyEvent)ev.event, 00);  
  135.                             mQueue.recycleEvent(ev);  
  136.                             break;  
  137.                         case RawInputEvent.CLASS_TOUCHSCREEN:  
  138.                             //Log.i(TAG, "Read next event " + ev);  
  139.                             dispatchPointer(ev, (MotionEvent)ev.event, 00);  
  140.                             break;  
  141.                         case RawInputEvent.CLASS_TRACKBALL:  
  142.                             dispatchTrackball(ev, (MotionEvent)ev.event, 00);  
  143.                             break;  
  144.                         case RawInputEvent.CLASS_CONFIGURATION_CHANGED:  
  145.                             configChanged = true;  
  146.                             break;  
  147.                         default:  
  148.                             mQueue.recycleEvent(ev);  
  149.                         break;  
  150.                     }  
  151.   
  152.                 } else if (configChanged) {  
  153.                     configChanged = false;  
  154.                     sendNewConfiguration();  
  155.   
  156.                 } else if (lastKey != null) {  
  157.                     curTime = SystemClock.uptimeMillis();  
  158.   
  159.                     // Timeout occurred while key was down.  If it is at or  
  160.                     // past the key repeat time, dispatch the repeat.  
  161.                     if (DEBUG_INPUT) Log.v(  
  162.                         TAG, "Key timeout: repeat=" + nextKeyTime  
  163.                         + ", now=" + curTime);  
  164.                     if (curTime < nextKeyTime) {  
  165.                         continue;  
  166.                     }  
  167.   
  168.                     lastKeyTime = nextKeyTime;  
  169.                     nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY;  
  170.                     keyRepeatCount++;  
  171.                     if (DEBUG_INPUT) Log.v(  
  172.                         TAG, "Key repeat: count=" + keyRepeatCount  
  173.                         + ", next @ " + nextKeyTime);  
  174.                     KeyEvent newEvent;  
  175.                     if (downTime != 0 && (downTime  
  176.                             + ViewConfiguration.getLongPressTimeout())  
  177.                             <= curTime) {  
  178.                         newEvent = KeyEvent.changeTimeRepeat(lastKey,  
  179.                                 curTime, keyRepeatCount,  
  180.                                 lastKey.getFlags() | KeyEvent.FLAG_LONG_PRESS);  
  181.                         downTime = 0;  
  182.                     } else {  
  183.                         newEvent = KeyEvent.changeTimeRepeat(lastKey,  
  184.                                 curTime, keyRepeatCount);  
  185.                     }  
  186.                     dispatchKey(newEvent, 00);  
  187.   
  188.                 } else {  
  189.                     curTime = SystemClock.uptimeMillis();  
  190.   
  191.                     lastKeyTime = curTime;  
  192.                     nextKeyTime = curTime + LONG_WAIT;  
  193.                 }  
  194.   
  195.             } catch (Exception e) {  
  196.                 Log.e(TAG,  
  197.                     "Input thread received uncaught exception: " + e, e);  
  198.             }  
  199.         }  
  200.     }  
  201. }  

 

 

 

http://waterlife.javaeye.com/blog/709885