Пример #1
0
    def update_event(self, event, hook_source):
        """ When a hook source gets an event, it should report it to this
        function. The only exception is HOOK_TIME which is handled within this
        class itself.
        """
        # TODO: Access should be locked
        if (self._hook_mask & hook_source) == GPS.NO_HOOKS:
            # We are not using this hook source, ignore.
            return

        self._update_times()
        prev_state = self.pwr_state

        if event == GPS.GPS_STATUS_SESSION_BEGIN:
            self.pwr_state = GPS.POWER_STATE_ON
        elif event == GPS.GPS_STATUS_SESSION_END:
            if self.pwr_state == GPS.POWER_STATE_ON:
                self.pwr_state = GPS.POWER_STATE_SLEEP
        elif event == GPS.GPS_STATUS_ENGINE_ON:
            if self.pwr_state == GPS.POWER_STATE_OFF:
                self.pwr_state = GPS.POWER_STATE_SLEEP
        elif event == GPS.GPS_STATUS_ENGINE_OFF:
            self.pwr_state = GPS.POWER_STATE_OFF
        else:
            self.logger.error("Unknown GPS event capture: {0}".format(event))

        if self.pwr_state != prev_state:
            if ((prev_state == GPS.POWER_STATE_ON) and
                    (self.pwr_state == GPS.POWER_STATE_SLEEP)):
                self._off_time = SystemClock.elapsedRealtime() + \
                    self._sleep_time
            else:
                # Any other state transition should reset the off timer
                self._off_time = None
Пример #2
0
    def start_sensor(self, name):
        if (name in self._on) and (self._on[name] == 0):
            self._on_times[name] -= SystemClock.elapsedRealtime() -\
                self._timestamp
            self.started_sensors += 1

        # WARNING: May break when name is invalid
        self._on[name] += 1
Пример #3
0
 def stop_sensor(self, name):
     if name in self._on:
         if self._on[name] == 0:
             return
         if self._on[name] - 1 == 0:
             self._on_times[name] += (SystemClock.elapsedRealtime() -
                                      self._timestamp)
             self.started_sensors -= 1
         self._on[name] -= 1
Пример #4
0
    def __init__(self):
        self._total = 0
        self._start_time = SystemClock.elapsedRealtime()

        self._counters = {
            self.COUNTER_MINUTE: _BucketCounter(),
            self.COUNTER_HOUR: _BucketCounter(),
            self.COUNTER_DAY: _BucketCounter(),
            self.COUNTER_TOTAL: _BucketCounter(),
        }
    def _prepare(self, iter_interval=1):
        """ Called once at the beginning of the daemon loop. """
        self._start_time = SystemClock.elapsedRealtime()
        self._iter_interval = iter_interval # Every second

        # Iteration-data buffers for cycling during data collection
        self._data1 = None
        self._data2 = None
        self._iter1 = -1
        self._iter2 = -1
Пример #6
0
    def is_stale(self):
        """ Heuristic to avoid excessive polling on UIDs. We shouldn't
        update state on every iteration as it takes too much time
        """
        if not self.is_initialized():
            return True

        # TODO: check if 10000 is the correct number (should be 10s?)
        # Reduce this number if we want more frequent WiFi checks
        return ((SystemClock.elapsedRealtime() - self._update_time) > min(
            10000, self.inactive_time))
Пример #7
0
    def is_stale(self):
        """ Heuristic to avoid excessive polling on UIDs. We shouldn't
        update state on every iteration as it takes too much time
        """
        if not self.is_initialized():
            return True

        # TODO: check if 10000 is the correct number (should be 10s?)
        # Reduce this number if we want more frequent WiFi checks
        return ((SystemClock.elapsedRealtime() - self._update_time) >
                min(10000, self.inactive_time))
Пример #8
0
    def is_stale(self):
        """ Heuristic to avoid excessive polling on UIDs. We shouldn't
        update state on every iteration as it takes too much time

        None -> Boolean
        """
        if self.pwr_state != ThreeG.POWER_STATE_IDLE:
            return True

        # TODO: check if 10000 us the correct number (Why 10s?)
        # Reduce this number if we want more frequent 3G checks
        return ((SystemClock.elapsedRealtime() - self._update_time) >
                min(10000, self._inactive_time))
Пример #9
0
    def get(self, type_):
        assert (Counter.COUNTER_MINUTE <= type_ <= Counter.COUNTER_TOTAL)

        if type_ == Counter.COUNTER_TOTAL:
            return self._total

        now = SystemClock.elapsedRealtime() - self._start_time
        timestamp = (now * _BucketCounter.BUCKET_NUM /
                     Counter.COUNTER_DURATIONS[type_])
        progress = ((now * _BucketCounter.BUCKET_NUM %
                     Counter.COUNTER_DURATIONS[type_]) /
                    Counter.COUNTER_DURATIONS[type_])
        return self._counters[type_].get(timestamp, progress)
Пример #10
0
    def is_stale(self):
        """ Heuristic to avoid excessive polling on UIDs. We shouldn't
        update state on every iteration as it takes too much time

        None -> Boolean
        """
        if self.pwr_state != ThreeG.POWER_STATE_IDLE:
            return True

        # TODO: check if 10000 us the correct number (Why 10s?)
        # Reduce this number if we want more frequent 3G checks
        return ((SystemClock.elapsedRealtime() - self._update_time) > min(
            10000, self._inactive_time))
Пример #11
0
    def update(self, tx_pkts, rx_pkts, tx_bytes, rx_bytes):
        now = SystemClock.elapsedRealtime()

        if (self._update_time is not None) and (now > self._update_time):
            delta_time = now - self._update_time
            self.delta_pkts = tx_pkts + rx_pkts - self.tx_pkts - self.rx_pkts
            self.delta_tx_bytes = tx_bytes - self.tx_bytes
            self.delta_rx_bytes = rx_bytes - self.rx_bytes

            inactive = (self.delta_tx_bytes == 0) and (self.delta_rx_bytes
                                                       == 0)
            if inactive:
                self._inactive_time += delta_time
            else:
                self._inactive_time = 0

            # TODO: Make this always work
            time_mult = 1
            if PowerEstimator.ITERATION_INTERVAL % 1000 != 0:
                # Cannot handle 1-sec iteration intervals
                pass
            else:
                time_mult = 1000 // PowerEstimator.ITERATION_INTERVAL

            if self.pwr_state == ThreeG.POWER_STATE_IDLE and not inactive:
                self.pwr_state = ThreeG.POWER_STATE_FACH
            elif self.pwr_state == ThreeG.POWER_STATE_FACH:
                if inactive:
                    self._pwr_state_time += 1
                    if (self._pwr_state_time >=
                        (self._fach_idle_time * time_mult)):
                        self._pwr_state_time = 0
                        self.pwr_state = ThreeG.POWER_STATE_IDLE
                else:
                    self._pwr_state_time = 0
                    if (self.delta_tx_bytes > 0) or (self.delta_rx_bytes > 0):
                        self.pwr_state = ThreeG.POWER_STATE_DCH
            elif self.pwr_state == ThreeG.POWER_STATE_DCH:
                if inactive:
                    self._pwr_state_time += 1
                    if self._pwr_state_time >= self._dch_fach_time * time_mult:
                        self._pwr_state_time = 0
                        self.pwr_state = ThreeG.POWER_STATE_FACH
                else:
                    self._pwr_state_time = 0

        self._update_time = now
        self.tx_pkts = tx_pkts
        self.rx_pkts = rx_pkts
        self.tx_bytes = tx_bytes
        self.rx_bytes = rx_bytes
Пример #12
0
    def update(self, tx_pkts, rx_pkts, tx_bytes, rx_bytes):
        now = SystemClock.elapsedRealtime()

        if (self._update_time is not None) and (now > self._update_time):
            delta_time = now - self._update_time
            self.delta_pkts = tx_pkts + rx_pkts - self.tx_pkts - self.rx_pkts
            self.delta_tx_bytes = tx_bytes - self.tx_bytes
            self.delta_rx_bytes = rx_bytes - self.rx_bytes

            inactive = (self.delta_tx_bytes == 0) and (self.delta_rx_bytes == 0)
            if inactive:
                self._inactive_time += delta_time
            else:
                self._inactive_time = 0

            # TODO: Make this always work
            time_mult = 1
            if PowerEstimator.ITERATION_INTERVAL % 1000 != 0:
                # Cannot handle 1-sec iteration intervals
                pass
            else:
                time_mult = 1000 // PowerEstimator.ITERATION_INTERVAL

            if self.pwr_state == ThreeG.POWER_STATE_IDLE and not inactive:
                self.pwr_state = ThreeG.POWER_STATE_FACH
            elif self.pwr_state == ThreeG.POWER_STATE_FACH:
                if inactive:
                    self._pwr_state_time += 1
                    if (self._pwr_state_time >=
                            (self._fach_idle_time * time_mult)):
                        self._pwr_state_time = 0
                        self.pwr_state = ThreeG.POWER_STATE_IDLE
                else:
                    self._pwr_state_time = 0
                    if (self.delta_tx_bytes > 0) or (self.delta_rx_bytes > 0):
                        self.pwr_state = ThreeG.POWER_STATE_DCH
            elif self.pwr_state == ThreeG.POWER_STATE_DCH:
                if inactive:
                    self._pwr_state_time += 1
                    if self._pwr_state_time >= self._dch_fach_time * time_mult:
                        self._pwr_state_time = 0
                        self.pwr_state = ThreeG.POWER_STATE_FACH
                else:
                    self._pwr_state_time = 0

        self._update_time = now
        self.tx_pkts = tx_pkts
        self.rx_pkts = rx_pkts
        self.tx_bytes = tx_bytes
        self.rx_bytes = rx_bytes
Пример #13
0
    def _update_times(self):
        now = SystemClock.elapsedRealtime()

        # Check if GPS has gone to sleep state due to timer
        if ((self._hook_mask & GPS.HOOK_TIMER != GPS.NO_HOOKS) and
                (self._off_time is not None) and (self._off_time < now)):
            self._state_times[self.pwr_state] += (self._off_time -
                                                  self._update_time) / 1000
            self.pwr_state = GPS.POWER_STATE_OFF
            self._off_time = None

        # Update the amount of time that we've been in the current state
        self._state_times[self.pwr_state] += ((now - self._update_time) /
                                              1000)
        self._update_time = now
Пример #14
0
    def get_times(self):
        now = SystemClock.elapsedRealtime()
        div = now - self._timestamp

        if div <= 0:
            div = 1

        times = {}

        for k, v in self._on_times.iteritems():
            factor = now - self._timestamp if self._on.get(k, 0) > 0 else 0
            times[k] = (v + factor) / div
            self._on_times[k] = 0

        self._timestamp = now
        return times
Пример #15
0
    def __init__(self, hook_mask, sleep_time=None, update_time=None):
        # The union of whatever valid hook sources. See HOOK_ constants
        self._hook_mask = hook_mask
        # The time GPS hardware should turn off. Only used if HOOK_TIMER is in
        # hook_mask. Not useful if HOOK_TIMER is not set
        self._off_time = None
        # Time GPS remains in sleep state after session has ended
        # (seconds)
        self._sleep_time = sleep_time

        if not update_time:
            self._update_time = SystemClock.elapsedRealtime()
        else:
            self._update_time = update_time

        self._state_times = []
        self.pwr_state = GPS.POWER_STATE_OFF
    def _run(self):
        """ Runs the daemon loop that collects data for this monitor."""

        # Hands off to client class to actually calculate the information we
        # want for this monitor

        iter_num = 0
        self._prepare()

        while not self.is_stopped():
            data = self.calc_iteration(iter_num)
            if data is not None:
                with self._data_lock:
                    if self._iter1 < self._iter2:
                        self._iter1 = iter_num
                        self._data1 = data
                    else:
                        self._iter2 = iter_num
                        self._data2 = data

            if not self.is_stopped():
                break

            now = SystemClock.elapsedRealtime()
            # Compute the next iteration that we can make the start of
            prev_iter = iter_num
            iter_num = max((iter_num + 1), 1 + (now - self._start_time) /
                           self._iter_interval)

            if prev_iter + 1 != iter_num:
                self.logger.warn("Had to skip iteration {0} to "
                                 "{1}".format(prev_iter, iter_num))

            # Sleep until next iteration completes
            time.sleep(self._start_time + iter_num * self._iter_interval - now)

        self._on_exit()
Пример #17
0
    def update(self, tx_pkts, rx_pkts, tx_bytes, rx_bytes):
        now = SystemClock.elapsedRealtime()

        if (self._update_time is not None) and (now > self._update_time):
            delta_time = now - self._update_time
            # 1024 * 7.8125 = 131.072
            self.tx_rate = (tx_bytes - self.tx_bytes) / 131.072 / delta_time
            self.delta_pkts = rx_pkts + tx_pkts - self.rx_pkts - self.tx_pkts
            self.delta_tx_bytes = tx_bytes - self.tx_bytes
            self.delta_rx_bytes = rx_bytes - self.rx_bytes

            if tx_pkts != self.tx_pkts:
                self.avg_tx_pkt_size = ((0.9 * self.avg_tx_pkt_size) +
                                        (0.1 * (tx_bytes - self.tx_bytes) /
                                            (tx_pkts - self.tx_pkts)))

            if rx_pkts != self.rx_pkts:
                self.avg_rx_pkt_size = ((0.9 * self.avg_rx_pkt_size) +
                                        (0.1 * (rx_bytes - self.rx_bytes) / (
                                            rx_pkts - self.rx_pkts)))

            if (rx_bytes != self.rx_bytes) or (tx_bytes != self.tx_bytes):
                self.inactive_time = 0
            else:
                self.inactive_time += now - self._update_time

            if self.delta_pkts < self._highlow_pktbound:
                self.pwr_state = Wifi.POWER_STATE_LOW
            elif self.delta_pkts > self._lowhigh_pktbound:
                self.pwr_state = Wifi.POWER_STATE_HIGH

        self._update_time = now
        self.tx_pkts = tx_pkts
        self.rx_pkts = rx_pkts
        self.tx_bytes = tx_bytes
        self.rx_bytes = rx_bytes
Пример #18
0
    def update(self, tx_pkts, rx_pkts, tx_bytes, rx_bytes):
        now = SystemClock.elapsedRealtime()

        if (self._update_time is not None) and (now > self._update_time):
            delta_time = now - self._update_time
            # 1024 * 7.8125 = 131.072
            self.tx_rate = (tx_bytes - self.tx_bytes) / 131.072 / delta_time
            self.delta_pkts = rx_pkts + tx_pkts - self.rx_pkts - self.tx_pkts
            self.delta_tx_bytes = tx_bytes - self.tx_bytes
            self.delta_rx_bytes = rx_bytes - self.rx_bytes

            if tx_pkts != self.tx_pkts:
                self.avg_tx_pkt_size = ((0.9 * self.avg_tx_pkt_size) +
                                        (0.1 * (tx_bytes - self.tx_bytes) /
                                         (tx_pkts - self.tx_pkts)))

            if rx_pkts != self.rx_pkts:
                self.avg_rx_pkt_size = ((0.9 * self.avg_rx_pkt_size) +
                                        (0.1 * (rx_bytes - self.rx_bytes) /
                                         (rx_pkts - self.rx_pkts)))

            if (rx_bytes != self.rx_bytes) or (tx_bytes != self.tx_bytes):
                self.inactive_time = 0
            else:
                self.inactive_time += now - self._update_time

            if self.delta_pkts < self._highlow_pktbound:
                self.pwr_state = Wifi.POWER_STATE_LOW
            elif self.delta_pkts > self._lowhigh_pktbound:
                self.pwr_state = Wifi.POWER_STATE_HIGH

        self._update_time = now
        self.tx_pkts = tx_pkts
        self.rx_pkts = rx_pkts
        self.tx_bytes = tx_bytes
        self.rx_bytes = rx_bytes
    def _run(self):
        """Loop that keeps updating the power profile"""

        start_time = SystemClock.elapsedRealtime()

        for hw in self._phone.hardware.values():
            hw.init(start_time, self.ITERATION_INTERVAL)
            hw.start()

        self._running.set()
        iter_num = 0

        while self.is_running():
            now = SystemClock.elapsedRealtime()

            # Compute the next iteration that we can make the ending of. We
            # wait for the end of the iteration so that the monitors have a
            # chance to collect data
            iter_num = max(iter_num, (now - start_time) //
                           self.ITERATION_INTERVAL)

            # sleep until the next iteration completes
            time.sleep(start_time + iter_num *
                       self.ITERATION_INTERVAL - now)

            # Check if service was interrupted while sleeping
            if not self.is_running():
                break

            total_power = 0

            hw_data = {}

            if iter_num % (30 * 60) == 0:
                self._log_sys_settings()

            if iter_num % 60 == 0:
                self._log_battery()

            for name, hw in self._phone.hardware.iteritems():
                data = hw.get_data(iter_num)

                if data is None:
                    continue

                hw_data[name] = data

                for uid, usage in data.uid_usage.iteritems():

                    power = self._phone.power_function[name](usage)
                    usage.power = power
                    self._pwr_history[name].add(uid, iter_num, power)
                    if uid == SystemInfo.AID_ALL:
                        total_power += power

                    # Update list of running apps
                    with self._appslock:
                        self._running_apps.setdefault(uid,
                                                      SystemInfo.get_uid_name(
                                                      uid))

                    if name == "OLED" and usage.pix_pwr >= 0:
                        self._oled_pwr_history.add_power(uid, iter_num,
                                                         1000 * data.pix_pwr)

                    self._log_uid_power(self, uid, name, power)

                # Only log app names for the first time
                if iter_num == 0:
                    self._log_app_names()

                self._log_power(total_power, hw_data)
                self._update_avg_power()

        # Wait for all hardware monitors to finish
        for hw in self._phone.hardware.values():
            hw.stop()
            hw.join()
Пример #20
0
 def interface_off(self):
     self._update_time = SystemClock.elapsedRealtime()
     self.pwr_state = ThreeG.POWER_STATE_IDLE
Пример #21
0
 def __init__(self):
     self._on = dict.fromkeys(Sensors.SENSORS, 0)
     self._on_times = dict.fromkeys(Sensors.SENSORS, 0)
     self._timestamp = SystemClock.elapsedRealtime()
     self.started_sensors = 0
Пример #22
0
 def add(self, value):
     self._total += value
     now = SystemClock.elapsedRealtime() - self._start_time
     for type_, counter in self._counters.iteritems():
         counter.add(value, now * _BucketCounter.BUCKET_NUM /
                            Counter.COUNTER_DURATIONS[type_])
Пример #23
0
 def interface_off(self):
     self._update_time = SystemClock.elapsedRealtime()
     self.pwr_state = ThreeG.POWER_STATE_IDLE