Repository

js/Mobilizing/misc/BatteryStatus.js

import * as debug from '../core/util/Debug';
import Component from '../core/Component';

/**
 * Fired when charging state changed
 * @event chargingchange
 */
const EVT_CHARGING_CHANGED = 'chargingchange';

/**
 * Fired when charge level changed
 * @event levelchange
 */
const EVT_LEVEL_CHANGED = 'levelchange';

/**
 * Fired when charging time changed
 * @event chargingtimechange
 */
const EVT_CHARGING_TIME_CHANGED = 'chargingtimechange';

/**
 * Fired when discharging time changed
 * @event dischargingtimechange
 */
const EVT_DISCHARGING_TIME_CHANGED = 'dischargingtimechange';

/**
* Component to monitor battery status changes
*/
export default class BatteryStatus extends Component {
    setup() {
        this._manager = null;
        this._batteryAvailable = typeof navigator.getBattery !== "undefined";
    }

    on() {
        if (this._batteryAvailable) {
            super.on();
            navigator.getBattery().then((manager) => this.onBatteryManager(manager));
        }
        else {
            debug.warn('The battery API is not supported on this device');
        }
    }

    off() {
        super.off();

        if (this._manager) {
            this._manager.removeEventListener("chargingchange", (event) => this.onChargingChange(event));
            this._manager.removeEventListener("chargingtimechange", (event) => this.onChargingTimeChange(event));
            this._manager.removeEventListener("levelchange", (event) => this.onLevelChange(event));
            this._manager.removeEventListener("dischargingtimechange", (event) => this.onDischargingTimeChange(event));

            this._manager = null;
        }
    }

    /**
    battery API promise callback
    Adds event listeners on the battery manager
    @param {BatteryManager} manager A BatteryManager (see https://developer.mozilla.org/en-US/docs/Web/API/BatteryManager)
    @private
    */
    onBatteryManager(manager) {
        if (!this.active) {
            // this component has been turned off before getting the manager
            return;
        }

        this._manager = manager;

        this._manager.addEventListener("chargingchange", (event) => this.onChargingChange(event));
        this._manager.addEventListener("chargingtimechange", (event) => this.onChargingTimeChange(event));
        this._manager.addEventListener("levelchange", (event) => this.onLevelChange(event));
        this._manager.addEventListener("dischargingtimechange", (event) => this.onDischargingTimeChange(event));
    }

    /**
    chargingchange event handler
    Fires a chargingchange event
    @private
    */
    onChargingChange(event) {
        this.events.trigger(EVT_CHARGING_CHANGED, event.target.charging);
    }

    /**
    chargingtimechange event handler
    Fires a chargingtimechange event
    @private
    */
    onChargingTimeChange(event) {
        this.events.trigger(EVT_CHARGING_TIME_CHANGED, event.target.chargingTime);
    }

    /**
    levelchange event handler
    Fires a levelchange event
    @private
    */
    onDischargingTimeChange(event) {
        this.events.trigger(EVT_DISCHARGING_TIME_CHANGED, event.target.dischargingTime);
    }

    /**
    dischargingtimechange event handler
    Fires a dischargingtimechange event
    @private
    */
    onLevelChange(event) {
        this.events.trigger(EVT_LEVEL_CHANGED, event.target.level);
    }

    /**
    Check if the battery is currently charging
    The component needs to be activated before using this method
    @return {Boolean} True if charging, false otherwise
    */
    isCharging() {
        if (!this._manager) {
            debug.warn('The battery component needs to be active to get battery information');
            return null;
        }

        return this._manager.charging;
    }

    /**
    Get the time remaining until the battery is fully charge
    The component needs to be activated before using this method
    @return {Number} The remaining time in seconds until the battery is fully charged, or 0 if the battery is already fully charged
    */
    getChargingTime() {
        if (!this._manager) {
            debug.warn('The battery component needs to be active to get battery information');
            return null;
        }

        return this._manager.chargingTime;
    }

    /**
    Get the time remaining until the battery is completely discharged
    The component needs to be activated before using this method
    @return {Number} The remaining time in seconds until the battery is completely discharged and the system will suspend
    */
    getDischargingTime() {
        if (!this._manager) {
            debug.warn('The battery component needs to be active to get battery information');
            return null;
        }

        return this._manager.dischargingTime;
    }

    /**
    Get the battery's charge level
    The component needs to be activated before using this method
    @return {Number} The charge level on a scale from 0.0 to 1.0
    */
    getLevel() {
        if (!this._manager) {
            debug.warn('The battery component needs to be active to get battery information');
            return null;
        }

        return this._manager.level;
    }
}