blob: 8c985f9762f4922ac3b464186b9acc3d83ff0dba [file] [log] [blame]
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import gobject
import logging
import mm1
class StateMachine(object):
"""
StateMachine is the abstract base class for the complex state machines
that are involved in the pseudo modem manager.
Every state transition is managed by a function that has been mapped to a
specific modem state. For example, the method that handles the case where
the modem is in the ENABLED state would look like:
def _HandleEnabledState(self):
# Do stuff.
The correct method will be dynamically located and executed by the step
function according to the dictionary returned by the subclass'
implementation of StateMachine._GetModemStateFunctionMap.
"""
def __init__(self, modem):
self._modem = modem
self._started = False
self._done = False
self._trans_func_map = self._GetModemStateFunctionMap()
def Cancel(self):
"""
Tells the state machine to stop transitioning to further states.
"""
self._done = True
def Step(self):
"""
Executes the next corresponding state transition based on the modem
state.
"""
if self._done:
return
if not self._started:
if not self._ShouldStartStateMachine():
logging.info('StateMachine cannot start.')
return
self._started = True
state = self._modem.Get(mm1.I_MODEM, 'State')
func = self._trans_func_map.get(state, None)
if func and func(self):
gobject.idle_add(StateMachine.Step, self)
else:
self._done = True
def _GetModemStateFunctionMap(self):
"""
Returns a mapping from modem states to corresponding transition
functions to execute. The returned function's signature must match:
StateMachine -> Boolean
The first argument to the function is a state machine, which will
typically be passed a value of |self|. The return value, if True,
indicates that the state machine should keep executing further state
transitions. A return value of False indicates that the state machine
will transition to a terminal state.
This method must be implemented by a subclass. Subclasses can further
override this method to provide custom functionality.
"""
raise NotImplementedError()
def _ShouldStartStateMachine(self):
"""
This method will be called when the state machine is in a starting
state. This method should return True, if the state machine can
successfully begin its state transitions, False if it should not
proceed. This method can also raise an exception in the failure case.
In the success case, this method should also execute any necessary
initialization steps.
This method must be implemented by a subclass. Subclasses can
further override this method to provide custom functionality.
"""
raise NotImplementedError()