26 #include "xqservicechannel.h" |
26 #include "xqservicechannel.h" |
27 #include "xqservicethreaddata.h" |
27 #include "xqservicethreaddata.h" |
28 #include "xqserviceipcclient.h" |
28 #include "xqserviceipcclient.h" |
29 |
29 |
30 #include <xqserviceutil.h> |
30 #include <xqserviceutil.h> |
|
31 #include <xqrequestutil.h> |
31 #include <qmetaobject.h> |
32 #include <qmetaobject.h> |
32 #include <QMap> |
33 #include <QMap> |
33 #include <QDataStream> |
34 #include <QDataStream> |
34 #include <qatomic.h> |
35 #include <qatomic.h> |
35 #include <QDebug> |
36 #include <QDebug> |
668 { |
669 { |
669 // The last argument should be the request index |
670 // The last argument should be the request index |
670 XQSERVICE_DEBUG_PRINT("\tDesserialize XQRequestInfo"); |
671 XQSERVICE_DEBUG_PRINT("\tDesserialize XQRequestInfo"); |
671 QVariant v; |
672 QVariant v; |
672 stream >> v; |
673 stream >> v; |
673 XQSERVICE_DEBUG_PRINT("\tQVariant type=%s", v.typeName()); |
674 XQSERVICE_DEBUG_PRINT("\tXQRequestInfo:QVariant type=%s", v.typeName()); |
674 if (QString(v.typeName()) == QString("XQRequestInfo")) |
675 if (QString(v.typeName()) == QString("XQRequestInfo")) |
675 { |
676 { |
676 XQRequestInfo info = v.value<XQRequestInfo>(); |
677 XQRequestInfo info = v.value<XQRequestInfo>(); |
677 |
678 |
678 //bring foreground or background based on RequestInfo from client side. |
679 //bring foreground or background based on RequestInfo from client side. |
679 XQServiceUtil::toBackground(info.isBackground()); |
680 bool bg = info.isBackground(); |
|
681 bool fg = info.isForeground(); |
|
682 if (bg && !fg) |
|
683 { |
|
684 XQSERVICE_DEBUG_PRINT("\tApply background option"); |
|
685 XQServiceUtil::toBackground(true); |
|
686 } |
|
687 else if (fg && !bg) |
|
688 { |
|
689 XQSERVICE_DEBUG_PRINT("\tApply foreground option"); |
|
690 XQServiceUtil::toBackground(false); |
|
691 } |
|
692 // If both off or both on, do not do anything |
680 |
693 |
681 XQServiceIpcClient *cl = XQService::serviceThreadData()->clientConnection(d->channelName); |
694 XQServiceIpcClient *cl = XQService::serviceThreadData()->clientConnection(d->channelName); |
682 // Attach to current request before the metacall below ! |
695 // Attach to current request before the metacall below ! |
683 cl->setRequestInfo(info); |
696 cl->setRequestInfo(info); |
684 } |
697 } |
685 } |
698 } |
686 else if (info->types[arg] != XQServiceAdaptorPrivate::QVariantId) { |
699 else if (info->types[arg] == XQServiceAdaptorPrivate::QVariantId) |
687 XQServiceVariant temp; |
700 { |
688 temp.load(stream, info->types[arg]); |
|
689 |
|
690 XQSERVICE_DEBUG_PRINT("\tQVariant type=%s", temp.typeName()); |
|
691 |
|
692 if (QString(temp.typeName()) == QString("XQSharableFile")) |
|
693 { |
|
694 //apply the patch |
|
695 if ( sf.isValid()) |
|
696 { |
|
697 args.append( qVariantFromValue(sf ) ); |
|
698 } |
|
699 |
|
700 } |
|
701 else |
|
702 { |
|
703 args.append(temp); |
|
704 } |
|
705 |
|
706 |
|
707 a[arg + 1] = (void *)(args[arg].data()); |
|
708 } else { |
|
709 // We need to handle QVariant specially because we actually |
701 // We need to handle QVariant specially because we actually |
710 // need the type header in this case. |
702 // need the type header in this case. |
711 QVariant temp; |
703 QVariant temp; |
712 stream >> temp; |
704 stream >> temp; |
|
705 |
|
706 XQSERVICE_DEBUG_PRINT("\tQVariantId:QVariant type=%s", temp.typeName()); |
|
707 |
|
708 if (QString(temp.typeName()) == QString("XQSharableFile")) |
|
709 { |
|
710 //apply the patch |
|
711 if ( sf.isValid()) |
|
712 { |
|
713 temp = qVariantFromValue( sf ); |
|
714 } |
|
715 } |
|
716 |
|
717 args.append(temp); |
|
718 a[arg + 1] = (void *)&(args[arg]); |
|
719 } |
|
720 else { |
|
721 // |
|
722 // The default handling |
|
723 // |
|
724 QVariant temp; |
|
725 stream >> temp; |
713 |
726 |
714 XQSERVICE_DEBUG_PRINT("\tQVariant type=%s", temp.typeName()); |
727 XQSERVICE_DEBUG_PRINT("\tDefault:QVariant type=%s", temp.typeName()); |
715 |
728 |
716 if (QString(temp.typeName()) == QString("XQSharableFile")) |
729 if (QString(temp.typeName()) == QString("XQSharableFile")) |
717 { |
730 { |
718 //apply the patch |
731 //apply the patch |
719 if ( sf.isValid()) |
732 if ( sf.isValid()) |
915 XQSERVICE_DEBUG_PRINT("userdata: %x",(int)userData); |
928 XQSERVICE_DEBUG_PRINT("userdata: %x",(int)userData); |
916 for(int i=0;i<args.size();++i){ |
929 for(int i=0;i<args.size();++i){ |
917 XQSERVICE_DEBUG_PRINT("args[%d]:type=%s,value=%s", i, args[i].typeName(), qPrintable(args[i].toString())); |
930 XQSERVICE_DEBUG_PRINT("args[%d]:type=%s,value=%s", i, args[i].typeName(), qPrintable(args[i].toString())); |
918 } |
931 } |
919 if (!sync && !rc) { |
932 if (!sync && !rc) { |
920 //TODO: set error |
933 // Something wrong as no callback given |
|
934 XQService::serviceThreadData()->setLatestError(XQService::EArgumentError); |
921 return false; |
935 return false; |
922 } |
936 } |
923 QByteArray array; |
937 QByteArray array; |
924 { |
938 QDataStream stream(&array, QIODevice::WriteOnly | QIODevice::Append); |
925 QDataStream stream |
939 QList<QVariant>::ConstIterator iter; |
926 (&array, QIODevice::WriteOnly | QIODevice::Append); |
940 for (iter = args.begin(); iter != args.end(); ++iter) { |
927 QList<QVariant>::ConstIterator iter; |
941 stream << *iter; |
928 if (!msg.contains(QLatin1String("QVariant"))) { |
942 } |
929 for (iter = args.begin(); iter != args.end(); ++iter) { |
943 // Stream is flushed and closed at this point. |
930 if (QString(iter->typeName()) == QString("XQRequestInfo")) |
|
931 { |
|
932 // Handle request options specially as we need type header |
|
933 XQSERVICE_DEBUG_PRINT("\tSerialize XQRequestInfo to stream"); |
|
934 stream << *iter; |
|
935 } |
|
936 else |
|
937 { |
|
938 XQServiceVariant copy(*iter); |
|
939 copy.save(stream); |
|
940 } |
|
941 } |
|
942 } else { |
|
943 QByteArray name = msg.toLatin1(); |
|
944 name = QMetaObject::normalizedSignature(name.constData()); |
|
945 int numParams = 0; |
|
946 int *params = XQServiceAdaptorPrivate::connectionTypes |
|
947 (name, numParams); |
|
948 int index = 0; |
|
949 for (iter = args.begin(); iter != args.end(); ++iter, ++index) { |
|
950 if (QString(iter->typeName()) == QString("XQRequestInfo")) |
|
951 { |
|
952 // Pass request info onward (extra internal parameter( |
|
953 XQSERVICE_DEBUG_PRINT("\tSerialize XQRequestInfo to stream"); |
|
954 stream << *iter; |
|
955 } |
|
956 else if (index < numParams && |
|
957 params[index] == XQServiceAdaptorPrivate::QVariantId) { |
|
958 // We need to handle QVariant specially because we actually |
|
959 // need the type header in this case. |
|
960 stream << *iter; |
|
961 } else { |
|
962 XQServiceVariant copy(*iter); |
|
963 copy.save(stream); |
|
964 } |
|
965 } |
|
966 if (params) |
|
967 qFree(params); |
|
968 } |
|
969 // Stream is flushed and closed at this point. |
|
970 } |
|
971 return XQServiceChannel::send(channel, msg, array, retValue, sync, rc, userData); |
944 return XQServiceChannel::send(channel, msg, array, retValue, sync, rc, userData); |
972 } |
945 } |
973 |
946 |
974 bool XQServiceAdaptor::cancelPendingSend(const QString& channel) |
947 bool XQServiceAdaptor::cancelPendingSend(const QString& channel) |
975 { |
948 { |