@Override
 public void run() {
   mSensorChangedLed.blink();
 }
 @Override
 public void run() {
   mSensorReadLed.blink();
 }
  private void processValuesLocked() {
    boolean logOutlier = false;
    long dischargeDuration = 0;

    mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
    if (mBatteryProps.chargerAcOnline) {
      mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
    } else if (mBatteryProps.chargerUsbOnline) {
      mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
    } else if (mBatteryProps.chargerWirelessOnline) {
      mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
    } else {
      mPlugType = BATTERY_PLUGGED_NONE;
    }

    if (DEBUG) {
      Slog.d(
          TAG,
          "Processing new values: "
              + "chargerAcOnline="
              + mBatteryProps.chargerAcOnline
              + ", chargerUsbOnline="
              + mBatteryProps.chargerUsbOnline
              + ", chargerWirelessOnline="
              + mBatteryProps.chargerWirelessOnline
              + ", batteryStatus="
              + mBatteryProps.batteryStatus
              + ", batteryHealth="
              + mBatteryProps.batteryHealth
              + ", batteryPresent="
              + mBatteryProps.batteryPresent
              + ", batteryLevel="
              + mBatteryProps.batteryLevel
              + ", batteryTechnology="
              + mBatteryProps.batteryTechnology
              + ", batteryVoltage="
              + mBatteryProps.batteryVoltage
              + ", batteryCurrentNow="
              + mBatteryProps.batteryCurrentNow
              + ", batteryChargeCounter="
              + mBatteryProps.batteryChargeCounter
              + ", batteryTemperature="
              + mBatteryProps.batteryTemperature
              + ", mBatteryLevelCritical="
              + mBatteryLevelCritical
              + ", mPlugType="
              + mPlugType);
    }
    if (mLastBatteryVoltage != mBatteryProps.batteryVoltage) {
      Xlog.d(
          TAG,
          "mBatteryVoltage="
              + mBatteryProps.batteryVoltage
              + ", batteryLevel="
              + mBatteryProps.batteryLevel_2nd);
    }
    // Update the battery LED
    mLed.updateLightsLocked();

    // Let the battery stats keep track of the current level.
    try {
      mBatteryStats.setBatteryState(
          mBatteryProps.batteryStatus,
          mBatteryProps.batteryHealth,
          mPlugType,
          mBatteryProps.batteryLevel,
          mBatteryProps.batteryTemperature,
          mBatteryProps.batteryVoltage);
    } catch (RemoteException e) {
      // Should never happen.
    }

    shutdownIfNoPowerLocked();
    shutdownIfOverTempLocked();

    if (mBatteryProps.batteryStatus != mLastBatteryStatus
        || mBatteryProps.batteryStatus_2nd != mLastBatteryStatus_2nd
        || mBatteryProps.batteryHealth != mLastBatteryHealth
        || mBatteryProps.batteryPresent != mLastBatteryPresent
        || mBatteryProps.batteryPresent_2nd != mLastBatteryPresent_2nd
        || mBatteryProps.batteryLevel != mLastBatteryLevel
        || mBatteryProps.batteryLevel_2nd != mLastBatteryLevel_2nd
        || mPlugType != mLastPlugType
        || mBatteryProps.batteryVoltage != mLastBatteryVoltage
        || mBatteryProps.batteryTemperature != mLastBatteryTemperature
        || mInvalidCharger != mLastInvalidCharger) {

      if (mPlugType != mLastPlugType) {
        if (mLastPlugType == BATTERY_PLUGGED_NONE) {
          // discharging -> charging

          // There's no value in this data unless we've discharged at least once and the
          // battery level has changed; so don't log until it does.
          if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryProps.batteryLevel) {
            dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
            logOutlier = true;
            EventLog.writeEvent(
                EventLogTags.BATTERY_DISCHARGE,
                dischargeDuration,
                mDischargeStartLevel,
                mBatteryProps.batteryLevel);
            // make sure we see a discharge event before logging again
            mDischargeStartTime = 0;
          }
        } else if (mPlugType == BATTERY_PLUGGED_NONE) {
          // charging -> discharging or we just powered up
          mDischargeStartTime = SystemClock.elapsedRealtime();
          mDischargeStartLevel = mBatteryProps.batteryLevel;
        }
      }
      if (mBatteryProps.batteryStatus != mLastBatteryStatus
          || mBatteryProps.batteryHealth != mLastBatteryHealth
          || mBatteryProps.batteryPresent != mLastBatteryPresent
          || mPlugType != mLastPlugType) {
        EventLog.writeEvent(
            EventLogTags.BATTERY_STATUS,
            mBatteryProps.batteryStatus,
            mBatteryProps.batteryHealth,
            mBatteryProps.batteryPresent ? 1 : 0,
            mPlugType,
            mBatteryProps.batteryTechnology);
      }
      if (mBatteryProps.batteryLevel != mLastBatteryLevel) {
        // Don't do this just from voltage or temperature changes, that is
        // too noisy.
        EventLog.writeEvent(
            EventLogTags.BATTERY_LEVEL,
            mBatteryProps.batteryLevel,
            mBatteryProps.batteryVoltage,
            mBatteryProps.batteryTemperature);
      }
      if (mBatteryLevelCritical
          && !mLastBatteryLevelCritical
          && mPlugType == BATTERY_PLUGGED_NONE) {
        // We want to make sure we log discharge cycle outliers
        // if the battery is about to die.
        dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
        logOutlier = true;
      }

      final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE;
      final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE;

      /* The ACTION_BATTERY_LOW broadcast is sent in these situations:
       * - is just un-plugged (previously was plugged) and battery level is
       *   less than or equal to WARNING, or
       * - is not plugged and battery level falls to WARNING boundary
       *   (becomes <= mLowBatteryWarningLevel).
       */
      final boolean sendBatteryLow =
          !plugged
              && mBatteryProps.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
              && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel
              && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);

      sendIntentLocked();

      // Separate broadcast is sent for power connected / not connected
      // since the standard intent will not wake any applications and some
      // applications may want to have smart behavior based on this.
      if (mPlugType != 0 && mLastPlugType == 0) {
        mHandler.post(
            new Runnable() {
              @Override
              public void run() {
                Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
              }
            });
      } else if (mPlugType == 0 && mLastPlugType != 0) {
        mHandler.post(
            new Runnable() {
              @Override
              public void run() {
                Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
              }
            });
      }

      if (sendBatteryLow) {
        mSentLowBatteryBroadcast = true;
        mHandler.post(
            new Runnable() {
              @Override
              public void run() {
                Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);
                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
              }
            });
      } else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= mLowBatteryCloseWarningLevel) {
        mSentLowBatteryBroadcast = false;
        mHandler.post(
            new Runnable() {
              @Override
              public void run() {
                Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
              }
            });
      }

      // Update the battery LED
      // mLed.updateLightsLocked();

      // This needs to be done after sendIntent() so that we get the lastest battery stats.
      if (logOutlier && dischargeDuration != 0) {
        logOutlierLocked(dischargeDuration);
      }

      mLastBatteryStatus = mBatteryProps.batteryStatus;
      mLastBatteryStatus_2nd = mBatteryProps.batteryStatus_2nd;
      mLastBatteryHealth = mBatteryProps.batteryHealth;
      mLastBatteryPresent = mBatteryProps.batteryPresent;
      mLastBatteryPresent_2nd = mBatteryProps.batteryPresent_2nd;
      mLastBatteryLevel = mBatteryProps.batteryLevel;
      mLastBatteryLevel_2nd = mBatteryProps.batteryLevel_2nd;
      mLastPlugType = mPlugType;
      mLastBatteryVoltage = mBatteryProps.batteryVoltage;
      mLastBatteryTemperature = mBatteryProps.batteryTemperature;
      mLastBatteryLevelCritical = mBatteryLevelCritical;
      mLastInvalidCharger = mInvalidCharger;
    }
  }