chxavplayview.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:44k
- /************************************************************************
- * chxavplayview.cpp
- * -----------------
- *
- * Synopsis:
- * Contains the implementation of the CHXAvPlayView class. This class
- * will control actual playback once a file/url has been selected for play.
- *
- * Target:
- * Symbian OS
- *
- *
- * (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
- *
- ************************************************************************/
- // Symbian includes...
- #include <coeccntx.h>
- #include <eikbtgpc.h>
- #include <eikmenub.h>
- #include <eikmenup.h>
- #include <eikfutil.h>
- #include <eikenv.h>
- #include <eikappui.h>
- #include <eikapp.h>
- #include <eikdoc.h>
- #include <avkon.hrh>
- #include <avkon.rsg>
- #include <eikmenup.h>
- #include <eikon.hrh>
- #include <aknviewappui.h>
- #include <apchangeobserver.h>
- // Helix includes...
- #include "hxassert.h"
- #include "ihxpckts.h"
- #include "hxstring.h"
- #include "hxurl.h"
- // Includes for this project...
- #include "hxsym_debug.h"
- #include "realplayer.rsg"
- #include "realplayer.mbg"
- #include "chxavplayer.h"
- #include "chxavplayerui.h"
- #include "chxavfilestore.h"
- #include "chxavfileui.h"
- #include "chxavclipinfolist.h"
- #include "chxavconfignames.h"
- #include "chxavinfolistpopup.h"
- #include "chxavcleanupstack.h"
- #include "chxavnavipanecontrol.h"
- #include "chxavplaylistnavicontrol.h"
- #include "chxavplayviewwindow.h"
- #include "chxavplayerstate.h"
- #include "chxavviewbase.h"
- #include "chxavplayview.h"
- #include "hxapihelp.h"
- #include "hxsym_leaveutil.h"
- #include "chxavcleanstring.h"
- #include "realplayer.hrh"
- #include "chxavnetconnectui.h"
- #include "chxavplayerr.h"
- namespace
- {
- // how long to show non-default navi control after user action
- const TUint k_msShowTempNavi = 1000;
-
- // how often to reset inactivity timer so backlight stays on during a video presentation
- const TUint k_msBacklightInterval = 5000;
- }
- /*
- * CHXAvPlayView
- * -------------
- * Constructor.
- *
- */
- CHXAvPlayView::CHXAvPlayView(TInt viewIndex, CHXAvPlayerUI *playerUI)
- : CHXAvViewBase(viewIndex, playerUI)
- , m_bViewPlaylistMode(false)
- , m_bEnsureResumeOnExitPlaylistMode(false)
- , m_lastPhoneState(ESACallNone)
- , m_msSeekStep(0)
- , m_bShutDownOnViewDeactivate(true)
- {
- }
- /*
- * ~CHXAvPlayView
- * --------------
- * Destructor.
- *
- */
- CHXAvPlayView::~CHXAvPlayView()
- {
- // player may not be shutdown yet (e.g., exiting from 'child' view)
- HX_ASSERT(m_player);
- if( m_player )
- {
- m_player->ShutDown();
- m_player->GetPlayerState().RemoveObserver(this);
- }
- }
- /*
- * ConstructL
- * ----------
- * Construction of elements.
- *
- */
- void CHXAvPlayView::ConstructL()
- {
- BaseConstructL(R_AVP_PLAYER_VIEW_INFO);
- // timer for hiding volume control after user interaction delay
- const CHXAvCommand& cmdHide =
- MakeCommand(this, &CHXAvPlayView::HideTempNaviControlNowL);
- m_cbTempNaviDisplay.ConstructL(cmdHide);
- // timer for periodically resetting backlight so it stays on while playing
- const CHXAvCommand& cmdBacklight =
- MakeCommand(this, &CHXAvPlayView::OnBacklightTimer);
- m_cbBacklight.ConstructL(cmdBacklight);
- // see SetEndSeekCallback()
- const CHXAvCommand& cmdEndSeek = MakeCommand(this, &CHXAvPlayView::OnEndSeekCallback);
- m_cbEndSeek.ConstructL(cmdEndSeek);
-
- // watch for phone call events
- const CHXAvCommand& cmdOnPhoneEvent =
- MakeCommand(this, &CHXAvPlayView::OnPhoneEvent);
- m_saWatcher.ConstructL(KUidCurrentCall, CActive::EPriorityHigh);
- m_lastPhoneState = m_saWatcher.GetSa().GetState(KUidCurrentCall);
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::ContructL(): current phone state = %ldn", m_lastPhoneState));
- m_saWatcher.SetEventActionL(cmdOnPhoneEvent);
- m_saWatcher.StartWatching();
- // command to execute if user cancels while connecting
- const CHXAvCommand& cmdCancelConnect =
- MakeCommand(this, &CHXAvPlayView::OnUserCancelConnect);
- m_spNetConnectUi = new (ELeave) CHXAvNetConnectUI();
- m_spNetConnectUi->ConstructL(m_playerUI->GetClientEngineManager()->GetEngine(), cmdCancelConnect);
- m_player = new (ELeave) CHXAvPlayer();
- m_player->ConstructL(m_playerUI->GetClientEngineManager(), m_spNetConnectUi);
- }
- ////////////////////////////////////////
- //
- void
- CHXAvPlayView::HandleVolumeCommand(TInt idCmd)
- {
- switch(idCmd)
- {
- case EVolUp:
- m_player->StepVolume(1);
- if( m_player->IsMuted())
- {
- // unmute
- m_player->Mute(false);
- }
-
- break;
- case EVolDown:
- m_player->StepVolume(-1);
- if( m_player->GetVolume() == 0 )
- {
- // ensure mute
- m_player->Mute(true);
- }
- else
- {
- // ensure not muted after user volume change to (still) positive volume level
- m_player->Mute(false);
- }
- break;
- default:
- HX_ASSERT(false);
- break;
- }
- }
- ////////////////////////////////////////////////
- //
- void CHXAvPlayView::DoExitPlaylistModeL(bool bPlayCurrent)
- {
- m_bViewPlaylistMode = false;
- DeactivateNaviPlaylistControl();
- if(bPlayCurrent && m_player->CanResume() )
- {
- m_player->PlayCurrent();
- }
- else
- {
- UpdateSoftkeyMenuStateL();
- }
- }
- ////////////////////////////////////////////////
- // activate navi playlist control with auto-hide timer ON so
- // it hides after a brief display
- void CHXAvPlayView::ShowTempPlaylistControlL()
- {
- if(!m_bViewPlaylistMode)
- {
- ActivateNaviPlaylistControlL(k_msShowTempNavi);
- m_naviPane->PushL(*m_spNaviPlaylistDecorator);
- }
- }
- ////////////////////////////////////////////////
- //
- // check for playlist-related commands
- //
- // return 'false' if we should continuing handling command
- //
- bool CHXAvPlayView::TryHandlePlaylistCommandL(TInt command)
- {
- bool bWasHandled = true;
- if(m_player->IsPlaylistLoaded() && m_player->GetPlaylistItemCount() > 1 )
- {
- switch(command)
- {
- case EShowPlaylistInfo:
- HX_ASSERT(!m_bViewPlaylistMode);
- ShowTempPlaylistControlL();
- break;
- case EEnterPlaylistMode:
- //HX_ASSERT(!m_bViewPlaylistMode);
- if( !m_bViewPlaylistMode )
- {
- m_bEnsureResumeOnExitPlaylistMode = m_player->IsPlaying();
- m_bViewPlaylistMode = true;
- UpdateSoftkeyMenuStateL();
-
- // activate navi playlist control with auto-hide timer OFF
- ActivateNaviPlaylistControlL(0);
- m_naviPane->PushL(*m_spNaviPlaylistDecorator);
- }
- break;
- case EExitPlaylistMode:
- HX_ASSERT(m_bViewPlaylistMode);
- if( m_bViewPlaylistMode)
- {
- DoExitPlaylistModeL(m_bEnsureResumeOnExitPlaylistMode);
-
- }
- break;
- case ENextClip:
- m_player->AdvancePlaylist(CHXAvPlayer::advanceNext | CHXAvPlayer::advanceLoop);
- ShowTempPlaylistControlL();
- if(!m_bViewPlaylistMode && m_player->CanResume())
- {
- m_player->PlayCurrent();
- }
- break;
- case EPrevClip:
- m_player->AdvancePlaylist(CHXAvPlayer::advancePrev | CHXAvPlayer::advanceLoop);
- ShowTempPlaylistControlL();
- if(!m_bViewPlaylistMode && m_player->CanResume())
- {
- m_player->PlayCurrent();
- }
- break;
- case EShowDefaultMenu:
- DoExitPlaylistModeL(false);
- HandleShowPopupL();
- break;
- default:
- bWasHandled = false;
- break;
- }
- }
- else
- {
- switch(command)
- {
- // ignore these when playlist not loaded
- case EShowPlaylistInfo:
- case EEnterPlaylistMode:
- case EExitPlaylistMode:
- case ENextClip:
- case EPrevClip:
- break;
- default:
- bWasHandled = false;
- break;
- }
- }
-
- return bWasHandled;
- }
- void CHXAvPlayView::DoTogglePlayState()
- {
- if (m_player->IsPaused())
- {
- m_player->Resume();
- }
- else if (m_player->IsStopped())
- {
- m_player->PlayCurrent();
- }
- else
- {
- m_player->Pause();
- }
- }
- /*
- * HandleSeekKeyCommand
- * --------------------
- * User pressed seek forward/back key.
- *
- */
- void
- CHXAvPlayView::HandleSeekKeyCommand(bool bForward)
- {
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::HandleSeekKeyCommand('%s')n", dbg::Bool(bForward)));
- if (m_player->IsSeeking())
- {
- HX_ASSERT(!m_player->GetClipInfo().IsLive());
- UINT32 newTime = m_player->GetClipTime();
-
- m_msSeekStep = GetNextSeekStep(m_msSeekStep);
- if( bForward )
- {
- // ok if we go past duration -- player handles it by moving to next clip (or stopping)
- newTime += m_msSeekStep;
- }
- else
- {
- newTime = m_player->GetClipTime();
- if( newTime > m_msSeekStep )
- {
- newTime -= m_msSeekStep;
- }
- else
- {
- newTime = 0;
- }
- }
- m_player->SetSeekPoint(newTime);
- }
- }
- ////////////////////////////////////////
- //
- void CHXAvPlayView::DoViewClipInfoL()
- {
- CHXAvClipInfoList* pList = new (ELeave) CHXAvClipInfoList();
- AUTO_PUSH_POP(pList);
- pList->ConstructL();
- pList->BuildClipInfoL(m_player);
- CHXAvInfoListPopup* pPopup = new (ELeave) CHXAvInfoListPopup();
- // save cleanupstack init until LD
- {
- AUTO_PUSH_POP(pPopup);
- pPopup->ConstructL( CHXAvCleanString(R_AVP_CLIPINF_TITLE)(), pList);
- }
- pPopup->ExecuteLD();
- }
- ////////////////////////////////////////
- //
- void
- CHXAvPlayView::DoSaveL()
- {
- //
- // perform action based on type of URL:
- //
- // local ram url -> copy ram file
- // local rm url -> copy file
- // network url -> create link
- //
- CHXString strSource;
- bool bUserCancelled = false;
- bool bSavingPlaylist = false;
- // save playlist or current clip that is playing?
- if( m_player->IsPlaylistLoaded() && m_player->GetPlaylistItemCount() > 1)
- {
- // query user: playlist or current clip
- TInt idxSel = 0;
- CAknListQueryDialog* pDlg = new (ELeave) CAknListQueryDialog(&idxSel);
- TInt ret = pDlg->ExecuteLD(R_AVP_SELECT_SAVE_SOURCE_DLG);
- if(ret != 0)
- {
- //HX_ASSERT((ret == EAknSoftkeyOk) || (ret == EAknSoftkeyYes));
- bool bCopyRam = (idxSel == 0);
- if( bCopyRam )
- {
- // save playlist (ram)
- bSavingPlaylist = true;
- strSource = m_player->GetMainURL();
- }
- }
- else
- {
- bUserCancelled = true;
- }
- }
- if(!bUserCancelled)
- {
-
- const CHXAvVector<CHXAvMediaFolderInfoPtr>& storeInfo = m_playerUI->GetMediaStoreInfoL();
- // XXXLCM automatic smart pointer not cleanup stack safe
- // set an arbitrary 'current path' for the file store
- CHXAvFileStorePtr spStore = new (ELeave) CHXAvFileStore();
- spStore->ConstructL(storeInfo[0]->GetRoot());
- CHXAvFileUIPtr spFileUi = new (ELeave) CHXAvFileUI();
- spFileUi->ConstructL(m_playerUI, spStore);
- if(strSource.IsEmpty())
- {
- // set source file to current URL
- strSource = m_player->GetPlayURL();
- }
- HX_ASSERT(!strSource.IsEmpty());
- CHXAvCleanString urlText(strSource);
-
- if( CHXAvUtil::IsLocal(urlText()))
- {
- //
- // copy file
- //
- // use source filename for default name
- // url may be escaped; get unescaped path-only portion
- // (e.g., realnetworksrootfoo.rm)
- HBufC* pSrcPath = CHXAvUtil::AllocStdPathFromPlayerUrlL(urlText());
- AUTO_PUSH_POP_DEL(pSrcPath);
- bool bIsValidLocalPath = CHXAvFile::PathExists(*pSrcPath);
- HX_ASSERT(bIsValidLocalPath); // menu item should be hidden to prevent this
- if( bIsValidLocalPath )
- {
- if( bSavingPlaylist )
- {
- spFileUi->DoSavePlaylistL(*pSrcPath, KNullDesC);
- }
- else
- {
-
- spFileUi->DoSaveClipL(*pSrcPath, KNullDesC);
- }
- }
- }
- else
- {
- //
- // create link
- //
- // set default link name to clip display title
- HBufC* pTitleText = CHXAvMisc::AllocTitleL(m_player);
- if(pTitleText)
- {
- AUTO_PUSH_POP_DEL(pTitleText);
- spFileUi->DoCreateLinkL(strSource, *pTitleText);
- }
- else
- {
- spFileUi->DoCreateLinkL(strSource, KNullDesC);
- }
-
- }
- }
- }
- ////////////////////////////////////////////////
- // we want to delay a bit (i.e., after the last seek key press)
- // before telling the player to end seeking (and resume play at
- // new point);
- //
- // this allows for a user entering a series of quick key presses and
- // avoids excessive start and end seek commands
- //
- void CHXAvPlayView::SetEndSeekCallback(bool bEnable)
- {
- if(bEnable && m_player->IsSeeking())
- {
- const TUint32 k_msEndSeekDelay = 400;
- m_cbEndSeek.Set(k_msEndSeekDelay);
- }
- else
- {
- m_cbEndSeek.Stop();
- }
- }
- ////////////////////////////////////////////////
- // see SetEndSeekCallback()
- void CHXAvPlayView::OnEndSeekCallback()
- {
- // only call end seek if we are still in seek mode; it is possible that
- // state changed (e.g., stop requested) since we set the end seek callback
- if( m_player->IsSeeking() )
- {
- m_player->EndSeek();
- }
- }
- /*
- * EnterSeekMode
- * -------------
- * Start and end seek.
- *
- */
- void
- CHXAvPlayView::EnterSeekMode(bool bEnter)
- {
- if (bEnter)
- {
- m_msSeekStep = 0;
- SetEndSeekCallback(false);
- // player may be seeking in case where end seek callback was pending
- if (!m_player->IsSeeking() && m_player->CanSeek())
- {
- // on-demand clip is seek-able
- m_player->StartSeek();
- }
- }
- else
- {
- // don't do seek right away (see SetEndSeekCalback)
- SetEndSeekCallback(true);
- }
-
- }
- /*
- * GetNextSeekStep
- * ---------------
- * Seek in larger steps as a seek key is held down, up to an absolute max step.
- *
- */
- UINT32
- CHXAvPlayView::GetNextSeekStep(UINT32 msSeekStep)
- {
- const UINT32 ONE_SECOND_MS = 1000;
- const UINT32 BIG_SEEK_DIV_MS = 20; // 5 % per step
- if (m_player != NULL)
- {
- UINT32 duration = m_player->GetClipDuration();
- UINT32 msMaxStep = duration / BIG_SEEK_DIV_MS;
-
- if( msSeekStep != 0 )
- {
- // double current step
- msSeekStep *= 2;
- }
- else
- {
- // init first step
- msSeekStep = ONE_SECOND_MS;
- }
-
- // confine value to our limits
- msSeekStep = max(ONE_SECOND_MS, min(msSeekStep, msMaxStep));
- }
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::GetNextSeekStep(): next step = %lu ms", msSeekStep));
- return msSeekStep;
- }
- // helper
- void CHXAvPlayView::HandleShowPopupL()
- {
- // pop up left options menu
- //
- // showing a popup menu prevents us from getting the key up event; just in case,
- // ensure we deactivate the playlist control
- //
- if( m_player->IsPlaying() )
- {
- // pause or stop
- DoTogglePlayState();
- }
- if(m_player->IsPaused())
- {
- ShowPopupMenuL(R_AVP_PAUSE_MENU_BAR);
- }
- else if (m_player->IsStopped())
- {
- ShowPopupMenuL(R_AVP_STOPPED_MENU_BAR);
- }
- else if(m_player->GetClipInfo().IsLive())
- {
- ShowPopupMenuL(R_AVP_LIVE_PLAY_MENU_BAR);
- }
- }
- /*
- * HandleCommandL
- * --------------
- * Handle commands passed to us by our control and directly.
- *
- */
- void CHXAvPlayView::HandleCommandL(TInt command)
- {
- bool bWasHandled = TryHandlePlaylistCommandL(command);
- if( !bWasHandled )
- {
- switch(command)
- {
- case EPlayPause:
- HX_ASSERT(m_player->CanPause() || m_player->CanResume());
- DoTogglePlayState();
- break;
- case EStop:
- m_player->Stop();
- break;
- case EBeginSeek:
- HX_ASSERT(m_player->CanSeek());
- EnterSeekMode(true);
- break;
- case EEndSeek:
- EnterSeekMode(false);
- break;
- case ESeekForward:
- HandleSeekKeyCommand(true);
- break;
- case ESeekBack:
- HandleSeekKeyCommand(false);
- break;
- case EVolUp:
- case EVolDown:
- HandleVolumeCommand(command);
- break;
- case EMute:
- m_player->Mute(!m_player->IsMuted());
- break;
- case ESaveToFolder:
- DoSaveL();
- break;
- case EClipInfoDialog:
- DoViewClipInfoL();
- break;
- case EShowDefaultMenu:
- HandleShowPopupL();
- break;
- /*case EToggleFullScreen:
- m_wpStatusPane->MakeVisible(!m_wpStatusPane->IsVisible());
- break;*/
- default:
- CHXAvViewBase::HandleCommandL(command);
- break;
- }
- }
- }
- /*
- * UpdateViewStateL
- * ----------------
- * ensure that view is in sync with player state
- *
- */
- void CHXAvPlayView::UpdateViewStateL()
- {
- UpdateSoftkeyMenuStateL();
- UpdateTitleL();
- UpdateContextPaneL();
- UpdateNaviVolumeControlL();
- UpdateNaviPlaylistControlL();
- UpdateNaviDefaultControlL();
- }
- ////////////////////////////////////////////////////////////
- // set file to launch on next view activation
- void CHXAvPlayView::SetViewActivateClipL(const TDesC& file)
- {
- m_spViewActivateClip = file.AllocL();
- }
- /*
- * CreateViewWindowForActivatingViewL
- * -------------------
- * Construct view window needed for active view
- *
- */
- CCoeControl* CHXAvPlayView::CreateViewWindowForActivatingViewL()
- {
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::CreateViewWindowForActivatingViewL()n"));
- if(!m_spWindow)
- {
- m_spWindow = new (ELeave) CHXAvPlayViewWindow();
- m_spWindow->ConstructL(m_playerUI, this, ClientRect());
- }
- return m_spWindow.raw_ptr();
- }
- /*
- * FinishViewActivateL
- * -------------------
- * View window is active and on top of control stack. Now
- * is a good time to allocate additional resources needed
- * for the active view.
- *
- */
- void CHXAvPlayView::FinishViewActivateL()
- {
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::FinishViewActivateL()n"));
- HX_ASSERT(m_spWindow);
- CHXAvPresentationWindow* pRenderWin = m_spWindow->GetPresentationWindow();
- // shut down player by default when view deactivates
- m_bShutDownOnViewDeactivate = true;
- if( m_player->IsShutDown() )
- {
- m_player->InitPlayerL(pRenderWin);
- }
- m_player->GetPlayerState().AddObserver(m_spNetConnectUi.raw_ptr());
- m_player->GetPlayerState().AddObserver(this);
- }
- /*
- * FinishViewDeactivateL
- * ---------------------
- * Destroy resources not needed when view is inactive
- *
- */
- void CHXAvPlayView::FinishViewDeactivateL()
- {
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::FinishViewDeactivateL()n"));
- // this ensures that next view gets a restored status pane
- m_spNaviVolDecorator = 0;
- m_spNaviDefaultDecorator = 0;
- m_spNaviPlaylistDecorator = 0;
- // ensure we don't get observation messages (and try to do ui stuff in response) when inactive
- m_player->GetPlayerState().RemoveObserver(this);
- m_player->GetPlayerState().RemoveObserver(m_spNetConnectUi.raw_ptr());
- if( m_bShutDownOnViewDeactivate )
- {
- // shutting down player saves some resources and ensures no cpu is used for static rendering
- m_player->ShutDown();
- // only destroy window if player is shutdown (otherwise player site still needs presentation window)
- m_spWindow = 0;
- }
-
- m_bViewPlaylistMode = false;
- m_bEnsureResumeOnExitPlaylistMode = false;
-
- // in case we were full screen
- // m_wpStatusPane->MakeVisible(ETrue);
- }
- /*
- * OnPlayInitiate
- * --------------
- * CHXAvPlayerStateObserver
- *
- */
- void
- CHXAvPlayView::OnPlayInitiate(const char *url)
- {
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::OnPlayInitiate(): '%s'n", (const char*)url));
- UpdateContextPaneL();
- UpdateSoftkeyMenuStateL();
- UpdateTitleL();
- }
- /*
- * OnMute
- * ------
- * CHXAvPlayerStateObserver, mute.
- *
- */
- void
- CHXAvPlayView::OnMute(bool bMute)
- {
- if(bMute)
- {
- //
- // mute state is indicated on the default navi control - hide temp
- // navi control so user can see it (vol control does not show mute)
- //
- HideTempNaviControlNowL();
- }
- }
- void
- CHXAvPlayView::OnBacklightTimer()
- {
- User::ResetInactivityTime();
- }
- /*
- * OnResume
- * --------
- * CHXAvPlayerStateObserver, started playing again.
- *
- */
- void
- CHXAvPlayView::OnResume()
- {
- UpdateContextPaneL();
- UpdateSoftkeyMenuStateL();
- InitBacklightState();
- }
- /*
- * OnStop
- * ------
- * CHXAvPlayerStateObserver, stopped.
- *
- */
- void
- CHXAvPlayView::OnStop()
- {
- UpdateContextPaneL();
- UpdateSoftkeyMenuStateL();
- m_cbBacklight.Stop();
- }
- /*
- * OnPause
- * -------
- * CHXAvPlayerStateObserver, paused.
- *
- */
- void
- CHXAvPlayView::OnPause()
- {
- UpdateContextPaneL();
- UpdateSoftkeyMenuStateL();
- m_cbBacklight.Stop();
- }
- void
- CHXAvPlayView::OnAdvancePlaylist()
- {
- UpdateTitleL();
- UpdateSoftkeyMenuStateL();
- }
- /*
- * OnBeginBuffering
- * ----------------
- *
- */
- void
- CHXAvPlayView::OnBeginBuffering(bool /*bIsBegin*/)
- {
- // update everything when entering/exiting buffering state
- UpdateContextPaneL();
- UpdateSoftkeyMenuStateL();
- }
- /*
- * OnBeginSeek
- * -----------
- * CHXAvPlayerStateObserver
- *
- */
- void
- CHXAvPlayView::OnBeginSeek()
- {
- UpdateSoftkeyMenuStateL();
- // this event only happens from user interaction; override volume control
- HideTempNaviControlNowL();
- }
- /*
- * OnLoadSession
- * -------------
- * Change the softkeys to show a stop button now that we are actually playing back.
- *
- */
- void
- CHXAvPlayView::OnLoadSession(IHXRequest *request)
- {
- CHXAvURLListPtr spRecentClips = m_playerUI->GetRecentClipsList();
- // Add this url to the recent clip list...
- HX_ASSERT(spRecentClips);
- if (spRecentClips)
- {
- HBufC* pTitleText = CHXAvMisc::AllocTitleL(m_player);
- if( pTitleText )
- {
- AUTO_PUSH_POP_DEL(pTitleText);
- CHXString strUrl = m_player->GetPlayURL();
- CHXString strTitle = CHXAvStringUtils::DescToString(*pTitleText);
- CHXAvURLInfo* pInfo = new (ELeave) CHXAvURLInfo(strUrl, strTitle); //XXXLCM leave
- spRecentClips->AddHead(pInfo);
- }
- }
- UpdateContextPaneL();
- UpdateSoftkeyMenuStateL();
- UpdateTitleL();
- // this is the first time we can know this is a video presentation
- InitBacklightState();
-
- }
- void CHXAvPlayView::InitBacklightState()
- {
- if(m_player->GetClipInfo().IsVideoPresentation())
- {
- // set repeating callback for keeping backlight on
- m_cbBacklight.Set(k_msBacklightInterval, CHXAvCallback::REPEAT);
- }
- }
- /*
- * OnVolume
- * --------
- * CHXAvPlayerStateObserver, volume changing.
- *
- */
- void
- CHXAvPlayView::OnVolume(unsigned int /*percentVol*/)
- {
- //if( bIsUserCommand )
- //{
- if(!m_bViewPlaylistMode )
- {
- ActivateNaviVolumeControlL(k_msShowTempNavi);
- UpdateNaviVolumeControlL();
- m_naviPane->PushL(*m_spNaviVolDecorator);
- }
- }
- void
- CHXAvPlayView::OnNetConnect()
- {
- UpdateSoftkeyMenuStateL();
- }
- /*
- * UpdateSoftkeyMenuStateL
- * ----------------------
- * Update the softeky and menu bar based on the player state.
- *
- */
- void
- CHXAvPlayView::UpdateSoftkeyMenuStateL()
- {
- CEikMenuBar* pMenuBar = MenuBar();
- HX_ASSERT(pMenuBar);
- if(!pMenuBar)
- {
- return;
- }
- const CHXAvPlayerState& state = m_player->GetPlayerState();
-
- CHXAvPlayerState::State playState = state.GetState();
-
- TInt idMenuBar = -1;
- TInt idCba = -1;
- if( m_bViewPlaylistMode )
- {
- idCba = R_AVP_PLAYER_VIEW_PLAYLIST_MODE_CBA;
- idMenuBar = R_AVP_EMPTY_MENU_BAR;
- }
- else
- {
- switch (playState)
- {
- case CHXAvPlayerState::Stopped:
- idCba = R_AVP_PLAYER_VIEW_IDLE_CBA;
- idMenuBar = R_AVP_STOPPED_MENU_BAR;
- break;
- case CHXAvPlayerState::Paused:
- idCba = R_AVP_PLAYER_VIEW_PAUSE_CBA;
- idMenuBar = R_AVP_PAUSE_MENU_BAR;
- break;
- case CHXAvPlayerState::Initiating:
- idCba = R_AVP_PLAYER_VIEW_CONNECTING_CBA;
- idMenuBar = R_AVP_EMPTY_MENU_BAR;
- break;
- case CHXAvPlayerState::Seeking:
- idCba = R_AVKON_SOFTKEYS_EMPTY;
- idMenuBar = R_AVP_EMPTY_MENU_BAR;
- break;
- case CHXAvPlayerState::Connecting:
- idCba = R_AVP_PLAYER_VIEW_CONNECTING_CBA;
- idMenuBar = R_AVP_EMPTY_MENU_BAR;
- break;
- case CHXAvPlayerState::Playing:
- if (m_player->GetClipInfo().IsLive())
- {
- idCba = R_AVP_PLAYER_VIEW_LIVE_PLAY_CBA;
- idMenuBar = R_AVP_LIVE_PLAY_MENU_BAR;
- }
- else
- {
- idCba = R_AVP_PLAYER_VIEW_PLAY_CBA;
- idMenuBar = R_AVP_EMPTY_MENU_BAR;
- }
- break;
- default:
- break;
- }
- }
- if (idMenuBar != -1 && idCba != -1)
- {
- Cba()->SetCommandSetL(idCba);
- pMenuBar->SetMenuTitleResourceId(idMenuBar);
- if (!m_playerUI->IsDisplayingMenuOrDialog())
- {
- Cba()->DrawNow();
- }
- }
- }
- //////////////////////////////
- // update volume control (if active) to match current player volume state
- //
- void CHXAvPlayView::UpdateNaviVolumeControlL()
- {
- if( m_spNaviVolDecorator)
- {
- CAknVolumeControl* volControl = static_cast<CAknVolumeControl*>(
- m_spNaviVolDecorator->DecoratedControl());
- TUint vol = m_player->GetVolume();
- HX_ASSERT( vol >= 0 && vol <= 100);
- // scale volume to vol (0 - 100) to control setting scale (1 - 10)
- TUint scaleVol = ( 10 * (vol + 9) ) / 100;
- if( scaleVol == 0 )
- {
- scaleVol = 1;
- }
- HX_ASSERT(scaleVol >=1 && scaleVol <= 10);
- volControl->SetValue(scaleVol);
- }
- }
- ////////////////////////////////////
- //
- void CHXAvPlayView::UpdateNaviPlaylistControlL()
- {
- // nothing
- }
- ////////////////////////////////////
- //
- void CHXAvPlayView::DeactivateNaviVolumeControl()
- {
- if(m_spNaviVolDecorator)
- {
- if( m_cbTempNaviDisplay.IsPending() )
- {
- m_cbTempNaviDisplay.Stop();
- }
- m_naviPane->Pop(m_spNaviVolDecorator.Ptr());
- m_spNaviVolDecorator = 0;
- }
- }
- ////////////////////////////////////
- //
- void CHXAvPlayView::DeactivateNaviPlaylistControl()
- {
- m_bViewPlaylistMode = false;
- if(m_spNaviPlaylistDecorator)
- {
- if( m_cbTempNaviDisplay.IsPending() )
- {
- m_cbTempNaviDisplay.Stop();
- }
- m_naviPane->Pop(m_spNaviPlaylistDecorator.Ptr());
- m_spNaviPlaylistDecorator = 0;
- }
- }
- ////////////////////////////////////
- //
- void CHXAvPlayView::HideTempNaviControlNowL()
- {
- // one of these is showing; hide
- DeactivateNaviVolumeControl();
- DeactivateNaviPlaylistControl();
- // now re-display custom control
- DrawNaviDefaultControlNowL();
-
- }
- ///////////////////////////////////
- // activate volume display callback and show the control
- //
- void CHXAvPlayView::ActivateNaviVolumeControlL(TUint msHide)
- {
- // ensure playlist control is hidden
- DeactivateNaviPlaylistControl();
- if( msHide )
- {
- // set timer for hiding volume control after a delay
- m_cbTempNaviDisplay.Set(msHide);
- }
- if( !m_spNaviVolDecorator )
- {
- // R_AVKON_NAVI_PANE_RECORDER_VOLUME_INDICATOR
- m_spNaviVolDecorator = m_naviPane->CreateVolumeIndicatorL(R_AVKON_NAVI_PANE_VOLUME_INDICATOR);
- }
- }
- ///////////////////////////////////
- // activate playlist callback and show the control
- //
- void CHXAvPlayView::ActivateNaviPlaylistControlL(TUint msHide)
- {
- // ensure volume control is hidden
- DeactivateNaviVolumeControl();
- if( msHide != 0 )
- {
- // set timer for hiding playlist control after a delay
- m_cbTempNaviDisplay.Set(msHide);
- }
- else if(m_cbTempNaviDisplay.IsPending())
- {
- m_cbTempNaviDisplay.Stop();
- }
-
- if( !m_spNaviPlaylistDecorator )
- {
- // create custom navi control (status and timer, etc)
- CHXAvPlaylistNaviControl* pControl = CHXAvPlaylistNaviControl::NewL(m_player, *m_naviPane);
- AUTO_PUSH_POP(pControl);
- // draw only works well if done via the navi pane push (from the decorator)
- const CHXAvCommand& cmdRefresh =
- MakeCommand(this, &CHXAvPlayView::DrawNaviPlaylistControlNowL);
- // navi pane control must draw itself via the navi pane
- pControl->SetRefreshCommandL(cmdRefresh);
- // decorator assumes ownership of our custom control
- m_spNaviPlaylistDecorator = CAknNavigationDecorator::NewL(m_naviPane, pControl);
- }
- }
- ////////////////////////////////////////
- // update navi control so it is showing if necessary
- // and redrawn; volume control takes precedence (unless
- // user action causes navi control state change)
- //
- void CHXAvPlayView::UpdateNaviDefaultControlL()
- {
- CHXAvNaviPaneControl* pControl = 0;
- if( m_spNaviDefaultDecorator )
- {
- pControl = static_cast<CHXAvNaviPaneControl*>(m_spNaviDefaultDecorator->DecoratedControl());
- }
- else
- {
- // create custom navi control (status and timer, etc)
- pControl = CHXAvNaviPaneControl::NewL(m_player, *m_naviPane);
- AUTO_PUSH_POP(pControl);
- // draw only works well if done via the navi pane push (from the decorator)
- const CHXAvCommand& cmdRefresh =
- MakeCommand(this, &CHXAvPlayView::DrawNaviDefaultControlNowL);
- // navi pane control must draw itself via the navi pane
- pControl->SetRefreshCommandL(cmdRefresh);
- // decorator assumes ownership of our custom control
- m_spNaviDefaultDecorator = CAknNavigationDecorator::NewL(m_naviPane, pControl);
- }
- pControl->UpdateEverythingL();
- DrawNaviDefaultControlNowL();
- }
- ///////////////////////////////////
- //
- void CHXAvPlayView::OnPhoneEvent()
- {
- // phone call state changed to one of following (enums in order):
- //
- // ESACallNone,
- // ESACallVoice,
- // ESACallFax,
- // ESACallData,
- // ESACallAlerting,
- // ESACallRinging,
- // ESACallAlternating
- //
- TSysAgentEvent event = m_saWatcher.GetSaEvent();
- TInt state = event.State();
- HX_ASSERT(event.Uid() == KUidCurrentCall);
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::OnPhoneEvent(): phone state now = %ldn", state));
-
- switch(state)
- {
- case ESACallNone:
- {
- // END call
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::OnPhoneEvent(): call (type = %ld) endedn", m_lastPhoneState));
- if(ESACallData == m_lastPhoneState)
- {
- //
- // data call has ended; user will be prompted by system to re-connect modem;
- // if user opts not to reconnect, backend socket user does not get notification
- // and ends up in weird state
- //
- HaltPlayer();
- }
-
- }
- break;
- case ESACallVoice:
- case ESACallFax:
- case ESACallAlerting:
- case ESACallRinging:
- case ESACallAlternating:
- // BEGIN call
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::OnPhoneEvent(): call starting or startedn"));
- HaltPlayer(); // just in case; we expect deactivate/loose focus event as well
- break;
- default:
- // ignore....
- break;
- }
- m_lastPhoneState = state;
- }
- void CHXAvPlayView::HandleForegroundEventL(TBool bEnterForeground)
- {
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::HandleForegroundEventL(): enter = '%s'n", dbg::Bool(bEnterForeground)));
- CHXAvViewBase::HandleForegroundEventL(bEnterForeground);
- if( bEnterForeground)
- {
- // in case this is first foreground event after activation
- if(m_spViewActivateClip)
- {
- m_player->Play(*m_spViewActivateClip);
- m_spViewActivateClip = 0;
- }
- }
- else
- {
- if(m_bViewPlaylistMode)
- {
- // we may miss shift up key event if it occurs while we are not in foreground
- DoExitPlaylistModeL(false);
- }
- }
-
- }
- ////////////////////////////////////////////////
- // app is loosing focus and we are active view
- void CHXAvPlayView::HandleLosePlayFocus()
- {
- HaltPlayer();
- }
- void CHXAvPlayView::HaltPlayer()
- {
- if( m_player )
- {
- bool bIsHalted = m_player->IsStopped() || m_player->IsPaused();
- if(!bIsHalted)
- {
- if(m_player->CanPause())
- {
- m_player->Pause();
- }
- else
- {
- m_player->Stop();
- }
- }
- }
- }
- ////////////////////////////////////////
- //
- void CHXAvPlayView::DrawNaviPlaylistControlNowL()
- {
- HX_ASSERT(!m_spNaviVolDecorator);
- if( m_spNaviPlaylistDecorator)
- {
- m_naviPane->PushL(*m_spNaviPlaylistDecorator);
- }
- }
- ////////////////////////////////////////
- //
- void CHXAvPlayView::DrawNaviDefaultControlNowL()
- {
- // don't draw custom if temp control is up
- if( m_spNaviDefaultDecorator && !m_spNaviVolDecorator && !m_spNaviPlaylistDecorator)
- {
- m_naviPane->PushL(*m_spNaviDefaultDecorator);
- }
-
- }
- ////////////////////////////////////////////////
- // ensure that title reflects state of the
- // player
- //
- void CHXAvPlayView::UpdateTitleL()
- {
- DPRINTF(SYMP_INFO, ("CHXAvPlayView::UpdateTitleL()n"));
- HBufC* pTitleText = CHXAvMisc::AllocTitleL(m_player);
- if( pTitleText )
- {
- AUTO_PUSH_POP_DEL(pTitleText);
- m_titlePane->SetTextL(*pTitleText);
- }
- else
- {
- // probably means no current url, let alone a file header
- SetDefaultAppTitleL();
- }
- }
- //////////////////////////////////////////////
- // hide or show clip info based on availability
- // of clip info
- void CHXAvPlayView::InitClipInfoMenuItem(CEikMenuPane* pMenuPane)
- {
- bool bShow = (m_player->GetClipInfo().GetFileHeader(0) != 0);
- pMenuPane->SetItemDimmed(EClipInfoDialog, !bShow);
- }
- //////////////////////////////////////////////
- // hide or show playlist menu items depending
- // on whether or not a playlist is loaded
- void CHXAvPlayView::InitPlaylistMenuItems(CEikMenuPane* pMenuPane)
- {
- bool bEnable = m_player->IsPlaylistLoaded() && m_player->GetPlaylistItemCount() > 1;
- pMenuPane->SetItemDimmed(EPrevClip, !bEnable);
- pMenuPane->SetItemDimmed(ENextClip, !bEnable);
- }
- //////////////////////////////////////////////
- // hide or show save based on the currently
- // loaded url
- void CHXAvPlayView::InitSaveMenuItem(CEikMenuPane* pMenuPane)
- {
- bool bHideIt = true;
- CHXAvCleanString txtSaveUrl(m_player->GetMainURL());
- //
- // hide 'save' menu item only for local clips that:
- //
- // 1) are already under one of our media folders and not in a hidden folder
- // 2) that reference an invalid path
- //
- // note: playlists (ram's) are always local
- //
-
- if( CHXAvUtil::IsLocal(txtSaveUrl()) )
- {
- // convert file url to full local path format
- HBufC* pPath = CHXAvUtil::AllocStdPathFromPlayerUrlL(txtSaveUrl());
- AUTO_PUSH_POP_DEL(pPath);
- if( !CHXAvFile::PathExists(*pPath) )
- {
- // can't save invalid path!
- bHideIt = true;
- }
- else
- {
- //
- // XXXLCM it arguably would be a nice idea to enable save all the time (as long as path is valid);
- // this would allow one way to copy from phone to mmc (or just ability to make new copy for
- // whatever reason)
- //
- // check if path exists under a media store root; if it does, hide it (already saved)
- //
- // exception: if under the system folder (which is hidden), enable it
- //
- const CHXAvVector<CHXAvMediaFolderInfoPtr>& info = m_playerUI->GetMediaStoreInfoL();
- for(TInt idx = 0; idx < info.Nelements(); ++idx)
- {
- TPtrC folder = info[idx]->GetRoot();
- // get relative path (without drive letter)
- TInt idxStart = 0;
- if(CHXAvFile::GetDriveIndex(*pPath) >= 0)
- {
- idxStart = 2;
- }
- TPtrC relPath(pPath->Mid(idxStart));
- bool bIsUnderSystemFolder = CHXAvFile::IsSubPath(CHXAvUtil::KEPSystemFolderName, relPath);
-
- bHideIt = CHXAvFile::IsSubPath(folder, *pPath) && !bIsUnderSystemFolder;
- if( bHideIt )
- {
- // no need to keep looking...
- break;
- }
- }
- }
- }
- pMenuPane->SetItemDimmed(ESaveToFolder, bHideIt);
- /*// if it is already saved, we can add it to the pinboard
- if (bHideIt)
- {
- // add to pinboard
- m_wpContext->PinbModel().AddLinkMenuItemL(*pMenuPane, EClipInfoDialog);
- }*/
-
- }
- ////////////////////////////////////////////////
- // idle (stopped) state
- void CHXAvPlayView::InitIdleOptionsMenu(CEikMenuPane* pMenuPane)
- {
- // enable play if player can be resumed (has a(n) URL)
- TBool bEnablePlay = m_player->CanResume();
- pMenuPane->SetItemDimmed(EPlayPause, !bEnablePlay);
- // save
- InitSaveMenuItem(pMenuPane);
- // clip info
- InitClipInfoMenuItem(pMenuPane);
- // playlist items
- InitPlaylistMenuItems(pMenuPane);
-
- // mute
- TInt textResID = m_player->IsMuted() ? R_MENU_UNMUTE : R_MENU_MUTE;
- pMenuPane->SetItemTextL(EMute, textResID);
- #if(0)
- // full screen
- const bool bEnableFullScreen = false;
- if( m_player->IsStopped() && bEnableFullScreen )
- {
- // only if player stopped (until backend supports dynamic resize)
- pMenuPane->SetItemDimmed(EToggleFullScreen, EFalse);
- TInt textResID = StatusPane()->IsVisible() ? R_MENU_ENTER_FULL_SCREEN : R_MENU_EXIT_FULL_SCREEN;
- pMenuPane->SetItemTextL(EToggleFullScreen, textResID);
- }
- else
- {
- pMenuPane->SetItemDimmed(EToggleFullScreen, ETrue);
- }
- #endif
- CHXAvMisc::InitHelpMenuItem(pMenuPane);
-
- }
- ////////////////////////////////////////////////
- // items common to pause and live
- void CHXAvPlayView::InitNonIdleMenuOptions(CEikMenuPane* pMenuPane)
- {
- // mute
- TInt textResID = m_player->IsMuted() ? R_MENU_UNMUTE : R_MENU_MUTE;
- pMenuPane->SetItemTextL(EMute, textResID);
- // save
- InitSaveMenuItem(pMenuPane);
- // clip info
- InitClipInfoMenuItem(pMenuPane);
- // prev next
- InitPlaylistMenuItems(pMenuPane);
- }
- ////////////////////////////////////////////////
- //
- void CHXAvPlayView::InitLivePlayOptionsMenu(CEikMenuPane* pMenuPane)
- {
- InitNonIdleMenuOptions(pMenuPane);
- }
- ////////////////////////////////////////////////
- //
- void CHXAvPlayView::InitPausedOptionsMenu(CEikMenuPane* pMenuPane)
- {
- InitNonIdleMenuOptions(pMenuPane);
- CHXAvMisc::InitHelpMenuItem(pMenuPane);
- }
- ////////////////////////////////////////////////
- // Called when a menu pane is about to be displayed
- //
- void
- CHXAvPlayView::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* pMenuPane)
- {
- bool bInitCommonItems = true;
- //
- // note: there is no menu in play state (just cba)
- //
- DPRINTF(SYMP_WSEVENTS, ("CHXAvPlayView::DynInitMenuPaneL(id=%d)n", aResourceId));
- switch(aResourceId)
- {
- case R_AVP_PLAYER_VIEW_IDLE_MENU_PANE:
- InitIdleOptionsMenu(pMenuPane);
- break;
- case R_AVP_PLAYER_VIEW_PAUSED_MENU_PANE:
- InitPausedOptionsMenu(pMenuPane);
- break;
- case R_AVP_PLAYER_VIEW_LIVE_PLAY_MENU_PANE:
- InitLivePlayOptionsMenu(pMenuPane);
- break;
- default:
- bInitCommonItems = false;
- break;
- }
- if(bInitCommonItems)
- {
- CHXAvMisc::InitDebugMenuItemsL(pMenuPane);
- }
-
- }
- ////////////////////////////////////////////////////
- // update context pane (i.e., app icon area) to reflect player state
- //
- void CHXAvPlayView::UpdateContextPaneL()
- {
- #if(0)
- bool bShowResumePendingIcon = false;
- //
- // dim icon while playback pending unless we are running
- // embedded (in that case we don't want to overwrite the
- // container app icon)
- //
- if( !m_playerUI->IsRunningEmbedded() )
- {
- CHXAvPlayerState::State state = m_player->GetPlayerState(),GetState();
- bShowResumePendingIcon = (state == CHXAvPlayerState::Connecting);
- bShowResumePendingIcon |= (CHXAvPlayerState::NotBuffering != m_player->GetPlayerState().GetBufferState());
- }
- if(bShowResumePendingIcon)
- {
- // grey out the app icon
- m_contextPane->SetPictureFromFileL(m_playerUI->GetAppImageFilePath(),
- EMbmRealplayerQgn_menu_rp_grey_cxt, EMbmRealplayerQgn_menu_rp_grey_cxt_mask);
- }
- else
- {
- // set default icon from AIF
- m_contextPane->SetPictureToDefaultL();
- }
- #endif
- }
- ////////////////////////////////////////
- // connect note callback
- void CHXAvPlayView::OnUserCancelConnect()
- {
- m_player->Stop();
- }
- // we must be last in observer chain
- void
- CHXAvPlayView::OnError(HX_RESULT code)
- {
- //
- // lookup user error message
- //
- UINT32 ulErrorStringID = ErrorStringTable[0].m_ulErrorStringID;
- for (int i = 0;
- i < sizeof(ErrorStringTable) / sizeof(ErrorStringTable[0]); ++i)
- {
- if(ErrorStringTable[i].m_ulErrorTag == code)
- {
- ulErrorStringID = ErrorStringTable[i].m_ulErrorStringID;
- break;
- }
- }
- CHXAvCleanString errText(ulErrorStringID);
- comptr<CHXLitePrefs> prefs = m_playerUI->GetClientEngineManager()->GetPrefs();
- const bool bAppendHexCode = prefs::GetBool(prefs, CHXAV_ErrMsgIncludeCode, true);
- // Let's not do any more memory allocations than we have to if we are
- // here precisely because we are out of memory.
- if(bAppendHexCode && code != HXR_OUTOFMEMORY)
- {
- //
- // create stringified error code to append to error message text
- //
- HBufC* pCodeText = 0;
- #if defined(HELIX_FEATURE_DPRINTF)
- // get nice (translated) version of result code
- CHXString str("n");
- str += dbg::ErrorCode(code);
- pCodeText = CHXAvStringUtils::AllocTextL(str);
- #else
- // in this case, just format number
- _LIT(KErrCodeFormat, "n0x%08x");
- pCodeText = CHXAvStringUtils::AllocFormatTextHexArgL(KErrCodeFormat, code);
- #endif
- AUTO_PUSH_POP_DEL(pCodeText);
- //
- // form message: user text + appended error code
- //
- HBufC* pFullText = CHXAvStringUtils::AllocTextL(errText(), *pCodeText);
- AUTO_PUSH_POP_DEL(pFullText);
- CHXAvMessageDialog::DoAlertErrorL(*pFullText);
- }
- else
- {
- CHXAvMessageDialog::DoAlertErrorL(errText());
- }
- }