Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3fb8952 authored by Jeff Brown's avatar Jeff Brown
Browse files

Implement screen on hack for wireless chargers.

We can't accurately detect whether the device is resting
on a wireless charger unless it is actually charging.
So we need to tweak the screen on when plugged / unplugged
policy accordingly to avoid spurious wakeups.

Bug: 7234284
Change-Id: I624b559e2e92b8813b12090bc20eca5f5158997e
parent a4d8204e
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -196,6 +196,15 @@ public final class BatteryService extends Binder {
        return false;
    }

    /**
     * Returns the current plug type.
     */
    public int getPlugType() {
        synchronized (mLock) {
            return mPlugType;
        }
    }

    /**
     * Returns battery level as a percentage.
     */
+55 −4
Original line number Diff line number Diff line
@@ -135,6 +135,11 @@ public final class PowerManagerService extends IPowerManager.Stub
    // minimum screen off timeout should be longer than this.
    private static final int SCREEN_DIM_DURATION = 7 * 1000;

    // Upper bound on the battery charge percentage in order to consider turning
    // the screen on when the device starts charging wirelessly.
    // See point of use for more details.
    private static final int WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT = 95;

    private Context mContext;
    private LightsService mLightsService;
    private BatteryService mBatteryService;
@@ -218,6 +223,9 @@ public final class PowerManagerService extends IPowerManager.Stub
    // True if the device is plugged into a power source.
    private boolean mIsPowered;

    // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS.
    private int mPlugType;

    // True if the device should wake up when plugged or unplugged.
    private boolean mWakeUpWhenPluggedOrUnpluggedConfig;

@@ -1013,15 +1021,19 @@ public final class PowerManagerService extends IPowerManager.Stub
     */
    private void updateIsPoweredLocked(int dirty) {
        if ((dirty & DIRTY_BATTERY_STATE) != 0) {
            boolean wasPowered = mIsPowered;
            final boolean wasPowered = mIsPowered;
            final int oldPlugType = mPlugType;
            mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
            mPlugType = mBatteryService.getPlugType();

            if (DEBUG) {
                Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
                        + ", mIsPowered=" + mIsPowered);
                        + ", mIsPowered=" + mIsPowered
                        + ", oldPlugType=" + oldPlugType
                        + ", mPlugType=" + mPlugType);
            }

            if (wasPowered != mIsPowered) {
            if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
                mDirty |= DIRTY_IS_POWERED;

                // Treat plugging and unplugging the devices as a user activity.
@@ -1030,7 +1042,7 @@ public final class PowerManagerService extends IPowerManager.Stub
                // Some devices also wake the device when plugged or unplugged because
                // they don't have a charging LED.
                final long now = SystemClock.uptimeMillis();
                if (mWakeUpWhenPluggedOrUnpluggedConfig) {
                if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType)) {
                    wakeUpNoUpdateLocked(now);
                }
                userActivityNoUpdateLocked(
@@ -1039,6 +1051,44 @@ public final class PowerManagerService extends IPowerManager.Stub
        }
    }

    private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(boolean wasPowered, int oldPlugType) {
        if (mWakeUpWhenPluggedOrUnpluggedConfig) {
            // FIXME: Need more accurate detection of wireless chargers.
            //
            // We are unable to accurately detect whether the device is resting on the
            // charger unless it is actually receiving power.  This causes us some grief
            // because the device might not appear to be plugged into the wireless charger
            // unless it actually charging.
            //
            // To avoid spuriously waking the screen, we apply a special policy to
            // wireless chargers.
            //
            // 1. Don't wake the device when unplugged from wireless charger because
            //    it might be that the device is still resting on the wireless charger
            //    but is not receiving power anymore because the battery is full.
            //
            // 2. Don't wake the device when plugged into a wireless charger if the
            //    battery already appears to be mostly full.  This situation may indicate
            //    that the device was resting on the charger the whole time and simply
            //    wasn't receiving power because the battery was full.  We can't tell
            //    whether the device was just placed on the charger or whether it has
            //    been there for half of the night slowly discharging until it hit
            //    the point where it needed to start charging again.
            if (wasPowered && !mIsPowered
                    && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
                return false;
            }
            if (!wasPowered && mIsPowered
                    && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
                    && mBatteryService.getBatteryLevel() >=
                            WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
                return false;
            }
            return true;
        }
        return false;
    }

    /**
     * Updates the value of mStayOn.
     * Sets DIRTY_STAY_ON if a change occurred.
@@ -1891,6 +1941,7 @@ public final class PowerManagerService extends IPowerManager.Stub
            pw.println("  mDirty=0x" + Integer.toHexString(mDirty));
            pw.println("  mWakefulness=" + wakefulnessToString(mWakefulness));
            pw.println("  mIsPowered=" + mIsPowered);
            pw.println("  mPlugType=" + mPlugType);
            pw.println("  mStayOn=" + mStayOn);
            pw.println("  mBootCompleted=" + mBootCompleted);
            pw.println("  mSystemReady=" + mSystemReady);