private boolean disableSensorLocked(Sensor sensor) {
   for (ListenerDelegate i : sListeners) {
     if (i.hasSensor(sensor)) {
       // not an error, it's just that this sensor is still in use
       return true;
     }
   }
   String name = sensor.getName();
   int handle = sensor.getHandle();
   return sensors_enable_sensor(sQueue, name, handle, SENSOR_DISABLE);
 }
 private boolean enableSensorLocked(Sensor sensor, int delay) {
   boolean result = false;
   for (ListenerDelegate i : sListeners) {
     if (i.hasSensor(sensor)) {
       String name = sensor.getName();
       int handle = sensor.getHandle();
       result = sensors_enable_sensor(sQueue, name, handle, delay);
       break;
     }
   }
   return result;
 }
 /** @hide */
 @Override
 protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
   synchronized (sListeners) {
     final int size = sListeners.size();
     for (int i = 0; i < size; i++) {
       ListenerDelegate l = sListeners.get(i);
       if (l.getListener() == listener) {
         if (sensor == null) {
           sListeners.remove(i);
           // disable all sensors for this listener
           for (Sensor s : l.getSensors()) {
             disableSensorLocked(s);
           }
         } else if (l.removeSensor(sensor) == 0) {
           // if we have no more sensors enabled on this listener,
           // take it off the list.
           sListeners.remove(i);
           disableSensorLocked(sensor);
         }
         break;
       }
     }
   }
 }
  /** @hide */
  @Override
  protected boolean registerListenerImpl(
      SensorEventListener listener, Sensor sensor, int delay, Handler handler) {
    boolean result = true;
    synchronized (sListeners) {
      // look for this listener in our list
      ListenerDelegate l = null;
      for (ListenerDelegate i : sListeners) {
        if (i.getListener() == listener) {
          l = i;
          break;
        }
      }

      // if we don't find it, add it to the list
      if (l == null) {
        l = new ListenerDelegate(listener, sensor, handler);
        sListeners.add(l);
        // if the list is not empty, start our main thread
        if (!sListeners.isEmpty()) {
          if (sSensorThread.startLocked()) {
            if (!enableSensorLocked(sensor, delay)) {
              // oops. there was an error
              sListeners.remove(l);
              result = false;
            }
          } else {
            // there was an error, remove the listener
            sListeners.remove(l);
            result = false;
          }
        } else {
          // weird, we couldn't add the listener
          result = false;
        }
      } else if (!l.hasSensor(sensor)) {
        l.addSensor(sensor);
        if (!enableSensorLocked(sensor, delay)) {
          // oops. there was an error
          l.removeSensor(sensor);
          result = false;
        }
      }
    }

    return result;
  }
      public void run() {
        // Log.d(TAG, "entering main sensor thread");
        final float[] values = new float[3];
        final int[] status = new int[1];
        final long timestamp[] = new long[1];
        Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);

        if (!open()) {
          return;
        }

        synchronized (this) {
          // we've open the driver, we're ready to open the sensors
          mSensorsReady = true;
          this.notify();
        }

        while (true) {
          // wait for an event
          final int sensor = sensors_data_poll(sQueue, values, status, timestamp);
          long lastLoopMS = System.currentTimeMillis();
          long timeToSleep = SENSOR_LOOPMINMS;

          int accuracy = status[0];
          synchronized (sListeners) {
            if (sensor == -1 || sListeners.isEmpty()) {
              // we lost the connection to the event stream. this happens
              // when the last listener is removed or if there is an error
              if (sensor == -1 && !sListeners.isEmpty()) {
                // log a warning in case of abnormal termination
                Log.e(TAG, "_sensors_data_poll() failed, we bail out: sensors=" + sensor);
              }
              // we have no more listeners or polling failed, terminate the thread
              sensors_destroy_queue(sQueue);
              sQueue = 0;
              mThread = null;
              break;
            }
            final Sensor sensorObject = sHandleToSensor.get(sensor);

            if (sensorObject != null) {
              final float mag =
                  FloatMath.sqrt(
                      values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);
              if (Math.abs(mag - SensorManager.STANDARD_GRAVITY) > MAGNITUDE_THRESHOLD) {
                // report the sensor event to all listeners that
                // care about it.
                final int size = sListeners.size();
                for (int i = 0; i < size; i++) {
                  ListenerDelegate listener = sListeners.get(i);
                  if (listener.hasSensor(sensorObject)) {
                    // this is asynchronous (okay to call
                    // with sListeners lock held).
                    listener.onSensorChangedLocked(sensorObject, values, timestamp, accuracy);
                  }
                }
              }
            }
          }

          timeToSleep = SENSOR_LOOPMINMS - (System.currentTimeMillis() - lastLoopMS);
          lastLoopMS = System.currentTimeMillis();
          try {
            if (timeToSleep > 0) Thread.sleep(timeToSleep);
          } catch (InterruptedException e) {;
          }
        }
        // Log.d(TAG, "exiting main sensor thread");
      }