declarativepurchaselistmodel.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /**
  2. * Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
  3. * All rights reserved.
  4. *
  5. * For the applicable distribution terms see the license.txt -file, included in
  6. * the distribution.
  7. */
  8. #include <QtAlgorithms>
  9. #include <QFile>
  10. #include <QTextStream>
  11. #include <QApplication>
  12. #include <QDirIterator>
  13. #include <QDebug>
  14. #include "declarativepurchaselistmodel.h"
  15. #include "purchasableitembase.h"
  16. #include "purchasableitem.h"
  17. #include "purchasableitemnonprotected.h"
  18. #define NONPROTECTEDCATALOG "/data/catalog.dat"
  19. #define PROTECTEDCATALOG "/drm/data"
  20. #define DRMPATTERN "resourceid_"
  21. Q_DECLARE_METATYPE(IAPClient::ProductDataList) //to be able to transfer data this type with Qt::QueuedConnection
  22. DeclarativePurchaseListModel::DeclarativePurchaseListModel(QObject *parent) :
  23. QAbstractListModel(parent),
  24. m_modelCommitRefCounter(0),
  25. m_requestId(KErrNotFound),
  26. m_isApplicationBusy(false)
  27. {
  28. QHash<int, QByteArray> roles;
  29. roles[PurchasableItemBase::ProductIdRole] = "productid";
  30. roles[PurchasableItemBase::DataReqResultRole] = "reqresult";
  31. roles[PurchasableItemBase::TitleRole] = "tile";
  32. roles[PurchasableItemBase::ShortDescriptionRole] = "shortDescr";
  33. roles[PurchasableItemBase::LongDescriptionRole] = "longDescr";
  34. roles[PurchasableItemBase::PriceRole] = "price";
  35. roles[PurchasableItemBase::DrmProtectionRole] = "isDrm";
  36. roles[PurchasableItemBase::IsMetadataKnown] = "isDataKnown";
  37. roles[PurchasableItemBase::IsBusy] = "isBusy";
  38. roles[PurchasableItemBase::IsActivated] = "isActivated";
  39. setRoleNames(roles);
  40. qRegisterMetaType<IAPClient::ProductDataList>("IAPClient::ProductDataList");
  41. qRegisterMetaType<IAPClient::UserAndDeviceDataHash>("IAPClient::UserAndDeviceDataHash");
  42. connect(&m_client, SIGNAL(restorableProductsReceived (int, QString, IAPClient::ProductDataList)),
  43. this, SLOT(restorableProductsReceived (int, QString, IAPClient::ProductDataList)),
  44. Qt::QueuedConnection);
  45. connect(&m_client, SIGNAL(userAndDeviceDataReceived (int, QString, IAPClient::UserAndDeviceDataHash)),
  46. this, SLOT(userAndDeviceDataReceived (int, QString, IAPClient::UserAndDeviceDataHash )),
  47. Qt::QueuedConnection);
  48. readNonProtectedCatalog();
  49. readDRMCatalog();
  50. }
  51. DeclarativePurchaseListModel::~DeclarativePurchaseListModel()
  52. {
  53. }
  54. QVariant DeclarativePurchaseListModel::data(const QModelIndex &index, int role) const
  55. {
  56. if (index.row() < 0 || index.row() > m_data.count())
  57. return QVariant();
  58. const PurchasableItemBase *record = m_data[index.row()];
  59. return record->metadata(role);
  60. }
  61. int DeclarativePurchaseListModel::rowCount(const QModelIndex & parent) const
  62. {
  63. return m_data.count();
  64. }
  65. bool DeclarativePurchaseListModel::drmFilter() const
  66. {
  67. return true;
  68. }
  69. void DeclarativePurchaseListModel::setDrmFilter(bool val)
  70. {
  71. }
  72. void DeclarativePurchaseListModel::classBegin()
  73. {
  74. }
  75. void DeclarativePurchaseListModel::componentComplete()
  76. {
  77. }
  78. void DeclarativePurchaseListModel::readNonProtectedCatalog()
  79. {
  80. QString filepath = QApplication::applicationDirPath();
  81. filepath.append(NONPROTECTEDCATALOG);
  82. QFile file(filepath);
  83. bool result = file.open(QFile::ReadOnly);
  84. if(!result)
  85. return;
  86. QTextStream stream(&file);
  87. QString line;
  88. do
  89. {
  90. line = stream.readLine();
  91. line.trimmed();
  92. if(!line.isEmpty())
  93. {
  94. QStringList items = line.split("|", QString::KeepEmptyParts);
  95. QString productId = items[0].trimmed();
  96. QString url = items[1].trimmed();
  97. PurchasableItemNonProtected *record = new PurchasableItemNonProtected(*this, productId, url);
  98. beginInsertRows(QModelIndex(), rowCount(), rowCount());
  99. m_data << record;
  100. endInsertRows();
  101. }
  102. }
  103. while (!line.isNull());
  104. file.close();
  105. }
  106. void DeclarativePurchaseListModel::readDRMCatalog()
  107. {
  108. QString filepath = QApplication::applicationDirPath();
  109. filepath.append(PROTECTEDCATALOG);
  110. QDirIterator dirit(filepath, QDir::Dirs, QDirIterator::NoIteratorFlags);
  111. while(dirit.hasNext())
  112. {
  113. QString dir = dirit.next();
  114. if(dir.contains(DRMPATTERN, Qt::CaseInsensitive))
  115. {
  116. // breakdown the !:/private/<SID>/drm/data/resourceid_<productID>/
  117. // extract the product to which this file belongs
  118. QString product;
  119. QStringList elem = dir.split("_", QString::SkipEmptyParts);
  120. elem=elem[1].split("/", QString::SkipEmptyParts);
  121. product = elem[0].trimmed();
  122. if(product.isEmpty())
  123. continue;
  124. QString productIcon(dir + "/test.png");
  125. PurchasableItem *record = new PurchasableItem(*this, product, productIcon);
  126. beginInsertRows(QModelIndex(), rowCount(), rowCount());
  127. m_data << record;
  128. endInsertRows();
  129. }
  130. }
  131. }
  132. bool DeclarativePurchaseListModel::setData(const QModelIndex & index, const QVariant & value, int role)
  133. {
  134. if(role < PurchasableItemBase::ProductIdRole)
  135. return false;
  136. PurchasableItemBase *record = const_cast<PurchasableItemBase*>(m_data[index.row()]);
  137. return record->setMetadata(value, role);
  138. }
  139. void DeclarativePurchaseListModel::beginModelUpdate()
  140. {
  141. if(!m_modelCommitRefCounter)
  142. beginResetModel();
  143. m_modelCommitRefCounter++;
  144. }
  145. void DeclarativePurchaseListModel::commitModelUpdate()
  146. {
  147. m_modelCommitRefCounter--;
  148. if(m_modelCommitRefCounter < 0)
  149. m_modelCommitRefCounter = 0;
  150. if(!m_modelCommitRefCounter)
  151. endResetModel();
  152. }
  153. IAPClient& DeclarativePurchaseListModel::client()
  154. {
  155. return m_client;
  156. }
  157. void DeclarativePurchaseListModel::buy(int index)
  158. {
  159. qDebug() << "DeclarativePurchaseListModel::buy " << index;
  160. const_cast<PurchasableItemBase*>(record(index))->purchase();
  161. }
  162. PurchasableItemBase* DeclarativePurchaseListModel::record(int index) const
  163. {
  164. return (m_data[index]);
  165. }
  166. void DeclarativePurchaseListModel::restorableProductsReceived(int requestId, QString status,
  167. IAPClient::ProductDataList items)
  168. {
  169. if(requestId != m_requestId)
  170. return;
  171. // Note , request id value is used as condition to busy indicator
  172. // it is needed to set the value to initial state when the request is done
  173. m_requestId = KErrNotFound;
  174. qDebug(__FUNCTION__);
  175. beginResetModel();
  176. PurchasableItemBase* item;
  177. foreach(item, m_data)
  178. {
  179. item->setMetadata(QVariant(false), PurchasableItemBase::IsBusy);
  180. if(item->isIncluded(items))
  181. {
  182. //trigger restoration
  183. item->restore();
  184. }
  185. }
  186. endResetModel();
  187. }
  188. void DeclarativePurchaseListModel::restoreProducts()
  189. {
  190. if(m_requestId >= 0)
  191. {
  192. qDebug() << "Catalog is busy. you can set only one request at time";
  193. return;
  194. }
  195. qDebug(__FUNCTION__);
  196. m_requestId = m_client.getRestorableProducts();
  197. if(m_requestId < 0)
  198. return; // failure hapened
  199. beginResetModel();
  200. PurchasableItemBase* item;
  201. foreach(item, m_data)
  202. {
  203. item->setMetadata(QVariant(true), PurchasableItemBase::IsBusy);
  204. }
  205. endResetModel();
  206. }
  207. void DeclarativePurchaseListModel::getUserInfo()
  208. {
  209. if(m_requestId >= 0)
  210. {
  211. qDebug() << "Catalog is busy. you can set only one request at time";
  212. return;
  213. }
  214. qDebug(__FUNCTION__);
  215. m_requestId = m_client.getUserAndDeviceId();
  216. if(m_requestId < 0)
  217. return; // failure hapened
  218. m_isApplicationBusy = true;
  219. emit applicationBusyChanged();
  220. }
  221. void DeclarativePurchaseListModel::userAndDeviceDataReceived (int requestId, QString status,
  222. IAPClient::UserAndDeviceDataHash userdata)
  223. {
  224. if(requestId != m_requestId)
  225. return;
  226. // Note , request id value is used as condition to busy indicator
  227. // it is needed to set the value to initial state when the request is done
  228. m_requestId = KErrNotFound;
  229. m_isApplicationBusy = false;
  230. emit applicationBusyChanged();
  231. qDebug(__FUNCTION__);
  232. qDebug() << "---data begin---" ;
  233. qDebug() << "\t" << userdata.value("accountdigest").toString();
  234. qDebug() << "\t" << userdata.value("imeidigest").toString();
  235. qDebug() << "\t" << userdata.value("imsidigest").toString();
  236. qDebug() << "\t" << userdata.value("country").toString();
  237. qDebug() << "\t" << userdata.value("language").toString();
  238. qDebug() << "\t" << userdata.value("devicemodel").toString();
  239. qDebug() << "---end data---" ;
  240. }
  241. bool DeclarativePurchaseListModel::isApplicationBusy() const
  242. {
  243. return m_isApplicationBusy;
  244. }
  245. void DeclarativePurchaseListModel::purgeProducts()
  246. {
  247. QString dirName = PurchasableItemBase::getTicketDir();
  248. QDir dir(dirName);
  249. if(!dir.exists(dirName))
  250. return;
  251. bool result;
  252. foreach(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot |
  253. QDir::System |
  254. QDir::Hidden |
  255. QDir::AllDirs |
  256. QDir::Files,
  257. QDir::DirsFirst))
  258. {
  259. result = QFile::remove(info.absoluteFilePath());
  260. if (!result)
  261. {
  262. break;
  263. }
  264. }
  265. dir.rmdir(dirName);
  266. beginResetModel();
  267. foreach(PurchasableItemBase* item, m_data)
  268. {
  269. item->setMetadata(QVariant(false), PurchasableItemBase::IsActivated);
  270. }
  271. endResetModel();
  272. }