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");
      }