javaruntimes/midp/runtime/src.s60/platformrequesthandler.cpp
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javaruntimes/midp/runtime/src.s60/platformrequesthandler.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,304 @@
+/*
+* 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:  This class provides container for message.
+*
+*/
+
+
+#include <memory>
+#include <schemehandler.h>        // SchemeHandler
+#include <apgcli.h>               // for RApaLsSession
+#include <apacmdln.h>
+#include <sstream>
+
+#include "platformrequesthandler.h"
+
+#include "javasymbianoslayer.h"
+#include "javacommonutils.h"
+#include "s60commonutils.h"
+#include "exceptionbase.h"
+#include "logger.h"
+
+using namespace java::runtime;
+using namespace java::util;
+
+
+PlatformRequestInterface* getPlatformRequestHandlerObj()
+{
+    JELOG2(EJavaRuntime);
+    return new PlatformRequestHandler();
+}
+
+/**
+ *
+ */
+PlatformRequestHandler::PlatformRequestHandler()
+{
+}
+
+/**
+ *
+ */
+PlatformRequestHandler::~PlatformRequestHandler()
+{
+}
+
+/**
+ * handleUri() supports at least following URIs:
+ * file://, http://, https://, rtsp://, mailto://, wtai:, tel:, vtel:,
+ * mms:, cti:, javaapp: and localapp:
+ */
+void PlatformRequestHandler::handleUri(const std::wstring& aUri)
+{
+    JELOG2(EJavaRuntime);
+    TRAPD(err,launchAppL(aUri););
+    if (err != KErrNone)
+    {
+        ELOG1(EJavaRuntime, "ERROR!!! PlatformRequestHandler::handleUri() %d",
+              err);
+        if (KErrNotFound == err)
+        {
+            if ((aUri.find(L"localapp:jam/launch?") == 0) ||
+                    (aUri.find(L"localapp://jam/launch?") == 0) ||
+                    (aUri.find(L"javaapp:") == 0))
+            {
+                // The URI is supported but the MIDlet specified by the URI
+                // does not exist.
+                throw ExceptionBase(PlatformRequestInterface::UNEXPECTED_ERROR,
+                                    "Cannot start Java application",__FILE__,__FUNCTION__,__LINE__);
+            }
+
+            throw ExceptionBase(PlatformRequestInterface::CONNECTION_NOT_SUPPORTED,
+                                "Not supported URI",__FILE__,__FUNCTION__,__LINE__);
+        }
+        else
+        {
+            std::string errTxt("Execution PlatformRequestHandler::handleUri() "
+                               "failed to following error: ");
+            errTxt.append(java::util::JavaCommonUtils::intToString(err));
+            throw ExceptionBase(PlatformRequestInterface::UNEXPECTED_ERROR,
+                                errTxt,__FILE__,__FUNCTION__,__LINE__);
+        }
+    }
+}
+
+/**
+ *
+ */
+void PlatformRequestHandler::launchAppL(const std::wstring& aUri)
+{
+    JELOG2(EJavaRuntime);
+    LOG1(EJavaRuntime, EInfo, "Platform request. URI: %S", aUri.c_str());
+    if (startsArbitraryNativeApp(aUri))
+    {
+        launchNativeAppL(aUri);
+    }
+    else
+    {
+        TPtrC ptr((const TUint16 *)aUri.c_str(), aUri.length());
+        std::auto_ptr<CSchemeHandler> schemeHandler(CSchemeHandler::NewL(ptr));
+        schemeHandler->HandleUrlStandaloneL(); // Process Uri in standalone mode.
+    }
+}
+
+/**
+ *
+ */
+bool PlatformRequestHandler::startsArbitraryNativeApp(const std::wstring& aUri)
+{
+    if (aUri.find(L"nativeapp:") == 0)
+    {
+        return true;
+    }
+
+    if (aUri.find(L"localapp:native/launch?") == 0 ||
+            aUri.find(L"localapp://native/launch?") == 0)
+    {
+        return true;
+    }
+
+    return false;
+}
+
+/**
+ *
+ */
+void PlatformRequestHandler::launchNativeAppL(const std::wstring& aUri)
+{
+    std::wstring appName;
+
+    RApaLsSession apaSession;
+    TInt err = apaSession.Connect();
+    User::LeaveIfError(err);
+    CleanupClosePushL(apaSession);
+
+    // Support percent encoding in the URI
+    std::wstring uri = JavaCommonUtils::percentDecode(aUri);
+
+    // Start by by Uid?
+    const std::wstring appUid(L"application-uid=");
+    const std::wstring appExe(L"application-exe=");
+    const std::wstring semiColon(L";");
+    std::string::size_type idx = uri.find(appUid);
+    std::string::size_type idxSemiColon;
+    if (idx != std::string::npos)
+    {
+        // Parse Uid
+        TUid uid;
+        idx += appUid.size(); // skip argument name
+        idxSemiColon = uri.find(semiColon, idx);
+        if (idxSemiColon == std::string::npos)
+        {
+            idxSemiColon = uri.size();
+        }
+        std::wstring wstrUid = uri.substr(idx, (idxSemiColon - idx));
+
+        LOG1(EJavaRuntime, EInfo,
+             "PlatformRequestHandler: launchNativeAppL: Uid in req is : %S", wstrUid.c_str());
+
+        long long tmpInt;
+        std::wstringstream stream(wstrUid);
+        if (wstrUid.find(L"0x") == 0 || wstrUid.find(L"0X") == 0)
+        {
+            // hexadecimal
+            stream >> std::hex >> tmpInt;
+        }
+        else
+        {
+            stream >> tmpInt;
+        }
+        uid.iUid = tmpInt;
+
+        // Find executable name from AppArc
+        TApaAppInfo info;
+        err = apaSession.GetAppInfo(info, uid);
+        if (KErrNone != err)
+        {
+            ELOG2(EJavaRuntime,
+                  "PlatformRequestHandler: launchNativeAppL: GetAppInfo for uid %x failed, err %d",
+                  uid.iUid,
+                  err);
+            User::Leave(err);
+        }
+        info.iFullName.Append('\0');
+        appName = (wchar_t *)(&(info.iFullName[0]));
+        LOG1(EJavaRuntime, EInfo,
+             "PlatformRequestHandler: launchNativeAppL: app to start is : %S", appName.c_str());
+    }
+    else if ((idx = uri.find(appExe)) != std::string::npos)
+    {
+        // Parse exe name
+        idx += appExe.size(); // skip argument name
+        idxSemiColon = uri.find(semiColon, idx);
+        if (idxSemiColon == std::string::npos)
+        {
+            idxSemiColon = uri.size();
+        }
+        appName = uri.substr(idx, (idxSemiColon - idx));
+
+        LOG1(EJavaRuntime, EInfo,
+             "PlatformRequestHandler: launchNativeAppL: Exe name in req is : %S", appName.c_str());
+    }
+    else
+    {
+        // Illegal uri
+        User::Leave(KErrArgument);
+    }
+
+    // Start forming command line
+    CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
+
+    // Set executable name
+    HBufC *pAppName = S60CommonUtils::wstringToDes(appName.c_str());
+    if (pAppName)
+    {
+        CleanupStack::PushL(pAppName);
+        cmdLine->SetExecutableNameL(*pAppName);
+        CleanupStack::PopAndDestroy(pAppName);
+    }
+    cmdLine->SetCommandL(EApaCommandRun);
+
+    // Content (document) specified?
+    const std::wstring contentArg(L"content=");
+    if ((idx = uri.find(contentArg)) != std::string::npos)
+    {
+        // Parse document name
+        idx += contentArg.size(); // skip argument name
+        idxSemiColon = uri.find(semiColon, idx);
+        if (idxSemiColon == std::string::npos)
+        {
+            idxSemiColon = uri.size();
+        }
+        std::wstring content = uri.substr(idx, (idxSemiColon - idx));
+
+        LOG1(EJavaRuntime, EInfo,
+             "PlatformRequestHandler: launchNativeAppL: content: %S", content.c_str());
+
+        HBufC *pContent = S60CommonUtils::wstringToDes(content.c_str());
+        if (pContent)
+        {
+            CleanupStack::PushL(pContent);
+            cmdLine->SetDocumentNameL(*pContent);
+            CleanupStack::PopAndDestroy(pContent);
+        }
+    }
+
+    // Other application arguments specified?
+    const std::wstring appArgs(L"application-args=");
+    if ((idx = uri.find(appArgs)) != std::string::npos)
+    {
+        // Parse applications args
+        idx += appArgs.size(); // skip argument name
+        // Rest of the command URI contains args
+        idxSemiColon = uri.size();
+        std::wstring args = uri.substr(idx, (idxSemiColon - idx));
+
+        LOG1(EJavaRuntime, EInfo,
+             "PlatformRequestHandler: launchNativeAppL: app args: %S", args.c_str());
+
+        if (args.size() > 0)
+        {
+            // Convert args to 8 bit descriptor
+            char* utf8string = NULL;
+            try
+            {
+                utf8string = JavaCommonUtils::wstringToUtf8(args);
+            }
+            catch (std::exception& e)
+            {
+                ELOG1(EJavaRuntime,
+                      "PlatformRequestHandler: launchNativeAppL: Cannot convert app args to"
+                      " UTF-8. Error %s", e.what());
+                User::Leave(KErrArgument);
+            }
+            TInt argsLen = strlen(utf8string);
+            TPtr8 ptrArgs((unsigned char *)utf8string, argsLen, argsLen + 4);
+
+            cmdLine->SetTailEndL(ptrArgs);
+            delete[] utf8string;
+        }
+    }
+
+    // Start executable
+    err = apaSession.StartApp(*cmdLine);
+    if (KErrNone != err)
+    {
+        ELOG1(EJavaRuntime,
+              "PlatformRequestHandler: launchNativeAppL: StartApp error %d", err);
+        User::Leave(err);
+    }
+
+    CleanupStack::PopAndDestroy(cmdLine);
+    CleanupStack::PopAndDestroy(); // apaSession
+}