[sip-comm] Re: Question on Presence Management in Java


#1

Hi again,

I found one solution that I thought I should share with you. It's not the
best solution since it ties up a thread with a timer, but it works. It's
based on checking the position of the mouse pointer every few seconds and
considering the user to be away when enough time has expired with no mouse
movement.

Once again, this method works but it's not great. Any input would still be
much appreciated.

/**

* A class that monitors user presence (whether the user's actually at
his/her

* desk using the computer) and fires an event when that status changes.

···

*

* This class is meant to be used as a ComponentRegistry singleton

* @author patrick.arnesen

*/

public class UserPresenceMonitor extends LoggingComponentRegistryUser

{

    private static final int CheckPeriodMillis = 5000;

    private static final int DefaultTimeoutMinutes = 6;

    private PointerInfo m_lastPointerInfo;

    private Timer m_timer;

    private int m_numChecksWithNoMouseMovement = 0;

    private boolean m_isUserPresent = true;

    private int m_numChecksThreshold;

    private PolisEvent<UserPresenceMonitor, Boolean>
m_userPresenceChangedEvent;

    public UserPresenceMonitor(ComponentRegistry creg)

    {

        super(creg);

        m_numChecksThreshold = calculateNumChecksThreshold();

        m_userPresenceChangedEvent =

            new PolisEvent<UserPresenceMonitor, Boolean>(creg, this);

    }

    public synchronized void start()

    {

        if(m_timer == null)

        {

            resetState();

            m_timer = new Timer(CheckPeriodMillis, new ActionListener()

            {

                public void actionPerformed(ActionEvent e)

                {

                    handleTimerEvent();

                }

            });

            m_timer.start();

            m_logger.info("User Presence Monitoring Started. NumChecks: " +
m_numChecksThreshold);

        }

    }

    public synchronized void stop()

    {

        if(m_timer != null)

        {

            m_timer.stop();

            m_timer = null;

            m_logger.info("User Presence Monitoring Stopped");

        }

    }

    public synchronized boolean isUserPresent()

    {

        return m_isUserPresent;

    }

    /**

     * This event fires on the swing thread

     *

     * boolean indicates user presence: true for present, false for away

     */

    public PolisEvent<UserPresenceMonitor, Boolean>
getUserPresenceChangedEvent()

    {

        return m_userPresenceChangedEvent;

    }

    private void resetState()

    {

        m_timer = null;

        m_lastPointerInfo = null;

        m_numChecksWithNoMouseMovement = 0;

        m_isUserPresent = true;

    }

    private void handleTimerEvent()

    {

        try

        {

            if(hasMouseMoved())

            {

                m_numChecksWithNoMouseMovement = 0;

                setIsUserPresent(true);

            }

            else

            {

                m_numChecksWithNoMouseMovement++;

                if(m_numChecksWithNoMouseMovement == m_numChecksThreshold)

                {

                    setIsUserPresent(false);

                }

            }

            m_logger.detail("NumChecksWithNoMouseMovement = " +
m_numChecksWithNoMouseMovement);

        }

        catch(Throwable ex)

        {

            m_logger.error(ex);

        }

    }

    private void setIsUserPresent(boolean isUserPresent)

    {

        if(m_isUserPresent != isUserPresent)

        {

            m_isUserPresent = isUserPresent;

            m_logger.info("User Presence Value Changed: " + isUserPresent);

            m_userPresenceChangedEvent.fire(isUserPresent);

        }

    }

    private boolean hasMouseMoved()

    {

        boolean hasMouseMoved = true; //assume true between 0 and the first
check.

        PointerInfo newPointerInfo = MouseInfo.getPointerInfo();

        if(m_lastPointerInfo != null)

        {

            hasMouseMoved = !(

newPointerInfo.getDevice().equals(m_lastPointerInfo.getDevice()) &&

newPointerInfo.getLocation().equals(m_lastPointerInfo.getLocation()));

        }

        m_lastPointerInfo = newPointerInfo;

        return hasMouseMoved;

    }

    private int calculateNumChecksThreshold()

    {

        Integer timeout =
m_creg.getConfig().getInt("MonitorUserPresenceTimeoutMinutes");

        timeout = timeout != null ? timeout : DefaultTimeoutMinutes;

        return (int) ((timeout * DateUtils.Minute) / CheckPeriodMillis);

    }

}

Patrick Arnesen

patrick.arnesen@vivraterra.com

604-312-5212

VivraTerra Software Corp

Makers of PolisT Group Productivity Software

www.vivraterra.com

VivraTerra Logo Polis Logo