Esempio n. 1
0
    def __init__(self, devconstants):
        super(GPS, self).__init__(Hardware.GPS, devconstants)
        self._uid_states = {}
        self._sleep_time = round(1000 * devconstants.GPS_SLEEP_TIME)
        self._update_time = 0
        self._hook_method = 0
        self._statekeeper = None
        self._status = None

        self._setup_gps_hook()

        self._uidstates_lock = threading.Lock()
        self._statekeeper_lock = threading.Lock()
        self._gpsstatus_lock = threading.Lock()

        # Track physical state
        self._statekeeper = GPSState(self._hook_method, self._sleep_time)

        # We need a GPS listener so that we can get the satellite count. Also
        # if anything goes wrong with the libgps hook, we revert to using this
        self._listener = GPSListener(self.__on_gps_status_changed)
        self._listener.start()

        # Use notification service to gather UID information if it's available

        callbacks = {
            NotificationProxy.ON_START_WAKELOCK: self.__on_start_wakelock,
            NotificationProxy.ON_STOP_WAKELOCK: self.__on_stop_wakelock,
            NotificationProxy.ON_START_GPS: self.__on_start_gps,
            NotificationProxy.ON_STOP_GPS: self.__on_start_gps,
        }

        if NotificationProxy.is_available():
            self._event_server = NotificationProxy(callbacks)
            self._event_server.add_hook()
Esempio n. 2
0
class Sensors(DeviceMonitor):
    SENSORS = SensorsAccess.get_sensors().keys()

    def __init__(self, devconstants=None):
        super(Sensors, self).__init__(Hardware.SENSORS, devconstants)
        self._state = SensorState()
        self._uid_states = {}
        self._sensorslock = threading.Lock()

        callbacks = {
            NotificationProxy.ON_START_SENSOR: self.__on_start_sensor,
            NotificationProxy.ON_STOP_SENSOR: self.__on_stop_sensor
        }

        self.has_uid_information = True

        if NotificationProxy.is_available():
            self._event_server = NotificationProxy(callbacks)
            self._event_server.add_hook()

    def _on_exit(self):
        if NotificationProxy.is_available():
            self._event_server.remove_hook()
        super(Sensors, self)._on_exit()

    def calc_iteration(self, iter_num):
        """ Return power usage of each application using sensors after one
        iteration. """
        result = IterationData()
        sensor_usage = SensorUsage()

        with self._sensorslock:
            sensor_usage.on_times = self._state.get_times()
            result.set_sys_usage(sensor_usage)

            for uid, state in self._uid_states.iteritems():
                usage = SensorUsage()
                usage.on_times = state.get_times()
                result.set_uid_usage(uid, usage)

                if state.started_sensors == 0:
                    del (self._uid_states[uid])

        return result

    def __on_start_sensor(self, uid, sensor):
        with self._sensorslock:
            self._state.start_sensor(sensor)
            uid_state = self._uid_states.setdefault(uid, SensorState())
            uid_state.start_sensor(sensor)

    def __on_stop_sensor(self, uid, sensor):
        with self._sensorslock:
            self._state.stop_sensor(sensor)
            uid_state = self._uid_states.setdefault(uid, SensorState())
            uid_state.stop_sensor(sensor)
Esempio n. 3
0
    def _on_exit(self):
        self._listener.stop()

        if NotificationProxy.is_available():
            self._event_server.remove_hook()

        super(GPS, self)._on_exit()
Esempio n. 4
0
    def __init__(self, devconstants=None):
        super(Sensors, self).__init__(Hardware.SENSORS, devconstants)
        self._state = SensorState()
        self._uid_states = {}
        self._sensorslock = threading.Lock()

        callbacks = {
            NotificationProxy.ON_START_SENSOR: self.__on_start_sensor,
            NotificationProxy.ON_STOP_SENSOR: self.__on_stop_sensor
        }

        self.has_uid_information = True

        if NotificationProxy.is_available():
            self._event_server = NotificationProxy(callbacks)
            self._event_server.add_hook()
Esempio n. 5
0
    def __init__(self, devconstants=None):
        super(Audio, self).__init__(Hardware.AUDIO, devconstants)

        self._uid_states = {}
        self._uid_usage = None
        self._uidstate_lock = threading.Lock()
        self._sys_uid = None

        callbacks = {
            NotificationProxy.ON_SYSTEM_MEDIA_CALL: self.__on_system_media_call,
            NotificationProxy.ON_START_MEDIA: self.__on_start_media,
            NotificationProxy.ON_STOP_MEDIA: self.__on_stop_media,
        }

        self.has_uid_information = NotificationProxy.is_available()

        if self.has_uid_information:
            self._event_server = NotificationProxy(callbacks)
            self._event_server.add_hook()
Esempio n. 6
0
    def __init__(self, devconstants=None):
        super(Audio, self).__init__(Hardware.AUDIO, devconstants)

        self._uid_states = {}
        self._uid_usage = None
        self._uidstate_lock = threading.Lock()
        self._sys_uid = None

        callbacks = {
            NotificationProxy.ON_SYSTEM_MEDIA_CALL:
            self.__on_system_media_call,
            NotificationProxy.ON_START_MEDIA: self.__on_start_media,
            NotificationProxy.ON_STOP_MEDIA: self.__on_stop_media,
        }

        self.has_uid_information = NotificationProxy.is_available()

        if self.has_uid_information:
            self._event_server = NotificationProxy(callbacks)
            self._event_server.add_hook()
Esempio n. 7
0
    def _setup_gps_hook(self):
        """ Setup method for collecting GPS state information. """
        # We can always use the status listener hook and perhaps the
        # notification hook if we are running eclaire or higher and the
        # notification hook is installed. We can only do this on eclaire or
        # higher because it wasn't until eclaire that they fixed a bug
        # where they didn't maintain a wakelock while the GPS engine was on
        self._hook_method = self.HOOK_GPS_STATUS_LISTENER

        try:
            # >= 5: eclair or higher
            if ((NotificationProxy.is_available() and
                    int(Build.VERSION.SDK_INT) >= 5)):
                self._hook_method |= self.HOOK_NOTIFICATIONS
        except ValueError:
            pass

        # If we don't have a way of getting the off<->sleep transitions via
        # notifications, let's just use a timer and simulate the state of
        # the GPS instead

        if self._hook_method & self.HOOK_NOTIFICATIONS == self.NO_HOOKS:
            self._hook_method |= self.HOOK_TIMER
Esempio n. 8
0
 def has_uid_information(self):
     return NotificationProxy.is_available()
Esempio n. 9
0
class GPS(DeviceMonitor):
    # Constants from android.location.GpsStatus
    GPS_EVENT_STARTED = 1
    GPS_EVENT_STOPPED = 2
    GPS_EVENT_FIRST_FIX = 3
    GPS_EVENT_SATELLITE_STATUS = 4

    # Local constants
    GPS_STATUS_SESSION_BEGIN = 1
    GPS_STATUS_SESSION_END = 2
    GPS_STATUS_ENGINE_ON = 3
    GPS_STATUS_ENGINE_OFF = 4

    NO_HOOKS = 0
    HOOK_GPS_STATUS_LISTENER = 1
    HOOK_NOTIFICATIONS = 2
    HOOK_TIMER = 4

    POWER_STATE_OFF = 0
    POWER_STATE_SLEEP = 1
    POWER_STATE_ON = 2
    NPOWER_STATES = 3

    def __init__(self, devconstants):
        super(GPS, self).__init__(Hardware.GPS, devconstants)
        self._uid_states = {}
        self._sleep_time = round(1000 * devconstants.GPS_SLEEP_TIME)
        self._update_time = 0
        self._hook_method = 0
        self._statekeeper = None
        self._status = None

        self._setup_gps_hook()

        self._uidstates_lock = threading.Lock()
        self._statekeeper_lock = threading.Lock()
        self._gpsstatus_lock = threading.Lock()

        # Track physical state
        self._statekeeper = GPSState(self._hook_method, self._sleep_time)

        # We need a GPS listener so that we can get the satellite count. Also
        # if anything goes wrong with the libgps hook, we revert to using this
        self._listener = GPSListener(self.__on_gps_status_changed)
        self._listener.start()

        # Use notification service to gather UID information if it's available

        callbacks = {
            NotificationProxy.ON_START_WAKELOCK: self.__on_start_wakelock,
            NotificationProxy.ON_STOP_WAKELOCK: self.__on_stop_wakelock,
            NotificationProxy.ON_START_GPS: self.__on_start_gps,
            NotificationProxy.ON_STOP_GPS: self.__on_start_gps,
        }

        if NotificationProxy.is_available():
            self._event_server = NotificationProxy(callbacks)
            self._event_server.add_hook()

    def _on_exit(self):
        self._listener.stop()

        if NotificationProxy.is_available():
            self._event_server.remove_hook()

        super(GPS, self)._on_exit()

    @property
    def has_uid_information(self):
        return NotificationProxy.is_available()

    def _setup_gps_hook(self):
        """ Setup method for collecting GPS state information. """
        # We can always use the status listener hook and perhaps the
        # notification hook if we are running eclaire or higher and the
        # notification hook is installed. We can only do this on eclaire or
        # higher because it wasn't until eclaire that they fixed a bug
        # where they didn't maintain a wakelock while the GPS engine was on
        self._hook_method = self.HOOK_GPS_STATUS_LISTENER

        try:
            # >= 5: eclair or higher
            if ((NotificationProxy.is_available() and
                    int(Build.VERSION.SDK_INT) >= 5)):
                self._hook_method |= self.HOOK_NOTIFICATIONS
        except ValueError:
            pass

        # If we don't have a way of getting the off<->sleep transitions via
        # notifications, let's just use a timer and simulate the state of
        # the GPS instead

        if self._hook_method & self.HOOK_NOTIFICATIONS == self.NO_HOOKS:
            self._hook_method |= self.HOOK_TIMER

    def __on_start_wakelock(self, uid, name, lock_type):
        """ Callback method for GPS status monitor. """
        if (uid == SystemInfo.AID_SYSTEM) and (name == "GpsLocationProvider"):
            self._statekeeper.update_event(self.GPS_STATUS_ENGINE_ON,
                                           self.HOOK_NOTIFICATIONS)

    def __on_stop_wakelock(self, uid, name, lock_type):
        """ Callback method for GPS status monitor. """
        if (uid == SystemInfo.AID_SYSTEM) and (name == "GpsLocationProvider"):
            self._statekeeper.update_event(self.GPS_STATUS_ENGINE_OFF,
                                           self.HOOK_NOTIFICATIONS)

    def __on_start_gps(self, uid):
        """ Callback method for GPS status monitor. """
        self.update_uid_event(uid, self.GPS_STATUS_SESSION_BEGIN,
                              self.HOOK_NOTIFICATIONS)

    def __on_stop_gps(self, uid):
        """ Callback method for GPS status monitor. """
        self.update_uid_event(uid, self.GPS_STATUS_SESSION_END,
                              self.HOOK_NOTIFICATIONS)

    def __on_gps_status_changed(self, event):
        """ Callback method for GPS status monitor. """
        if event == self.GPS_EVENT_STARTED:
            self._statekeeper.update_event(self.GPS_STATUS_SESSION_BEGIN,
                                           self.HOOK_GPS_STATUS_LISTENER)
        elif event == self.GPS_EVENT_STOPPED:
            self._statekeeper.update_event(self.GPS_STATUS_SESSION_END,
                                           self.HOOK_GPS_STATUS_LISTENER)
        with self._gpsstatus_lock:
            self._status = self._listener.gps_status

    def update_uid_event(self, uid, event, hook_source):
        """ Update GPS state machine for given UID """
        with self._uidstates_lock:

            state = self._uid_states.get(uid, None)

            if not state:
                state = GPSState(self.HOOK_NOTIFICATIONS | self.HOOK_TIMER,
                                 self._sleep_time, self._update_time)
                self._uid_states[uid] = state

            state.update_event(event, hook_source)

    def calc_iteration(self, iter_num):
        """ Return power usage of each application using GPS after one
        iteration. """
        result = IterationData()

        # Get the power data for the physical GPS device

        with self._statekeeper_lock:
            state_times = self._statekeeper.state_times
            pwr_state = self._statekeeper.pwr_state
            self._statekeeper.reset_times()

        # Get the number of satellite that were available in the last update

        num_satellites = 0
        with self._gpsstatus_lock:
            if pwr_state == self.POWER_STATE_ON and self._status is not None:
                num_satellites = len(self._status.getSatellites())

        result.set_sys_usage(GPSUsage(state_times, num_satellites))

        # Get usage data for each UID we have information on
        if self.has_uid_information:
            with self._uidstates_lock:
                self._update_time = (self._start_time + self._iter_interval *
                                     iter_num)
                for uid, state in self._uid_states.iteritems():
                    state_times = state.get_state_times()
                    pwr_state = state.get_power_state()
                    state.reset_times()

                    # There is a guarantee that num_satellites will be zero
                    # if GPS is off (see above)
                    result.set_uid_usage(uid, GPSUsage(state_times,
                                                       num_satellites))

                    # Remove state information for UIDs no longer using the GPS
                    if pwr_state == self.POWER_STATE_OFF:
                        del (self._uid_states[uid])

        return result
Esempio n. 10
0
class Audio(DeviceMonitor):
    AudioProxy = AudioAccess()

    def __init__(self, devconstants=None):
        super(Audio, self).__init__(Hardware.AUDIO, devconstants)

        self._uid_states = {}
        self._uid_usage = None
        self._uidstate_lock = threading.Lock()
        self._sys_uid = None

        callbacks = {
            NotificationProxy.ON_SYSTEM_MEDIA_CALL:
            self.__on_system_media_call,
            NotificationProxy.ON_START_MEDIA: self.__on_start_media,
            NotificationProxy.ON_STOP_MEDIA: self.__on_stop_media,
        }

        self.has_uid_information = NotificationProxy.is_available()

        if self.has_uid_information:
            self._event_server = NotificationProxy(callbacks)
            self._event_server.add_hook()

    def _on_exit(self):
        if self.has_uid_information:
            self._event_server.remove_hook()
        super(Audio, self)._on_exit()

    def __on_system_media_call(self, uid):
        self._sys_uid = uid

    def __on_start_media(self, uid, id_):
        uid_usage = MediaUsage(uid, id_)
        if (uid == SystemInfo.AID_SYSTEM) and (self._sys_uid is not None):
            uid_usage.proxy_uid = self._sys_uid
            self._sys_uid = None
        else:
            uid_usage.proxy_uid = uid
        with self._uidstate_lock:
            # Act like a treeset. Just insert, but don't update
            self._uid_states.setdefault(uid, uid_usage)

    def __on_stop_media(self, uid, id_):
        with self._uidstate_lock:
            del (self._uid_states[uid])

    def calc_iteration(self, iter_num):
        """ Return power usage of each application using audio after one
        iteration. """
        result = IterationData()

        audio_on = (self._uid_usage is not None and len(self._uid_states) != 0
                    ) or (self.AudioProxy.is_music_active())
        result.set_sys_usage(AudioUsage(audio_on))

        if self._uid_usage is not None:
            with self._uidstate_lock:
                uid = -1

                for usage in self._uid_usage.values():
                    if usage.uid != uid:
                        result.set_uid_usage(usage.proxy_uid, AudioUsage(True))
                    uid = usage.uid

        return result
Esempio n. 11
0
 def _on_exit(self):
     if NotificationProxy.is_available():
         self._event_server.remove_hook()
     super(Sensors, self)._on_exit()
Esempio n. 12
0
class Audio(DeviceMonitor):
    AudioProxy = AudioAccess()

    def __init__(self, devconstants=None):
        super(Audio, self).__init__(Hardware.AUDIO, devconstants)

        self._uid_states = {}
        self._uid_usage = None
        self._uidstate_lock = threading.Lock()
        self._sys_uid = None

        callbacks = {
            NotificationProxy.ON_SYSTEM_MEDIA_CALL: self.__on_system_media_call,
            NotificationProxy.ON_START_MEDIA: self.__on_start_media,
            NotificationProxy.ON_STOP_MEDIA: self.__on_stop_media,
        }

        self.has_uid_information = NotificationProxy.is_available()

        if self.has_uid_information:
            self._event_server = NotificationProxy(callbacks)
            self._event_server.add_hook()

    def _on_exit(self):
        if self.has_uid_information:
            self._event_server.remove_hook()
        super(Audio, self)._on_exit()

    def __on_system_media_call(self, uid):
        self._sys_uid = uid

    def __on_start_media(self, uid, id_):
        uid_usage = MediaUsage(uid, id_)
        if (uid == SystemInfo.AID_SYSTEM) and (self._sys_uid is not None):
            uid_usage.proxy_uid = self._sys_uid
            self._sys_uid = None
        else:
            uid_usage.proxy_uid = uid
        with self._uidstate_lock:
            # Act like a treeset. Just insert, but don't update
            self._uid_states.setdefault(uid, uid_usage)

    def __on_stop_media(self, uid, id_):
        with self._uidstate_lock:
            del (self._uid_states[uid])

    def calc_iteration(self, iter_num):
        """ Return power usage of each application using audio after one
        iteration. """
        result = IterationData()

        audio_on = (self._uid_usage is not None and len(self._uid_states) !=
                    0) or (self.AudioProxy.is_music_active())
        result.set_sys_usage(AudioUsage(audio_on))

        if self._uid_usage is not None:
            with self._uidstate_lock:
                uid = -1

                for usage in self._uid_usage.values():
                    if usage.uid != uid:
                        result.set_uid_usage(usage.proxy_uid, AudioUsage(True))
                    uid = usage.uid

        return result