javauis/coreui_akn/src/coreuiavkonimpl.cpp
branchRCL_3
changeset 19 04becd199f91
child 60 6c158198356e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/coreui_akn/src/coreuiavkonimpl.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,490 @@
+/*
+* 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: A CoreUi Avkon implementation.
+*
+*/
+
+#include <string.h>
+#include <apgwgnam.h>
+#include <akntitle.h>
+
+#include "logger.h"
+#include "coreuiavkonimpl.h"
+#include "javauiavkonimpl.h"
+#include "runtimeexception.h"
+#include "javacommonutils.h"
+
+using namespace java::ui;
+using namespace java::util;
+
+// ======== STATIC VARIABLES ========
+
+/**
+* Singleton
+*/
+
+NONSHARABLE_CLASS(CoreUiGlobals)
+{
+public:
+    CoreUiGlobals() : mUiCore(0)
+    {
+    }
+
+public:
+    java::ui::CoreUiAvkonImpl* mUiCore;
+};
+
+
+#if defined(__WINSCW__)
+
+#include <pls.h>
+CoreUiGlobals* getCoreUiGlobals()
+{
+    // Access the PLS of this process
+    CoreUiGlobals* globals  =
+        Pls<CoreUiGlobals>(TUid::Uid(0x2002703C));
+    return globals;
+}
+
+#else
+
+
+static CoreUiGlobals* sGlobals = 0;
+
+CoreUiGlobals* getCoreUiGlobals()
+{
+    if (sGlobals == 0)
+    {
+        sGlobals = new CoreUiGlobals(); // codescanner::nonleavenew
+    }
+    return sGlobals;
+}
+#endif
+
+
+CoreUi& getUiInstance()
+{
+    JELOG2(EJavaUI);
+    CoreUiGlobals* globals = getCoreUiGlobals();
+    if (globals->mUiCore == 0)
+    {
+        globals->mUiCore = new CoreUiAvkonImpl(); // codescanner::nonleavenew
+    }
+
+    return *globals->mUiCore;
+}
+
+void releaseUi()
+{
+    JELOG2(EJavaUI);
+    CoreUiGlobals* globals = getCoreUiGlobals();
+    if (globals->mUiCore)
+    {
+        globals->mUiCore->dispose();
+    }
+}
+
+EXPORT_C FuncPtr findDllMethod(const char* funcName)
+{
+    JELOG2(EJavaUI);
+    FuncPtr ptr = 0;
+    if (strcmp(funcName, "getUiInstance") == 0)
+    {
+        ptr = (FuncPtr)getUiInstance;
+    }
+    else if (strcmp(funcName, "releaseUi") == 0)
+    {
+        ptr = (FuncPtr)releaseUi;
+    }
+    return ptr;
+}
+
+EXPORT_C bool CoreUiAvkon::isCoreUiCreated()
+{
+    JELOG2(EJavaUI);
+    CoreUiGlobals* globals = getCoreUiGlobals();
+    return globals->mUiCore != 0;
+}
+
+EXPORT_C CoreUiAvkonLcdui& CoreUiAvkonLcdui::getInstance()
+{
+    JELOG2(EJavaUI);
+    return static_cast<CoreUiAvkonLcdui&>(
+               static_cast<CoreUiAvkonImpl&>(getUiInstance()));
+}
+
+EXPORT_C CoreUiAvkonEswt& CoreUiAvkonEswt::getInstance()
+{
+    JELOG2(EJavaUI);
+    return static_cast<CoreUiAvkonEswt&>(
+               static_cast<CoreUiAvkonImpl&>(getUiInstance()));
+}
+
+CoreUiAvkonImpl& CoreUiAvkonImpl::getInstanceImpl()
+{
+    JELOG2(EJavaUI);
+    return static_cast<CoreUiAvkonImpl&>(::getUiInstance());
+}
+
+CoreUiAvkonImpl::CoreUiAvkonImpl() : mJavaUiAvkonEnv(0), mWgName(0),
+        mJavaUiAppUi(0),
+        mState(Constructed), mShowStartScreen(true),
+        mJavaVm(0), mShutDownPending(false),
+        mShutdownTimer(0)
+{
+    JELOG2(EJavaUI);
+    mLock.CreateLocal();
+
+}
+
+
+CoreUiAvkonImpl::~CoreUiAvkonImpl()
+{
+    JELOG2(EJavaUI);
+    delete mWgName;
+    mWgName = 0;
+    mLock.Close();
+}
+
+void CoreUiAvkonImpl::ensureInitialized(const TUid& appUid,
+                                        CoreUiParams* params)
+{
+    JELOG2(EJavaUI);
+    if (mJavaUiAvkonEnv == 0)
+    {
+        java::util::Uid uid;
+        TUidToUid(appUid, uid);
+
+        start(uid, params);
+    }
+}
+
+
+CoreUiAvkonLcduiSupport& CoreUiAvkonImpl::getLcduiSupport()
+{
+    return mLcduiSupport;
+}
+
+CoreUiAvkonEswtSupport& CoreUiAvkonImpl::getEswtSupport()
+{
+    return mEswtSupport;
+}
+
+void CoreUiAvkonImpl::start(const java::util::Uid& midletUid,
+                            CoreUiParams* uiParams)
+{
+    mMidletUid = midletUid;
+    if (uiParams != 0)
+    {
+        mCoreUiParams = *uiParams;
+    }
+    mLcduiSupport.startUiThread(*this);
+}
+
+void CoreUiAvkonImpl::startScheduler()
+{
+    JELOG2(EJavaUI);
+    if (mJavaUiAvkonEnv != 0)
+    {
+        mState = CoreUiCreated;
+        mJavaUiAvkonEnv->ExecuteD();
+        cancelShutdownTimer();
+        mEswtSupport.dispose();
+        mJavaUiAvkonEnv = 0;
+        delete mWgName;
+        mWgName = 0;
+    }
+    mState = Destroyed;
+}
+
+void CoreUiAvkonImpl::createUi()
+{
+    JELOG2(EJavaUI);
+    // Construct the environment (EikonEnv + AppUi + server)
+
+    // The cleanup stack is created here
+    mJavaUiAvkonEnv = new CEikonEnv; // codescanner::nonleavenew
+
+    if (mJavaUiAvkonEnv != 0)
+    {
+        uidToTUid(mMidletUid, mMidletTUid);
+        if (mMidletUid == Uid(L"[2001843a]") || // Is it installer.
+                mMidletUid == Uid(L"[2002121e]"))    // Is it TCK runner.
+        {
+            mShowStartScreen = false;
+        }
+        TRAPD(status, initAvkonUiL());
+        if (status != KErrNone)
+        {
+            // Deletes AS and CleanupTrap. No need to call 'delete env'.
+            mJavaUiAvkonEnv->DestroyEnvironment();
+            std::string errorStr("Ui creation failed: ");
+            errorStr.append(JavaCommonUtils::intToString(status));
+            throw java::runtime::RuntimeException(errorStr, __FILE__, __FUNCTION__, __LINE__);
+        }
+        mEswtSupport.uiThreadInit();
+    }
+}
+
+void CoreUiAvkonImpl::initAvkonUiL()
+{
+    JELOG2(EJavaUI);
+    TApaApplicationFactory appFactory(newJavaApplication);
+
+    CApaCommandLine* appCmdLine = CApaCommandLine::NewLC();
+    appCmdLine->SetExecutableNameL(KNullDesC);          // None - app function provided by the app factory
+    appCmdLine->SetDefaultScreenL(0);
+    appCmdLine->SetServerNotRequiredL();                //
+    if (mCoreUiParams.isBackgroundStart())
+    {
+        appCmdLine->SetCommandL(EApaCommandBackground);
+    }
+    mJavaUiAvkonEnv->DisableExitChecks(ETrue);
+    mJavaUiAvkonEnv->ConstructAppFromCommandLineL(appFactory, *appCmdLine);
+
+    CleanupStack::PopAndDestroy(appCmdLine);
+
+    mJavaUiAvkonEnv->AppUiFactory()->StatusPane()->MakeVisible(EFalse);
+
+
+    // Contruct the WindowsGroupName, used to change the displayed name in the tasklist
+    mWgName = CApaWindowGroupName::NewL(mJavaUiAvkonEnv->WsSession());
+    mWgName->SetRespondsToSwitchFilesEvent(EFalse);
+    mWgName->SetRespondsToShutdownEvent(ETrue);
+    mWgName->SetHidden(EFalse);
+    mWgName->SetAppUid(mMidletTUid);
+    mWgName->SetWindowGroupName(mJavaUiAvkonEnv->RootWin());
+
+    mJavaUiAvkonEnv->RootWin().EnableReceiptOfFocus(ETrue);
+}
+
+
+void CoreUiAvkonImpl::dispose()
+{
+    JELOG2(EJavaUI);
+    bool canBeDisposed = mJavaUiAppUi == 0 ||
+                         (mJavaUiAppUi && mJavaUiAppUi->isClosingPossible());
+    if (canBeDisposed)
+    {
+        if (mState != Destroyed)
+        {
+            mLcduiSupport.closeUi();
+        }
+        delete this;
+        CoreUiGlobals* globals = getCoreUiGlobals();
+        globals->mUiCore = 0;
+    }
+}
+
+CApaWindowGroupName* CoreUiAvkonImpl::getWindowGroupName() const
+{
+    JELOG2(EJavaUI);
+    return mWgName;
+}
+
+bool  CoreUiAvkonImpl::showStartScreen() const
+{
+    JELOG2(EJavaUI);
+    return mShowStartScreen && mCoreUiParams.getScreenMode() != NO_START_SCREEN;
+}
+
+
+CoreUiAvkonAppUi* CoreUiAvkonImpl::getJavaUiAppUi() const
+{
+    JELOG2(EJavaUI);
+    return mJavaUiAppUi;
+}
+
+CAknAppUi* CoreUiAvkonImpl::getJavaAknAppUi() const
+{
+    JELOG2(EJavaUI);
+    return mJavaUiAppUi;
+}
+
+void CoreUiAvkonImpl::setJavaUiAppUi(JavaUiAvkonAppUi* appUi)
+{
+    JELOG2(EJavaUI);
+    mJavaUiAppUi = appUi;
+}
+
+RHeap* CoreUiAvkonImpl::getProcessHeap() const
+{
+    JELOG2(EJavaUI);
+    return mLcduiSupport.getProcessHeap();
+}
+
+RHeap* CoreUiAvkonImpl::getUiThreadHeap() const
+{
+    JELOG2(EJavaUI);
+    return mLcduiSupport.getUiThreadHeap();
+}
+
+
+bool CoreUiAvkonImpl::setJavaVm(JNIEnv* env)
+{
+    JELOG2(EJavaUI);
+    mLock.Wait();
+    bool result = false; // Meaning the starting of the MIDlet
+    // should not be allowed.
+    LOG(EJavaUI, EInfo, "Setting JavaVm");
+    if (!mShutDownPending)
+    {
+        LOG(EJavaUI, EInfo, "  No pending shutdown");
+        env->GetJavaVM(&mJavaVm); // Get pointer to VM
+        if (mJavaVm)
+        {
+            LOG(EJavaUI, EInfo, "  Got the VM");
+            result = true;
+        }
+        else
+        {
+            ELOG(EJavaUI, "JNI attachUiToVm(), GetJavaVM(() failed");
+        }
+    }
+    mLock.Signal();
+    LOG1(EJavaUI, EInfo, "CoreUiAvkonImpl::setJavaPeer result = %d", result);
+    return result;
+}
+
+void CoreUiAvkonImpl::shutDownRequestFromWindowServer()
+{
+    JELOG2(EJavaUI);
+    LOG(EJavaUI, EInfo, "shutDownRequestFromWindowServer");
+    mLock.Wait();
+    if (mState != ShuttingDown)
+    {
+        mState = ShuttingDown;
+        if (mShutdownTimer == 0)
+        {
+            TRAP_IGNORE(setShutdownTimerL());
+        }
+        LOG(EJavaUI, EInfo, "  mState != SHUTTING_DOWN");
+        if (mJavaVm) // Check if the VM already running.
+        {
+            LOG(EJavaUI, EInfo, "  We have the VM");
+
+            bool success =
+                callStaticVoidJavaMethod("com/nokia/mj/impl/coreui/CoreUi",
+                                         "shutdownRequest",
+                                         "()V");
+
+            if (!success)
+            {
+                ELOG(EJavaUI, "Killing process forcefully");
+                RProcess().Kill(-1);
+            }
+
+
+        }
+        else
+        {
+            LOG(EJavaUI, EInfo, "  Pending request");
+            // No, pend the request.
+            mShutDownPending = true;
+        }
+    }
+    mLock.Signal();
+}
+
+bool CoreUiAvkonImpl::callStaticVoidJavaMethod(const char* className,
+        const char* methodName,
+        const char* methodSignature,
+        ...)
+{
+    JELOG2(EJavaUI);
+    bool success = false;
+
+    JNIEnv* env;
+#ifdef RD_JAVA_UITHREAD_OWN_HEAP
+    User::SwitchHeap(getProcessHeap());
+#endif // RD_JAVA_UITHREAD_OWN_HEAP
+    int result = mJavaVm->AttachCurrentThread((void**)&env, 0);
+    if (result == 0)
+    {
+        LOG(EJavaUI, EInfo, "  VM Attached");
+        jclass clz = env->FindClass(className);
+        if (clz != 0)
+        {
+            LOG(EJavaUI, EInfo, "  jclass created");
+            jmethodID methodId =
+                env->GetStaticMethodID(clz, methodName, methodSignature);
+            if (methodId != 0)
+            {
+                LOG(EJavaUI, EInfo, "  methodId created");
+                va_list args;
+                va_start(args, methodSignature);
+                env->CallStaticVoidMethodV(clz, methodId, args);
+                LOG(EJavaUI, EInfo, "  CallStaticVoidMethodV done");
+                va_end(args);
+                // Close message sent successfully to Java side.
+                success = true;
+            }
+            else
+            {
+                ELOG(EJavaUI, "callStaticVoidJavaMethod, "
+                     "GetMethodID(() failed");
+            }
+            env->DeleteLocalRef(clz);
+        }
+        else
+        {
+            ELOG(EJavaUI, "callStaticVoidJavaMethod, "
+                 "GetObjectClass() failed");
+        }
+        result = mJavaVm->DetachCurrentThread();
+        LOG1(EJavaUI, EInfo, "  DetachCurrentThread done, st = %d", result);
+    }
+    else
+    {
+        ELOG(EJavaUI, "callStaticVoidJavaMethod, "
+             "AttachCurrentThread() failed");
+    }
+#ifdef RD_JAVA_UITHREAD_OWN_HEAP
+    User::SwitchHeap(getUiThreadHeap());
+#endif // RD_JAVA_UITHREAD_OWN_HEAP
+    return success;
+}
+
+void CoreUiAvkonImpl::setShutdownTimerL()
+{
+    JELOG2(EJavaUI);
+    LOG(EJavaUI, EInfo, "setShutdownTimerL");
+    mShutdownTimer = CPeriodic::NewL(CActive::EPriorityStandard);
+    mShutdownTimer->Start(8000000, 1000000,
+                          TCallBack(shutdownTimerCallback, 0));
+}
+
+void CoreUiAvkonImpl::cancelShutdownTimer()
+{
+    JELOG2(EJavaUI);
+    LOG(EJavaUI, EInfo, "cancelShutdownTimer");
+    if (mShutdownTimer)
+    {
+        if (mShutdownTimer->IsActive())
+        {
+            LOG(EJavaUI, EInfo, "  It was active");
+            mShutdownTimer->Cancel();
+        }
+        delete mShutdownTimer;
+        mShutdownTimer = 0;
+    }
+}
+
+TInt CoreUiAvkonImpl::shutdownTimerCallback(TAny*)
+{
+    JELOG2(EJavaUI);
+    ELOG(EJavaUI, "Killing process forcefully due to timer");
+    RProcess().Kill(-1);
+    return 0;
+}