--- a/camerauis/cameraxui/cxui/src/cxuiapplicationframeworkmonitorprivate.cpp Tue Aug 31 15:03:46 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,495 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-#include <QObject>
-
-#ifdef Q_OS_SYMBIAN
-#include <e32cmn.h>
-#include <w32std.h>
-#include <apgwgnam.h>
-#include <apgtask.h>
-#include <eikenv.h>
-#include <avkondomainpskeys.h> // keyguard state
-#include <hwrmpowerstatesdkpskeys.h> // battery status
-#include <UsbWatcherInternalPSKeys.h> // usb status
-#include <usbman.h>
-#include <usbpersonalityids.h>
-
-#include <QMetaEnum>
-#include <QString>
-#include <QVariant>
-#include <QTimer>
-#include <qsymbianevent.h>
-
-#endif // Q_OS_SYMBIAN
-
-#include "cxutils.h"
-#include "cxuieventlog.h"
-#include "cxuiapplication.h"
-#include "cxesettings.h"
-#include "cxuiapplicationframeworkmonitorprivate.h"
-
-namespace{
- const int CXUI_USB_MODE_CHECK_TIMER_DELAY = 1000; // 1 second
-}
-
-#ifdef Q_OS_SYMBIAN
-namespace
-{
- inline QString convertTDesC2QString(const TDesC& aDescriptor)
- {
- #ifdef QT_NO_UNICODE
- return QString::fromLocal8Bit(aDescriptor.Ptr(), aDescriptor.Length());
- #else
- return QString::fromUtf16(aDescriptor.Ptr(), aDescriptor.Length());
- #endif
- }
-
- inline QString windowGroupName(RWsSession& ws, int id)
- {
- TBuf<CApaWindowGroupName::EMaxLength> name;
- ws.GetWindowGroupNameFromIdentifier(id, name);
- // Window group name contains "null" characters,
- // which are considered end-of-string if not replaced.
- for (int i=0; i < name.Length(); i++) {
- if (name[i] == NULL) {
- name[i] = ' ';
- }
- }
- return convertTDesC2QString(name);
- }
-
- inline QString bitString(int number, char fill = '0', int width = 32)
- {
- return QString::number(number, 2).rightJustified(width, fill);
- }
-
- //!@todo: Avkon UIDs not needed once device dialogs fully implemented in Orbit.
-
- // AknCapServer
- static const unsigned int UID_AKNCAPSERVER = 0x10207218;
-
- // Phone ui
- static const unsigned int UID_PHONEUI = 0x100058B3;
- // Task switcher
- static const unsigned int UID_TASKSWITCHER = 0x2002677D;
- // Dialog server
- static const unsigned int UID_DIALOGAPPSERVER = 0x20022FC5;
-
- // Log event types
- static const char *EVENT_USB = "usb";
- static const char *EVENT_FOREGROUND = "foreground";
-}
-#endif // Q_OS_SYMBIAN
-
-
-/*!
-* Constructor
-*/
-CxuiApplicationFrameworkMonitorPrivate::CxuiApplicationFrameworkMonitorPrivate(CxuiApplicationFrameworkMonitor *parent,
- CxuiApplication &application,
- CxeSettings& settings)
- : q(parent),
- mApplication(application),
- mSettings(settings),
-#ifdef Q_OS_SYMBIAN
- mWsSession(CCoeEnv::Static()->WsSession()),
- mWindowGroup(CCoeEnv::Static()->RootWin()),
- mWindowGroupId(mWindowGroup.Identifier()),
- mWindowGroupName(),
- mKeyLockState(EKeyguardNotActive),
- mBatteryStatus(EBatteryStatusUnknown),
- mUsbPersonality(0),
- mUsbModeCheckTimer(this),
- mEventLog(NULL),
-#endif // Q_OS_SYMBIAN
- mState(CxuiApplicationFrameworkMonitor::ForegroundOwned)
-{
- CX_DEBUG_ENTER_FUNCTION();
-#ifdef Q_OS_SYMBIAN
- mWindowGroup.EnableFocusChangeEvents();
- mWindowGroupName = windowGroupName(mWsSession, mWindowGroupId);
- mEventLog = new CxuiEventLog("CxuiApplicationFrameworkMonitorPrivate");
- init();
- mUsbModeCheckTimer.setSingleShot(true);
- mUsbModeCheckTimer.setInterval(CXUI_USB_MODE_CHECK_TIMER_DELAY);
- connect(&mUsbModeCheckTimer, SIGNAL(timeout()),
- this, SLOT(usbModeCheckTimerCallback()));
-#endif // Q_OS_SYMBIAN
- CX_DEBUG_EXIT_FUNCTION();
-}
-
-/*!
-* Destructor
-*/
-CxuiApplicationFrameworkMonitorPrivate::~CxuiApplicationFrameworkMonitorPrivate()
-{
- CX_DEBUG_ENTER_FUNCTION();
-#ifdef Q_OS_SYMBIAN
- delete mEventLog;
-#endif // Q_OS_SYMBIAN
- CX_DEBUG_EXIT_FUNCTION();
-}
-
-/*!
-* Current foreground owning state of this application.
-* @return Foreground owning state.
-*/
-CxuiApplicationFrameworkMonitor::ForegroundState CxuiApplicationFrameworkMonitorPrivate::foregroundState() const
-{
- return mState;
-}
-
-/*!
-* Is USB connected in mass memory mode?
-* @return True if USB mass memory mode is active and connected, false otherwise.
-*/
-bool CxuiApplicationFrameworkMonitorPrivate::isUsbMassMemoryModeActive() const
-{
- bool active(false);
-#ifdef Q_OS_SYMBIAN
- // Mass memory mode activity can be seen from the KUsbWatcherSelectedPersonality property.
- // When USB is connected in Mass Memory Mode, we get KUsbPersonalityIdMS as personality id.
- // If USB is not connected, personality id is KUsbWatcherSelectedPersonalityNone.
- active = (mUsbPersonality == KUsbPersonalityIdMS);
-#endif // Q_OS_SYMBIAN
- return active;
-}
-
-
-
-#ifdef Q_OS_SYMBIAN
-/*!
-* Slot to handle Symbian event.
-* @param event Symbian event to be handled. (Ownership not taken.)
-*/
-void CxuiApplicationFrameworkMonitorPrivate::handleEvent(const QSymbianEvent *event)
-{
- // We receive tons of these events, so function start and end traces
- // are intentionally left out.
-
- if (event) {
- switch (event->type()) {
- case QSymbianEvent::WindowServerEvent:
- handleWindowServerEvent(event);
- break;
- }
- }
-}
-
-/*!
-* Handle changes in RProperty values of keylock state and battery status.
-* @param uid Category uid of the changed property.
-* @param key Integer key of the changed property.
-* @param value New value of the changed property.
-*/
-void CxuiApplicationFrameworkMonitorPrivate::handlePropertyEvent(long int uid, unsigned long int key, QVariant value)
-{
- CX_DEBUG_ENTER_FUNCTION();
-
- if (uid == KPSUidAvkonDomain.iUid && key == KAknKeyguardStatus) {
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - keylock status changed: %d -> %d", mKeyLockState, value.toInt()));
-
- // Check if the keylock value has actually changed
- const int newKeyLockState = value.toInt();
- if (newKeyLockState != mKeyLockState) {
- mKeyLockState = newKeyLockState;
- // Set foreground state based on keylock status and focused application info.
- setState(getCurrentState());
- }
- } else if (uid == KPSUidHWRMPowerState.iUid && key == KHWRMBatteryStatus ) {
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - battery status changed: %d -> %d", mBatteryStatus, value.toInt() ));
-
- // If status changed, check if battery is going empty.
- const int newBatteryStatus = value.toInt();
- if (newBatteryStatus != mBatteryStatus) {
- mBatteryStatus = newBatteryStatus;
-
- // Notify that battery is almost empty,
- // need to stop any recordings etc.
- if(mBatteryStatus == EBatteryStatusEmpty) {
- emit q->batteryEmpty();
- }
- }
- } else if (uid == KPSUidUsbWatcher.iUid && key == KUsbWatcherSelectedPersonality) {
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - usb personality changed: %d -> %d", mUsbPersonality, value.toInt()));
-
- const int newUsbPersonality(value.toInt());
- if (newUsbPersonality != mUsbPersonality) {
- // Check before saving the new state if mass memory mode was active,
- // so we know when to emit the unactivated signal.
- const bool wasUsbMassMemoryModeActive(isUsbMassMemoryModeActive());
- // Store new state.
- mUsbPersonality = newUsbPersonality;
-
- // Save state to log.
- if (mEventLog) {
- mEventLog->append(EVENT_USB, QString::number(mUsbPersonality));
- }
-
- // Check if mass memory mode activity changed.
- if (wasUsbMassMemoryModeActive != isUsbMassMemoryModeActive()) {
-
- // If the massmemory mode switched from on to off,
- // the signal is emitted immediately.
- // If the switch is from off to on, we need to use a timer
- // as a workaround because plugging in the USB charger
- // sends a mass memory mode change event.
- if (wasUsbMassMemoryModeActive) {
- emit q->usbMassMemoryModeToggled(isUsbMassMemoryModeActive());
- } else {
- // (Re)starting the timer
- mUsbModeCheckTimer.stop();
- mUsbModeCheckTimer.start();
- }
-
- }
- }
- }
-
- CX_DEBUG_EXIT_FUNCTION();
-}
-
-/*!
-* Callback function for the timer used to seperate USB charging
-* from USB mass memory mode
-*/
-void CxuiApplicationFrameworkMonitorPrivate::usbModeCheckTimerCallback()
-{
- CX_DEBUG_ENTER_FUNCTION();
-
- // if the device is still in mass memory mode after the timer has finished,
- // the device really is in massmemory mode and not plugged into the charger
- if (isUsbMassMemoryModeActive()){
- emit q->usbMassMemoryModeToggled(isUsbMassMemoryModeActive());
- }
-
- CX_DEBUG_EXIT_FUNCTION();
-}
-
-/*!
-* Set initial values.
-*/
-void CxuiApplicationFrameworkMonitorPrivate::init()
-{
- CX_DEBUG_ENTER_FUNCTION();
-
- // Connect to application (window server) events.
- connect(&mApplication, SIGNAL(symbianEvent(const QSymbianEvent *)), this, SLOT(handleEvent(const QSymbianEvent *)));
-
- QVariant value;
-
- // Get initial battery status.
- mSettings.get(KPSUidHWRMPowerState.iUid, KHWRMBatteryStatus, Cxe::PublishAndSubscribe, value);
- mBatteryStatus = value.toInt();
-
- // Get initial keylock status.
- mSettings.get(KPSUidAvkonDomain.iUid, KAknKeyguardStatus, Cxe::PublishAndSubscribe, value);
- mKeyLockState = value.toInt();
-
- // Get current USB personality
- mSettings.get(KPSUidUsbWatcher.iUid, KUsbWatcherSelectedPersonality, Cxe::PublishAndSubscribe, value);
- mUsbPersonality = value.toInt();
-
- bool ok = connect(&mSettings, SIGNAL(settingValueChanged(long int, unsigned long int, QVariant)),
- this, SLOT(handlePropertyEvent(long int, unsigned long int, QVariant)));
- CX_DEBUG_ASSERT(ok);
-
- // Get foreground state. Depends on keyguard status, so that needs to be read first.
- mState = getCurrentState();
-
- CX_DEBUG_EXIT_FUNCTION();
-}
-
-/*!
-* Helper method to handle Symbian event that specificly is of type QSymbianEvent::WindowServerEvent.
-* @param event Symbian event to be handled. (Ownership not taken.)
-*/
-void CxuiApplicationFrameworkMonitorPrivate::handleWindowServerEvent(const QSymbianEvent *event)
- {
- // We receive tons of these events, so function start and end traces
- // are intentionally left out.
-
- const TWsEvent *wsEvent = event->windowServerEvent();
- if (wsEvent) {
- switch (wsEvent->Type()) {
- case EEventFocusGroupChanged: {
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - EEventFocusGroupChanged event"));
- setState(getCurrentState());
- break;
- }
- case EEventFocusGained: {
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - EEventFocusGained event"));
- setState(getCurrentState());
- break;
- }
- case EEventFocusLost: {
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - EEventFocusLost event"));
- setState(getCurrentState());
- break;
- }
- case EEventWindowVisibilityChanged: {
- const TWsVisibilityChangedEvent *visibilityEvent = wsEvent->VisibilityChanged();
- if (visibilityEvent) {
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - EFullyVisible: bits[%s]",
- bitString(TWsVisibilityChangedEvent::EFullyVisible).toAscii().constData() ));
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - EPartiallyVisible: bits[%s]",
- bitString(TWsVisibilityChangedEvent::EPartiallyVisible).toAscii().constData() ));
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - ENotVisible: bits[%s]",
- bitString(TWsVisibilityChangedEvent::ENotVisible).toAscii().constData() ));
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - event: bits[%s]",
- bitString(visibilityEvent->iFlags).toAscii().constData() ));
- }
- break;
- }
- default:
- break;
- }
- }
-}
-
-/*!
-* Set state and emit signal if state really changes.
-* @param state New state.
-*/
-void CxuiApplicationFrameworkMonitorPrivate::setState(CxuiApplicationFrameworkMonitor::ForegroundState state)
-{
- if (mState != state) {
- const CxuiApplicationFrameworkMonitor::ForegroundState original(mState);
-
- // Check if state transition is acceptable in current state.
- switch (mState) {
- case CxuiApplicationFrameworkMonitor::ForegroundOwned:
- case CxuiApplicationFrameworkMonitor::ForegroundPartiallyLost:
- // All changes accepted.
- mState = state;
- break;
- case CxuiApplicationFrameworkMonitor::ForegroundFullyLost:
- // If foreground application is changed to note when we are already
- // fully in background, cannot accept state change to "partial foreground".
- if (state != CxuiApplicationFrameworkMonitor::ForegroundPartiallyLost) {
- mState = state;
- } else {
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - state change full bg -> partial bg ignored"));
- }
- }
-
- if (mState != original) {
- // Print the event log with this foreground event included.
- if (mEventLog) {
- mEventLog->append(
- EVENT_FOREGROUND,
- CxuiApplicationFrameworkMonitor::staticMetaObject.enumerator(
- CxuiApplicationFrameworkMonitor::staticMetaObject.indexOfEnumerator("ForegroundState")).valueToKey(mState));
- mEventLog->print();
- }
-
- // If state was changed, signal it to listeners.
- emit q->foregroundStateChanged(mState);
- }
- }
-}
-
-/*!
-* Get the current foreground state.
-* @return Current state for foreground ownership.
-*/
-CxuiApplicationFrameworkMonitor::ForegroundState CxuiApplicationFrameworkMonitorPrivate::getCurrentState()
-{
- CX_DEBUG_ENTER_FUNCTION();
-
- CxuiApplicationFrameworkMonitor::ForegroundState state(CxuiApplicationFrameworkMonitor::ForegroundOwned);
- int focusWindowGroupId(mWsSession.GetFocusWindowGroup());
-
- if (mKeyLockState != EKeyguardNotActive) {
- // Keylock enabled is the same as if other application is in foreground.
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - key lock on"));
- state = CxuiApplicationFrameworkMonitor::ForegroundFullyLost;
- } else if (focusWindowGroupId == mWindowGroupId) {
- // If our window group has focus, we clearly are the foreground owning application.
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - Foreground window group matches ours."));
- state = CxuiApplicationFrameworkMonitor::ForegroundOwned;
-
- } else {
- // Need to check if foreground is owned by known apps.
- unsigned int uid(focusedApplicationUid());
-
- // Check the app uid.
- switch (uid) {
- case UID_AKNCAPSERVER:
- case UID_TASKSWITCHER:
- case UID_DIALOGAPPSERVER:
- // Note or task switcher in foreground.
- state = CxuiApplicationFrameworkMonitor::ForegroundPartiallyLost;
- break;
- case UID_PHONEUI:
- default:
- // Foreground owned by other app.
- state = CxuiApplicationFrameworkMonitor::ForegroundFullyLost;
- break;
- }
- }
-
- CX_DEBUG_EXIT_FUNCTION();
- return state;
-}
-
-/*!
-* Get the uid of application in foreground.
-* @return Application uid for the foreground application.
-*/
-unsigned int CxuiApplicationFrameworkMonitorPrivate::focusedApplicationUid()
-{
- unsigned int uid(0);
- int focusWgId(mWsSession.GetFocusWindowGroup());
-
- TRAP_IGNORE({
- CApaWindowGroupName* wgn = CApaWindowGroupName::NewLC(mWsSession, focusWgId);
- uid = wgn->AppUid().iUid;
- CleanupStack::PopAndDestroy(wgn);
- });
-
- // If the window group identifier does not have the application uid set,
- // get it via thread secure id.
- if (uid == 0) {
- TApaTask task(mWsSession);
- task.SetWgId(focusWgId);
-
- RThread t;
- int err = t.Open(task.ThreadId());
- if (err == KErrNone) {
- uid = t.SecureId().iId;
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - uid resolved from thread"));
- }
- t.Close();
- }
-
-#ifdef CX_DEBUG
- QString name(windowGroupName(mWsSession, focusWgId));
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - Own window group id: 0x%08x", mWindowGroupId));
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - Focused window group id: 0x%08x", focusWgId));
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - Own window group name: [%s]", mWindowGroupName.toAscii().constData()));
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - Focused window group name: [%s]", name.toAscii().constData()));
- CX_DEBUG(("CxuiApplicationFrameworkMonitor - Focused application uid: 0x%08x", uid));
-#endif
-
- return uid;
-}
-
-#endif // Q_OS_SYMBIAN
-
-// end of file