javauis/mmapi_qt/baseline/src/cmmarecordcontrol.cpp
branchRCL_3
changeset 24 0fd27995241b
child 26 dc7c549001d5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/mmapi_qt/baseline/src/cmmarecordcontrol.cpp	Tue May 11 16:07:20 2010 +0300
@@ -0,0 +1,298 @@
+/*
+* Copyright (c) 2002-2007 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:  This class is a RecordControl.
+*
+*/
+
+
+//  INCLUDE FILES
+#include <logger.h>
+#include "cmmarecordcontrol.h"
+#include "cmmaplayer.h"
+
+
+_LIT(KControlName, "RecordControl");
+
+CMMARecordControl::CMMARecordControl(CMMAPlayer* aPlayer):
+        iState(ERecordUninitialized),
+        iPlayer(aPlayer),
+        iStartTime(0)
+{
+}
+
+
+CMMARecordControl::~CMMARecordControl()
+{
+    iRecordPauseTimer.Cancel();
+    iRecordPauseTimer.Close();
+
+    if (iPlayer)
+    {
+        iPlayer->RemoveStateListener(this);
+    }
+
+    delete iOutputStream;
+
+    iFile.Close();
+    iFs.Delete(iFilename);
+    iFs.Close();
+}
+
+void CMMARecordControl::WaitForPauseL(const TInt64& aMediaTime)
+{
+    // reusing time variable
+    TInt64 time = iStartTime - aMediaTime + KMinRecordPauseInterval;
+    iStartTime = 0;
+    LOG1( EJavaMMAPI, EInfo, "CMMARecordControl::WaitForPauseL wait time = %d", (TInt)time);
+    // if time > 0, time between record and pause is smaller than
+    // KMinRecordPauseInterval and we have to wait.
+    if (time > 0)
+    {
+        TRequestStatus status;
+        iRecordPauseTimer.Cancel();
+        iRecordPauseTimer.After(status, I64INT(time));
+        User::WaitForRequest(status);
+        // Status ignored because recording must be stopped.
+    }
+}
+
+void CMMARecordControl::ConstructL()
+{
+    User::LeaveIfError(iRecordPauseTimer.CreateLocal());
+
+    User::LeaveIfError(iFs.Connect());
+
+    // create temporary file for recording
+    User::LeaveIfError(iFile.Temp(iFs,
+                                  KMMARecordTempDirectory,
+                                  iFilename,
+                                  EFileRead | EFileWrite | EFileShareAny));
+
+    iPlayer->AddStateListenerL(this);
+}
+
+void CMMARecordControl::StartRecordL()
+{
+    LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::StartRecordL+");
+
+    // Initialize needs to be done only once after setRecordLocation or
+    // setRecordStream and before commit or reset. Although startRecord can be
+    // called several times in the process, the initialization must happen
+    // only in the first call to startRecord
+    if (iState == ERecordUninitialized)
+    {
+        InitializeL();
+    }
+
+    iState = ERecordStandBy;
+    // calling next state if player is already started
+    NextStateL(iPlayer->State());
+
+    iPlayer->GetMediaTime(&iStartTime);
+    iPlayer->PostLongEvent(CMMAPlayerEvent::ERecordStarted, iStartTime);
+
+    LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::StartRecordL-");
+}
+
+
+void CMMARecordControl::StopRecordL()
+{
+    LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::StopRecordL+");
+    if (iState == ERecordRecording)
+    {
+        NextStateL(iPlayer->State());
+    }
+
+    iState = ERecordInitialized;
+
+    // ask mediatime again for more accurate value
+    TInt64 time;
+    iPlayer->GetMediaTime(&time);
+    iPlayer->PostLongEvent(CMMAPlayerEvent::ERecordStopped, time);
+
+    LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::StopRecordL-");
+}
+
+
+void CMMARecordControl::CommitL()
+{
+    LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::CommitL+");
+    // reset the recorder if already initialized
+    if (iState > ERecordUninitialized)
+    {
+        DoResetL();
+    }
+    else
+    {
+        // not even initialized yet, just inform java
+        iOutputStream->WriteL(KNullDesC8);
+        return;
+    }
+    iState = ERecordUninitialized;
+
+    // Create buffer for file context
+    TInt fileSize;
+    User::LeaveIfError(iFile.Size(fileSize));
+    LOG1( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::CommitL size in bytes = %d", fileSize);
+
+    HBufC8* data = HBufC8::NewLC(fileSize);
+
+    // Read file context
+    TPtr8 dataPtr = data->Des();
+    TInt pos(0);
+    User::LeaveIfError(iFile.Seek(ESeekStart, pos));
+    User::LeaveIfError(iFile.Read(dataPtr));
+    User::LeaveIfError(iFile.SetSize(0));
+    User::LeaveIfError(iFile.Flush());
+
+    // Write whole video data to stream
+    iOutputStream->WriteL(dataPtr);
+    CleanupStack::PopAndDestroy(data);
+
+    LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::CommitL-");
+}
+
+
+void CMMARecordControl::ResetL()
+{
+    LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::ResetL+");
+    // reset the recorder if already initialized
+    if (iState > ERecordUninitialized)
+    {
+        DoResetL();
+        LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::DoResetL done");
+        iState = ERecordUninitialized;
+
+        // Empty file that it can be reused
+        User::LeaveIfError(iFile.SetSize(0));
+        User::LeaveIfError(iFile.Flush());
+    }
+
+    LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::ResetL-");
+}
+
+void CMMARecordControl::SetRecordStream(CMMAOutputStream* aStream)
+{
+    LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::SetRecordStream");
+    __ASSERT_DEBUG(aStream, User::Panic(
+                       _L("CMMAVideoRecordControl:: Stream is NULL."),
+                       KErrArgument));
+    delete iOutputStream;
+    iOutputStream = aStream;
+}
+
+
+HBufC* CMMARecordControl::GetContentTypeL()
+{
+    LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::GetContentTypeL");
+    return iPlayer->ContentType();
+}
+
+const TDesC& CMMARecordControl::ClassName() const
+{
+    return KControlName;
+}
+
+void CMMARecordControl::StateChanged(TInt aState)
+{
+    TRAPD(err, NextStateL(aState));
+    if (err)
+    {
+        Error(err);
+    }
+}
+
+void CMMARecordControl::Error(TInt aErrorCode)
+{
+    ELOG1( EJavaMMAPI, "MMA:CMMARecordControl::Error %d", aErrorCode);
+    TBuf<KRecordErrorMessageSize> errorMessage;
+    errorMessage.Format(KMMARecordErrorMsg, aErrorCode);
+    iPlayer->PostStringEvent(CMMAPlayerEvent::ERecordError,
+                             errorMessage);
+}
+
+void CMMARecordControl::HandleRecordSizeLimit()
+{
+    // commit the stream
+    iOutputStream->Commit();
+    TInt64 time;
+    iPlayer->GetMediaTime(&time);
+    iPlayer->PostLongEvent(CMMAPlayerEvent::ERecordStopped, time);
+}
+
+void CMMARecordControl::NextStateL(TInt aPlayerState)
+{
+    LOG1( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::NextStateL Player state = %d", aPlayerState);
+    LOG1( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::NextStateL internal state = %d", iState);
+    switch (iState)
+    {
+    case ERecordUninitialized:
+    {
+        LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::NextStateL: case ERecordUninitialized");
+        // This is the initial state.
+        // To getinto this state, commit or reset must be called
+        // To get out of this state startRecord must be called
+
+        break;
+    }
+    case ERecordInitialized:
+    {
+        LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::NextStateL: case ERecordInitialized");
+        // To get into this state stopRecord must be called.
+        // To get out of this state startRecord, commit or reset must be
+        // called
+        break;
+    }
+    case ERecordStandBy:
+    {
+        LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::NextStateL: case ERecordStandBy");
+        // To get into this state startRecord must be called.
+        // To get out of this state stopRecord, commit or reset must be
+        // called, or state of the Player must change to STARTED
+
+
+        // start the actual recording if player is started
+        if (aPlayerState == CMMAPlayer::EStarted)
+        {
+            LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::NextStateL: ERecordStandBy -> ERecordRecording");
+            DoStartRecordL();
+            iState = ERecordRecording;
+        }
+        break;
+    }
+    case ERecordRecording:
+    {
+        LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::NextStateL: case ERecordRecording");
+
+        // To get into this state startRecord must have been called and
+        // the Player must be in STARTED state.
+        // To get out of this state, stopRecord, commit or reset must be
+        // called or the Player must change to a state other than STARTED
+        TInt64 time;
+        iPlayer->GetMediaTime(&time);
+        WaitForPauseL(time);
+        DoStopRecordL();
+        iState = ERecordStandBy;
+        break;
+    }
+    default:
+    {
+        LOG( EJavaMMAPI, EInfo, "MMA:CMMARecordControl::NextStateL: case default - code should not reach here!!");
+        __ASSERT_DEBUG(KErrGeneral, User::Invariant());   // This will newer occur
+        break;
+    }
+    }
+}
+
+//  END OF FILE