| Home · All Namespaces · All Classes |
00001 /*************************************************************************** 00002 ** 00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 00004 ** All rights reserved. 00005 ** Contact: Nokia Corporation (directui@nokia.com) 00006 ** 00007 ** This file is part of mhome. 00008 ** 00009 ** If you have questions regarding the use of this file, please contact 00010 ** Nokia at directui@nokia.com. 00011 ** 00012 ** This library is free software; you can redistribute it and/or 00013 ** modify it under the terms of the GNU Lesser General Public 00014 ** License version 2.1 as published by the Free Software Foundation 00015 ** and appearing in the file LICENSE.LGPL included in the packaging 00016 ** of this file. 00017 ** 00018 ****************************************************************************/ 00019 00020 #include "applicationpackagemonitor.h" 00021 #include "launcherdatastore.h" 00022 #include <QDir> 00023 #include <QDBusConnection> 00024 #include <mdesktopentry.h> 00025 #include <mfiledatastore.h> 00026 #include <msubdatastore.h> 00027 00028 static const QString PACKAGE_MANAGER_DBUS_SERVICE="com.nokia.package_manager"; 00029 static const QString PACKAGE_MANAGER_DBUS_PATH="/com/nokia/package_manager"; 00030 static const QString PACKAGE_MANAGER_DBUS_INTERFACE="com.nokia.package_manager"; 00031 00032 static const QString OPERATION_INSTALL = "Install"; 00033 static const QString OPERATION_UNINSTALL = "Uninstall"; 00034 static const QString OPERATION_REFRESH = "Refresh"; 00035 static const QString OPERATION_UPGRADE = "Upgrade"; 00036 00037 static const QString DESKTOPENTRY_PREFIX = "DesktopEntries"; 00038 static const QString PACKAGE_PREFIX = "Packages/"; 00039 static const QString INSTALLER_EXTRA = "installer-extra/"; 00040 00041 static const QString CONFIG_PATH = "/.config/meegotouchhome"; 00042 00043 static const QString PACKAGE_STATE_INSTALLED = "installed"; 00044 static const QString PACKAGE_STATE_INSTALLABLE = "installable"; 00045 static const QString PACKAGE_STATE_BROKEN = "broken"; 00046 static const QString PACKAGE_STATE_UPDATEABLE = "updateable"; 00047 static const QString PACKAGE_STATE_INSTALLING ="installing"; 00048 static const QString PACKAGE_STATE_DOWNLOADING ="downloading"; 00049 00050 static const QString DESKTOP_ENTRY_KEY_PACKAGE_STATE = "PackageState"; 00051 static const QString DESKTOP_ENTRY_KEY_PACKAGE_NAME = "Package"; 00052 static const QString DESKTOP_ENTRY_GROUP_MEEGO = "X-MeeGo"; 00053 00054 class ApplicationPackageMonitor::ExtraDirWatcher : public LauncherDataStore 00055 { 00056 public: 00057 ExtraDirWatcher(MDataStore *dataStore, const QString &directoryPath); 00058 ~ExtraDirWatcher(); 00059 00060 protected: 00061 virtual bool isDesktopEntryValid(const MDesktopEntry &entry, const QStringList &acceptedTypes); 00062 }; 00063 00064 ApplicationPackageMonitor::ApplicationPackageMonitor() 00065 : con(QDBusConnection::systemBus()) 00066 { 00067 con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "download_progress", 00068 this, SLOT(packageDownloadProgress(const QString&, const QString&, const QString&, int, int))); 00069 con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "operation_started", 00070 this, SLOT(packageOperationStarted(const QString&, const QString&, const QString&))); 00071 con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "operation_progress", 00072 this, SLOT(packageOperationProgress(const QString&, const QString &, const QString&, int))); 00073 con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "operation_complete", 00074 this, SLOT(packageOperationComplete(const QString&, const QString&, const QString&, const QString&, bool))); 00075 00076 QString configPath = QDir::homePath() + CONFIG_PATH; 00077 00078 if (!QDir::root().exists(configPath)) { 00079 QDir::root().mkpath(configPath); 00080 } 00081 00082 QString dataStoreFileName = configPath + "/applicationpackage.data"; 00083 00084 dataStore = new MFileDataStore(dataStoreFileName); 00085 00086 // ExtraDirWatcher takes ownership of dataStore 00087 extraDirWatcher = QSharedPointer<ExtraDirWatcher>(new ExtraDirWatcher(dataStore, APPLICATIONS_DIRECTORY+INSTALLER_EXTRA)); 00088 00089 connect(extraDirWatcher.data(), SIGNAL(desktopEntryAdded(QString)), this, SLOT(updatePackageState(QString)), Qt::UniqueConnection); 00090 connect(extraDirWatcher.data(), SIGNAL(desktopEntryChanged(QString)), this, SLOT(updatePackageState(QString)), Qt::UniqueConnection); 00091 connect(extraDirWatcher.data(), SIGNAL(desktopEntryRemoved(QString)), this, SLOT(packageRemoved(QString)), Qt::UniqueConnection); 00092 } 00093 00094 ApplicationPackageMonitor::~ApplicationPackageMonitor() 00095 { 00096 } 00097 00098 00099 void ApplicationPackageMonitor::packageRemoved(const QString &desktopEntryPath) 00100 { 00101 QString packageKey; 00102 00103 foreach(const QString &pkgKey, dataStore->allKeys()) { 00104 if(pkgKey.contains(PACKAGE_PREFIX)) { 00105 if(dataStore->value(pkgKey).toString() == desktopEntryPath) { 00106 packageKey = pkgKey; 00107 break; 00108 } 00109 } 00110 } 00111 00112 dataStore->remove(DESKTOPENTRY_PREFIX+desktopEntryPath); 00113 dataStore->remove(packageKey); 00114 activePackages.remove(packageKey.remove(PACKAGE_PREFIX)); 00115 00116 emit installExtraEntryRemoved(desktopEntryPath); 00117 } 00118 00119 void ApplicationPackageMonitor::updatePackageStates() 00120 { 00121 QStringList keyList(dataStore->allKeys()); 00122 00123 foreach (QString key, keyList) { 00124 if (key.contains(PACKAGE_PREFIX)) { 00125 QString desktopEntryPath = dataStore->value(key).toString(); 00126 QString state = dataStore->value(DESKTOPENTRY_PREFIX + desktopEntryPath).toString(); 00127 if (state == PACKAGE_STATE_BROKEN) { 00128 // emit operation error for a broken package 00129 emit operationError(desktopEntryPath, QString()); 00130 } else if(state == PACKAGE_STATE_DOWNLOADING) { 00131 emit downloadProgress(desktopEntryPath, 0, 0); 00132 } else if(state == PACKAGE_STATE_INSTALLING) { 00133 emit installProgress(desktopEntryPath, 0); 00134 } 00135 } 00136 } 00137 } 00138 00139 ApplicationPackageMonitor::PackageProperties &ApplicationPackageMonitor::activePackageProperties(const QString packageName) 00140 { 00141 if (!activePackages.contains(packageName)) { 00142 // Set the desktopEntryName if already known 00143 activePackages[packageName].desktopEntryName = desktopEntryName(packageName); 00144 } 00145 00146 return activePackages[packageName]; 00147 } 00148 00149 void ApplicationPackageMonitor::packageDownloadProgress(const QString &operation, 00150 const QString &packageName, 00151 const QString &packageVersion, 00152 int already, int total) 00153 { 00154 Q_UNUSED(operation) 00155 Q_UNUSED(packageVersion) 00156 00157 PackageProperties &properties = activePackageProperties(packageName); 00158 00159 if (isValidOperation(properties, operation)) { 00160 emit downloadProgress(properties.desktopEntryName, already, total); 00161 } 00162 00163 storePackageState(packageName, PACKAGE_STATE_DOWNLOADING); 00164 } 00165 00166 void ApplicationPackageMonitor::packageOperationStarted(const QString &operation, 00167 const QString &packageName, 00168 const QString &version) 00169 { 00170 Q_UNUSED(operation) 00171 Q_UNUSED(packageName) 00172 Q_UNUSED(version) 00173 } 00174 00175 void ApplicationPackageMonitor::packageOperationProgress(const QString &operation, 00176 const QString &packageName, 00177 const QString &packageVersion, 00178 int percentage) 00179 { 00180 Q_UNUSED(packageVersion) 00181 00182 PackageProperties &properties = activePackageProperties(packageName); 00183 00184 if (isValidOperation(properties, operation)) { 00185 properties.installing = true; 00186 emit installProgress(properties.desktopEntryName, percentage); 00187 storePackageState(packageName, PACKAGE_STATE_INSTALLING); 00188 } 00189 } 00190 00191 void ApplicationPackageMonitor::packageOperationComplete(const QString &operation, 00192 const QString &packageName, 00193 const QString &packageVersion, 00194 const QString &error, 00195 bool need_reboot) 00196 { 00197 Q_UNUSED(packageVersion) 00198 Q_UNUSED(need_reboot) 00199 00200 PackageProperties &properties = activePackageProperties(packageName); 00201 00202 if (!isValidOperation(properties, operation)) { 00203 return; 00204 } 00205 00206 if (!error.isEmpty()) { 00207 if (properties.installing) { 00208 emit operationError(properties.desktopEntryName, error); 00209 storePackageState(packageName, PACKAGE_STATE_BROKEN); 00210 } 00211 else { 00212 // Downloading 00213 MDesktopEntry entry(properties.desktopEntryName); 00214 QString packageState = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_STATE); 00215 if (packageState == PACKAGE_STATE_INSTALLED || packageState == PACKAGE_STATE_UPDATEABLE) { 00216 // Application is previously installed. Downloading update failed but application still usable. 00217 emit operationSuccess(properties.desktopEntryName.replace(INSTALLER_EXTRA, QString())); 00218 storePackageState(packageName, packageState); 00219 } else { 00220 emit operationError(properties.desktopEntryName, error); 00221 storePackageState(packageName, PACKAGE_STATE_BROKEN); 00222 } 00223 } 00224 } else { 00225 emit operationSuccess(properties.desktopEntryName.replace(INSTALLER_EXTRA, QString())); 00226 storePackageState(packageName, PACKAGE_STATE_INSTALLED); 00227 } 00228 00229 activePackages.remove(packageName); 00230 } 00231 00232 void ApplicationPackageMonitor::storePackageState(const QString& packageName, const QString& state) 00233 { 00234 QString path = dataStore->value(PACKAGE_PREFIX + packageName).toString(); 00235 extraDirWatcher->updateDataForDesktopEntry(path, state); 00236 } 00237 00238 bool ApplicationPackageMonitor::isValidOperation(const PackageProperties &properties, const QString &operation) 00239 { 00240 if ((operation.compare(OPERATION_INSTALL, Qt::CaseInsensitive) == 0 || 00241 operation.compare(OPERATION_UPGRADE, Qt::CaseInsensitive) == 0 ) && 00242 !properties.desktopEntryName.isEmpty() ) { 00243 return true; 00244 } else { 00245 return false; 00246 } 00247 } 00248 00249 void ApplicationPackageMonitor::updatePackageState(const QString &desktopEntryPath) 00250 { 00251 MDesktopEntry entry(desktopEntryPath); 00252 00253 QString packageName = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_NAME); 00254 QString packageState = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_STATE); 00255 00256 if (!packageName.isEmpty()) { 00257 QString pkgKey = PACKAGE_PREFIX+packageName; 00258 00259 if (packageState == PACKAGE_STATE_BROKEN) { 00260 // emit operation error for a broken package 00261 emit operationError(desktopEntryPath, QString()); 00262 } 00263 00264 dataStore->createValue(pkgKey, desktopEntryPath); 00265 00266 if (activePackages.contains(packageName)) { 00267 // Package is being installed, add the desktop entry path directly 00268 activePackages[packageName].desktopEntryName = desktopEntryPath; 00269 } 00270 } 00271 00272 extraDirWatcher->updateDataForDesktopEntry(desktopEntryPath, packageState); 00273 } 00274 00275 QString ApplicationPackageMonitor::desktopEntryName(const QString &packageName) 00276 { 00277 QString pkgKey = PACKAGE_PREFIX+packageName; 00278 00279 if (!dataStore->contains(pkgKey)) { 00280 // Package not installed 00281 return QString(); 00282 } 00283 00284 if (!QFile::exists(dataStore->value(pkgKey).toString())) { 00285 // The extra desktop file doesn't exist anymore, the package has been uninstalled 00286 dataStore->remove(pkgKey); 00287 return QString(); 00288 } 00289 00290 return dataStore->value(pkgKey).toString(); 00291 } 00292 00293 ApplicationPackageMonitor::ExtraDirWatcher::ExtraDirWatcher(MDataStore *dataStore, const QString &directoryPath) : 00294 LauncherDataStore(dataStore, directoryPath) 00295 { 00296 } 00297 00298 ApplicationPackageMonitor::ExtraDirWatcher::~ExtraDirWatcher() 00299 { 00300 } 00301 00302 bool ApplicationPackageMonitor::ExtraDirWatcher::isDesktopEntryValid(const MDesktopEntry &entry, const QStringList &acceptedTypes) 00303 { 00304 Q_UNUSED(acceptedTypes); 00305 00306 return entry.contains(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_NAME) 00307 && entry.contains(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_STATE); 00308 }
| Copyright © 2010 Nokia Corporation | Generated on Thu Nov 4 2010 18:20:42 Doxygen 1.7.1 |
MeeGo Touch |