qthighway/xqservice/src/xqaiwutils.cpp
changeset 1 2b40d63a9c3d
child 4 90517678cc4f
equal deleted inserted replaced
0:cfcbf08528c4 1:2b40d63a9c3d
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 *
       
     5 * This program is free software: you can redistribute it and/or modify
       
     6 * it under the terms of the GNU Lesser General Public License as published by
       
     7 * the Free Software Foundation, version 2.1 of the License.
       
     8 * 
       
     9 * This program is distributed in the hope that it will be useful,
       
    10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12 * GNU Lesser General Public License for more details.
       
    13 *
       
    14 * You should have received a copy of the GNU Lesser General Public License
       
    15 * along with this program.  If not, 
       
    16 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
       
    17 *
       
    18 * Description:
       
    19 *
       
    20 */
       
    21 
       
    22 #include <e32std.h>
       
    23 #include <apgcli.h>
       
    24 #include <apacmdln.h> 
       
    25 #include <apparc.h>
       
    26 #include <apmstd.h>
       
    27 #include <w32std.h>
       
    28 #include <apgtask.h>
       
    29 
       
    30 #include "xqaiwdecl.h"
       
    31 #include "xqservicelog.h"
       
    32 #include <xqserviceglobal.h>  // Error codes
       
    33 #include <xqserviceipcconst.h>
       
    34 #include "xqaiwutils.h"
       
    35 
       
    36 
       
    37 class XQAiwUtilsPrivate : public QObject
       
    38 {
       
    39     public:
       
    40 
       
    41         XQAiwUtilsPrivate();
       
    42         virtual ~XQAiwUtilsPrivate();
       
    43         
       
    44         void launchApplicationL(int applicationId, const QString &cmdArguments);
       
    45         int findApplicationFromApa(const QFile &file, int &applicationId);
       
    46         int findApplicationFromApa(const XQSharableFile &file, int &applicationId);
       
    47         bool applicationExists(int applicationId);
       
    48         int toIntFromHex(const QString &str, bool *ok);
       
    49         
       
    50     public:
       
    51         RApaLsSession apaSession;
       
    52     
       
    53 };
       
    54 
       
    55 
       
    56 XQAiwUtils::XQAiwUtils()
       
    57    : d(NULL)
       
    58 {
       
    59     XQSERVICE_DEBUG_PRINT("XQAiwUtils::XQAiwUtils");
       
    60     d = new XQAiwUtilsPrivate();
       
    61 }
       
    62 
       
    63 XQAiwUtils::~XQAiwUtils()
       
    64 {
       
    65     XQSERVICE_DEBUG_PRINT("XQAiwUtils::~XQAiwUtils");
       
    66     delete d;
       
    67 };
       
    68 
       
    69 int XQAiwUtils::launchApplication(int applicationId, const QString &cmdArguments)
       
    70 {
       
    71     TInt error = KErrNone;
       
    72     TRAP(error, d->launchApplicationL(applicationId, cmdArguments));
       
    73     return mapError(error);
       
    74 }
       
    75 
       
    76 int XQAiwUtils::mapError(int symbianError)
       
    77 {
       
    78     XQSERVICE_DEBUG_PRINT("XQAiwUtils::doMapErrors");
       
    79     XQSERVICE_DEBUG_PRINT("error: %d", symbianError);
       
    80     int error(XQService::ENoError);
       
    81     switch (symbianError)
       
    82     {
       
    83         case KErrNone:
       
    84         {
       
    85             error = XQService::ENoError;
       
    86             break;
       
    87         }
       
    88         
       
    89         case KErrPermissionDenied:
       
    90         case KErrServerTerminated:
       
    91         {
       
    92             error = XQService::EConnectionClosed;
       
    93             break;
       
    94         }
       
    95         case KErrServerBusy:
       
    96         {
       
    97             error = XQService::EConnectionError;
       
    98             break;
       
    99         }
       
   100         case KErrArgument:
       
   101         {
       
   102             error = XQService::EArgumentError;
       
   103             break;
       
   104         }
       
   105         case KErrNoMemory:
       
   106         {
       
   107             error = XQService::EIPCError;
       
   108             break;
       
   109         }
       
   110         case KErrNotFound:
       
   111         {
       
   112             error = XQService::EServerNotFound;
       
   113             break;
       
   114         }
       
   115         
       
   116         default:
       
   117         {
       
   118             error = XQService::EUnknownError;
       
   119             break;
       
   120         }
       
   121     }
       
   122     XQSERVICE_DEBUG_PRINT("error: %d", error);
       
   123     return error;
       
   124     
       
   125 }
       
   126 
       
   127 int XQAiwUtils::findApplication(const QFile &file, int &applicationId)
       
   128 {
       
   129     XQSERVICE_DEBUG_PRINT("XQAiwUtils::findApplication %s", qPrintable(file.fileName()));
       
   130     TInt error = KErrNone;
       
   131     int appId = 0;
       
   132     error = d->findApplicationFromApa(file, appId);
       
   133     if (!error)
       
   134     {
       
   135         applicationId = appId;
       
   136     }
       
   137     return error;
       
   138 
       
   139 }
       
   140 
       
   141 int XQAiwUtils::findApplication(const XQSharableFile &file, int &applicationId)
       
   142 {
       
   143     XQSERVICE_DEBUG_PRINT("XQAiwUtils::findApplication (handle)");
       
   144     TInt error = KErrNone;
       
   145     int appId = 0;
       
   146     error = d->findApplicationFromApa(file, appId);
       
   147     if (!error)
       
   148     {
       
   149         applicationId = appId;
       
   150     }
       
   151     return error;
       
   152 
       
   153 }
       
   154 
       
   155 
       
   156 int XQAiwUtils::findApplication(const QUrl &uri, int &applicationId)
       
   157 {
       
   158     XQSERVICE_DEBUG_PRINT("XQAiwUtils::findapplication %s", qPrintable(uri.toString()));
       
   159     int appId = 0;
       
   160     bool idOk = false;
       
   161     if (uri.scheme() == XQURI_SCHEME_ACTIVITY)  // application://uid3
       
   162     {
       
   163         QString uid = uri.authority(); 
       
   164         XQSERVICE_DEBUG_PRINT("findApplication::authority=%s", qPrintable(uid));
       
   165         appId = d->toIntFromHex(uid, &idOk);
       
   166         XQSERVICE_DEBUG_PRINT("XQAiwUriDriver::appid=%x,%d", appId, idOk);
       
   167 
       
   168         if (idOk)
       
   169         {
       
   170             idOk = d->applicationExists(appId);
       
   171         }
       
   172     }
       
   173     else if (uri.scheme() == XQURI_SCHEME_FILE)  // file://
       
   174     {
       
   175         TInt err = d->findApplicationFromApa(uri.toLocalFile(), appId);
       
   176         idOk = (err == KErrNone);
       
   177     }
       
   178 
       
   179     if (idOk)
       
   180     {
       
   181         applicationId = appId;
       
   182         return mapError(KErrNone);
       
   183     }
       
   184 
       
   185     return mapError(KErrNotFound);
       
   186 
       
   187 }
       
   188 
       
   189 // Create space separated command line args
       
   190 QString XQAiwUtils::createCmdlineArgs(const QList<QVariant> &args)
       
   191 {
       
   192     XQSERVICE_DEBUG_PRINT("XQAiwUtils::createCmdlineArgs");
       
   193     
       
   194     QString argsStr = "";
       
   195     for ( int i = 0; i < args.size(); ++i )
       
   196     {
       
   197         QVariant v = args.at(i);
       
   198         QString s = v.toString();
       
   199         if (!s.isEmpty())
       
   200         {
       
   201             argsStr += (i==0 ? "" : " ");
       
   202             argsStr += s;
       
   203         }
       
   204     }
       
   205 
       
   206     return argsStr;
       
   207     
       
   208 }
       
   209 
       
   210 
       
   211 // Error error message for R&D purposes
       
   212 QString XQAiwUtils::createErrorMessage(int errorCode, const QString context, const QString detail)
       
   213 {
       
   214     QString txt;
       
   215     switch (errorCode)
       
   216     {
       
   217         case XQService::ENoError:
       
   218                 txt =  "ENoError";
       
   219         break;
       
   220 
       
   221         case XQService::EConnectionError:
       
   222                 txt ="EConnectionError";
       
   223         break;
       
   224 
       
   225         case XQService::EConnectionClosed:
       
   226                 txt = "EConnectionClosed";
       
   227         break;
       
   228 
       
   229         case XQService::EServerNotFound:
       
   230                 txt = "EServerNotFound";
       
   231         break;
       
   232 
       
   233         case XQService::EIPCError:
       
   234                 txt = "EIPCError";
       
   235         break;
       
   236 
       
   237         case XQService::EUnknownError:
       
   238                 txt = "EUnknownError";
       
   239         break;
       
   240 
       
   241         case XQService::ERequestPending:
       
   242                 txt = "ERequestPending";
       
   243         break;
       
   244 
       
   245         case XQService::EMessageNotFound:
       
   246                 txt = "EMessageNotFound";
       
   247         break;
       
   248 
       
   249         case XQService::EArgumentError:
       
   250                 txt = "EArgumentError";
       
   251         break;
       
   252 
       
   253         default:
       
   254             txt = QString("AIW error: %1").arg(errorCode);
       
   255             break;
       
   256 
       
   257     }
       
   258 
       
   259     QString ret = "AIW error: ";
       
   260     ret += txt;
       
   261     ret += " (";
       
   262     ret += context;
       
   263     ret += ",";
       
   264     ret += detail;
       
   265     ret += ")";
       
   266 
       
   267     return ret;
       
   268 }
       
   269 
       
   270 
       
   271 void XQAiwUtilsPrivate::launchApplicationL(int applicationId, const QString &cmdArguments)
       
   272 {
       
   273     XQSERVICE_DEBUG_PRINT("XQAiwUtils::launchApplication");
       
   274     XQSERVICE_DEBUG_PRINT("applicationId=%x, cmdArguments %s", applicationId, qPrintable(cmdArguments));
       
   275 
       
   276     TPtrC cmdArgs( reinterpret_cast<const TUint16*>(cmdArguments.utf16()) );
       
   277     TUid uid;
       
   278     uid.iUid = applicationId;
       
   279 
       
   280     RWsSession wsSession;
       
   281     User::LeaveIfError(wsSession.Connect());
       
   282     CleanupClosePushL(wsSession);
       
   283 
       
   284     TApaTaskList taskList( wsSession );
       
   285     TApaTask task = taskList.FindApp( uid );
       
   286 
       
   287     if ( task.Exists() )
       
   288     {
       
   289         // Switching
       
   290         XQSERVICE_DEBUG_PRINT("XQAiwUtils::launchApplication: switch to existing");
       
   291         // TODO: How to pass new aguments to  running process ? Use SendMessage ?
       
   292         task.BringToForeground();
       
   293         CleanupStack::PopAndDestroy();  // wsSession
       
   294     }
       
   295     else
       
   296     {
       
   297         // Start application
       
   298         TApaAppInfo aInfo;
       
   299         User::LeaveIfError( apaSession.GetAppInfo( aInfo, uid ) );
       
   300         CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
       
   301         cmdLine->SetExecutableNameL( aInfo.iFullName );
       
   302         RProcess newApp;
       
   303         User::LeaveIfError(newApp.Create(aInfo.iFullName, cmdArgs));
       
   304         cmdLine->SetProcessEnvironmentL(newApp);
       
   305         newApp.Resume();
       
   306         newApp.Close(); // Close the handle (not the app)
       
   307         CleanupStack::PopAndDestroy(2);  // cmdLine, wsSession
       
   308     }
       
   309 
       
   310     XQSERVICE_DEBUG_PRINT("application started");
       
   311 
       
   312 }
       
   313 
       
   314 // ----- XQAiwUtilsPrivate --- 
       
   315 
       
   316 XQAiwUtilsPrivate::XQAiwUtilsPrivate()
       
   317 {
       
   318     apaSession.Connect();
       
   319 }
       
   320 
       
   321 XQAiwUtilsPrivate::~XQAiwUtilsPrivate()
       
   322 {
       
   323     apaSession.Close();
       
   324 }
       
   325 
       
   326 
       
   327 int XQAiwUtilsPrivate::findApplicationFromApa(const QFile &file, int &applicationId)
       
   328 {
       
   329     QString fileName = file.fileName();
       
   330     XQSERVICE_DEBUG_PRINT("XQAiwUtilsPrivate::::findApplicationFromApa %s", qPrintable(fileName));
       
   331     
       
   332     TPtrC name( reinterpret_cast<const TUint16*>(fileName.utf16()) );
       
   333 
       
   334     // Get the UID and MIME type for the given file name.
       
   335     TUid uid;
       
   336     uid.iUid=0;
       
   337     TDataType dataType;
       
   338     TInt err = apaSession.AppForDocument(name, uid, dataType);
       
   339     XQSERVICE_DEBUG_PRINT("\tFind status %d,%x", err, uid.iUid);
       
   340     if (err || uid.iUid == 0)
       
   341     {
       
   342         XQSERVICE_DEBUG_PRINT("\tHandler not found");
       
   343         return KErrNotFound;
       
   344     }
       
   345 
       
   346     applicationId = uid.iUid;  // return value
       
   347 
       
   348     XQSERVICE_DEBUG_PRINT("\tapplicationId=%x", applicationId);
       
   349     return KErrNone;
       
   350     
       
   351 }
       
   352 
       
   353 int XQAiwUtilsPrivate::findApplicationFromApa(const XQSharableFile &file, int &applicationId)
       
   354 {
       
   355     XQSERVICE_DEBUG_PRINT("XQAiwUtilsPrivate::findApplicationFromApa (handle)");
       
   356     RFile fileHandle;
       
   357     if (!file.getHandle(fileHandle))
       
   358     {
       
   359         XQSERVICE_DEBUG_PRINT("\tInvalid handle");
       
   360         return KErrArgument;
       
   361     }
       
   362 
       
   363     // Get the UID and MIME type for the given file name.
       
   364     TUid uid;
       
   365     uid.iUid=0;
       
   366     TDataType dataType;
       
   367     TInt err = apaSession.AppForDocument(fileHandle, uid, dataType);
       
   368     XQSERVICE_DEBUG_PRINT("\tFind status %d,%x", err, uid.iUid);
       
   369     if (err || uid.iUid == 0)
       
   370     {
       
   371         XQSERVICE_DEBUG_PRINT("\tHandler not found");
       
   372         return KErrNotFound;
       
   373     }
       
   374 
       
   375     applicationId = uid.iUid;  // return value
       
   376 
       
   377     XQSERVICE_DEBUG_PRINT("\tapplicationId=%x", applicationId);
       
   378     return KErrNone;
       
   379 
       
   380 }
       
   381 
       
   382 
       
   383 bool XQAiwUtilsPrivate::applicationExists(int applicationId)
       
   384 {
       
   385     TUid uid;
       
   386     uid.iUid = applicationId;
       
   387 
       
   388     TApaAppInfo aInfo;
       
   389     return apaSession.GetAppInfo( aInfo, uid ) == KErrNone;
       
   390     
       
   391 }
       
   392 
       
   393 //
       
   394 // For some reason QString::toInt(0,16) does not work...
       
   395 // Implement own converter
       
   396 //
       
   397 int XQAiwUtilsPrivate::toIntFromHex(const QString &str, bool *ok)
       
   398 {
       
   399     int result=0;
       
   400     int power = 0;
       
   401     int base=16;
       
   402     QString s = str.toUpper();
       
   403     for (int i=s.length()-1; i >= 0; i--)
       
   404     {
       
   405         int val = (int)s[i].toLatin1();
       
   406         int num;
       
   407         if ((val >= (int)'A') && (val <= (int)'F'))
       
   408             num = 10 + (val - (int)'A');
       
   409         else if ((val >= (int)'0') && (val <= (int)'9'))
       
   410             num = val - (int)'0';
       
   411         else
       
   412         {
       
   413             *ok = false;
       
   414             return 0;
       
   415         }
       
   416         
       
   417         int multiplier = 1;
       
   418         for (int j=0; j < power; j++) 
       
   419             multiplier *= base; // Calculate power
       
   420         
       
   421         result += multiplier*num;
       
   422         power++;
       
   423     }
       
   424 
       
   425     *ok = true;
       
   426 
       
   427     return result;
       
   428 }
       
   429