phoneapp/phoneuiqtviewadapter/src/phonevisibilityhandler.cpp
author hgs
Fri, 15 Oct 2010 12:58:46 +0300
changeset 78 baacf668fe89
parent 76 cfea66083b62
permissions -rw-r--r--
201041

/*
* Copyright (c) 2010 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: Adjusts visibility of Phone app in device lock situations.
*
*/
#include <eikenv.h>
#include <xqserviceutil.h>
#include <telinformationpskeys.h>
#include <coreapplicationuisdomainpskeys.h>
#include <apgtask.h>
#include <ccallinformation.h>
#include <ccallinfoiter.h>
#include <keyguardaccessapi.h>
#include "phonevisibilityhandler.h"
#include "cphonepubsubproxy.h"
#include "phoneconstants.h"
#include "phoneuiqtviewif.h"
#include "qtphonelog.h"

/*!
    PhoneVisibilityHandler::PhoneVisibilityHandler.
 */
PhoneVisibilityHandler::PhoneVisibilityHandler(PhoneUIQtViewIF &view, QObject *parent)
    : 
    QObject(parent),
    m_view(view),
    m_eikonEnv(CEikonEnv::Static()),
    m_carModeEnabled(false),
    m_hideDeviceDialogs(false),
    m_deviceLockEnabled(false),
    m_carModeSubscriber(0),
    m_carModePublisher(0),
    m_phoneVisible(false)
{
    PHONE_TRACE
    sendToBackground(); // Send phone to background

    m_carModePublisher = new QValueSpacePublisher("/phone",this);
    m_carModePublisher->setValue(QString("/carmode"),QVariant(false));
    
    m_carModeSubscriber = new QValueSpaceSubscriber("/phone/carmode", this);
    connect(m_carModeSubscriber, SIGNAL(contentsChanged()), this, SLOT(carModeChanged()));
    m_carModeEnabled = m_carModeSubscriber->value().toBool();

    int autlockValue = CPhonePubSubProxy::Instance()->Value(
                KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus);
    m_deviceLockEnabled = (EAutolockOff < autlockValue);

    
    // Start listening to device lock changes
    QT_TRAP_THROWING(CPhonePubSubProxy::Instance()->NotifyChangeL(
            KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus, this));
    
    QT_TRAP_THROWING(CPhonePubSubProxy::Instance()->NotifyChangeL(
        KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus, this));
}


/*!
    PhoneVisibilityHandler::~PhoneVisibilityHandler.
 */
PhoneVisibilityHandler::~PhoneVisibilityHandler()
{
    PHONE_TRACE
    CPhonePubSubProxy::Instance()->CancelAllNotifications(this);
}

/*!
    PhoneVisibilityHandler::bringToForeground.
 */
void PhoneVisibilityHandler::bringToForeground()
{
    PHONE_TRACE2("m_carModeEnabled=", m_carModeEnabled)
    
    if (!m_carModeEnabled) {
        disableKeyGuard();
        adjustVisibility(BringForwards);    // change coe priority
        m_view.bringToForeground(); // change z-order
    }
}

/*!
    PhoneVisibilityHandler::bringVideoCallToForeground.
 */
void PhoneVisibilityHandler::bringVideoCallToForeground()
{
    PHONE_TRACE
    TApaTaskList taskList(m_eikonEnv->WsSession());
    const TUid KVideoTelUid = TUid::Uid(0x101F8681);
    TApaTask task = taskList.FindApp(KVideoTelUid);
    task.BringToForeground();
}

/*!
    PhoneVisibilityHandler::hideDeviceDialogs.
 */
void PhoneVisibilityHandler::hideDeviceDialogs(bool hide)
{
    PHONE_TRACE2(": hide =", hide)
    m_hideDeviceDialogs = hide;
    adjustVisibility(KeepCurrentPos);
}

/*!
    PhoneVisibilityHandler::phoneVisible.
 */
bool PhoneVisibilityHandler::phoneVisible() const
{
    PHONE_TRACE
    return m_phoneVisible;
}

/*!
     PhoneVisibilityHandler::windowVisibilityChange
 */
void PhoneVisibilityHandler::windowVisibilityChange(bool visible)
{
    PHONE_TRACE2(": visible =", visible)
    m_phoneVisible = visible;
}

/*!
    PhoneVisibilityHandler::sendToBackground.
 */
void PhoneVisibilityHandler::sendToBackground()
{
    PHONE_TRACE2(":m_carModeEnabled =", m_carModeEnabled)
    
    if(m_carModeEnabled) {
        // Don't bring homescreen to foreground
        return;
    }
    enableKeyGuard();
    // Send phone back on WSERV stack
    m_view.hide();  // change z-order
    adjustVisibility(SendToBack); // change coe priority
}

/*!
    PhoneVisibilityHandler::HandlePropertyChangedL.
 */
void PhoneVisibilityHandler::HandlePropertyChangedL(const TUid& aCategory, 
    const TUint aKey, const TInt aValue)
{
    if((aCategory == KPSUidCoreApplicationUIs) &&
            (aKey == KCoreAppUIsAutolockStatus)) {
        // Adjust visibility according mode
        m_deviceLockEnabled = (EAutolockOff < aValue);
        PHONE_TRACE2(": m_deviceLockEnabled=", m_deviceLockEnabled);
        m_view.setRestrictedMode(m_deviceLockEnabled);
        adjustVisibility(KeepCurrentPos);
    }
}

/*!
 *  PhoneVisibilityHandler::disableKeyGuard().
 */
bool PhoneVisibilityHandler::disableKeyGuard()
{
    PHONE_TRACE
    TRAP_IGNORE(
        CKeyguardAccessApi* keyguardAccess = CKeyguardAccessApi::NewL( );
        if (!m_keyguardOnBeforeForeground) {
            // Check if keyguard previous status only when it is not set
            // Keyguard status will be restored when phone is ordered to background
            m_keyguardOnBeforeForeground = keyguardAccess->IsKeyguardEnabled();
        }
        keyguardAccess->DisableKeyguard( EFalse );
        delete keyguardAccess;
        );
    
    return m_keyguardOnBeforeForeground;
}

/*!
 *  PhoneVisibilityHandler::enableKeyGuard().
 */
void PhoneVisibilityHandler::enableKeyGuard()
{
    PHONE_TRACE
    if (phoneVisible() && m_keyguardOnBeforeForeground) {
        // If phone is visible return to previous keyguard status
        TRAP_IGNORE(
            CKeyguardAccessApi* keyguardAccess = CKeyguardAccessApi::NewL( );
            keyguardAccess->EnableKeyguard( EFalse );
            delete keyguardAccess;
            );
    }
    m_keyguardOnBeforeForeground = false;
}

/*!
 *  PhoneVisibilityHandler::ongoingCalls().
 */
int PhoneVisibilityHandler::ongoingCalls()
{
    int amountOfCalls=0;
    TRAP_IGNORE(
        CCallInformation* callInfos = CCallInformation::NewL();
        CleanupStack::PushL(callInfos);
        Q_ASSERT(callInfos != 0);
        amountOfCalls = callInfos->GetCallsL().Count();
        CleanupStack::PopAndDestroy(callInfos);
        );
    return amountOfCalls;
}

/*!
    PhoneVisibilityHandler::adjustVisibility.
	 -1 Ordinal position is lowest ( not visible )
	  0 Ordinal position is highest ( visible )
	  1 - ... Ordinal postition under one or more window group
	  
	It is agreed with devicedialog that:
     - Incoming call, ECoeWinPriorityAlwaysAtFront + 100
     - Ongoing call + security, ECoeWinPriorityAlwaysAtFront + 1
     - Ongoing call, ECoeWinPriorityNormal
 */
void PhoneVisibilityHandler::adjustVisibility(AdjustAction action)
{
    PHONE_TRACE
    int ordinalPos = m_eikonEnv->RootWin().OrdinalPosition();
    if (m_carModeEnabled || (action == SendToBack)) {
        PHONE_TRACE1(": SendPhoneToBackground")
        m_eikonEnv->RootWin().SetOrdinalPosition(-1, ECoeWinPriorityNeverAtFront);
    } else if ((KeepCurrentPos == action) &&
        (m_eikonEnv->RootWin().OrdinalPriority() == ECoeWinPriorityNeverAtFront)) {
        // Skip situations where phone is put to back
        // and action is not to bring it up
        // Execution must come here if there is no calls
        PHONE_TRACE1(": Skip")
        
    } else if (m_hideDeviceDialogs) {
        PHONE_TRACE1(": Hide dialogs")
        m_eikonEnv->RootWin().SetOrdinalPosition(0, ECoeWinPriorityAlwaysAtFront + 100);
        
    } else if (m_deviceLockEnabled) {
        // critical notes are allowed to show on top of Phone application
        PHONE_TRACE1(": Devicelock")
        m_eikonEnv->RootWin().SetOrdinalPosition(0, ECoeWinPriorityAlwaysAtFront + 1);
        
    } else if (BringForwards == action) {
        // Try to show phone with normal priority
        PHONE_TRACE1(": Bring forward")
        m_eikonEnv->RootWin().SetOrdinalPosition(ordinalPos, ECoeWinPriorityNormal);
    } else {
        // Normalize visiblity after ie. device lock
        PHONE_TRACE1(": Normalize")
        m_eikonEnv->RootWin().SetOrdinalPosition(ordinalPos, ECoeWinPriorityNormal);
        // Flush is needed here, because otherwise launching an application may fail
        // if done same time with normalization.
        m_eikonEnv->WsSession().Flush();        
    }
}

void PhoneVisibilityHandler::carModeChanged()
{
    PHONE_TRACE
    m_carModeEnabled = m_carModeSubscriber->value().toBool();
    
    if(!m_carModeEnabled && (ongoingCalls() > 0)) {
        bringToForeground();
    }
    // Adjust visibility according mode (TODO!)
    PHONE_TRACE2(": m_carModeEnabled=", m_carModeEnabled)
}