ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

cloudmanager.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "backends/cloud/cloudmanager.h"
00024 #include "backends/cloud/box/boxstorage.h"
00025 #include "backends/cloud/dropbox/dropboxstorage.h"
00026 #include "backends/cloud/onedrive/onedrivestorage.h"
00027 #include "backends/cloud/googledrive/googledrivestorage.h"
00028 #include "common/translation.h"
00029 #include "common/config-manager.h"
00030 #include "common/str.h"
00031 #ifdef USE_SDL_NET
00032 #include "backends/networking/sdl_net/localwebserver.h"
00033 #endif
00034 
00035 namespace Common {
00036 
00037 DECLARE_SINGLETON(Cloud::CloudManager);
00038 
00039 }
00040 
00041 namespace Cloud {
00042 
00043 const char *const CloudManager::kStoragePrefix = "storage_";
00044 
00045 CloudManager::CloudManager() : _currentStorageIndex(0), _activeStorage(nullptr) {}
00046 
00047 CloudManager::~CloudManager() {
00048     g_system->getEventManager()->getEventDispatcher()->unregisterSource(this);
00049 
00050     delete _activeStorage;
00051     freeStorages();
00052 }
00053 
00054 Common::String CloudManager::getStorageConfigName(uint32 index) const {
00055     switch (index) {
00056     case kStorageNoneId: return "<none>";
00057     case kStorageDropboxId: return "Dropbox";
00058     case kStorageOneDriveId: return "OneDrive";
00059     case kStorageGoogleDriveId: return "GoogleDrive";
00060     case kStorageBoxId: return "Box";
00061     }
00062     assert(false); // Unhandled StorageID value
00063     return "";
00064 }
00065 
00066 void CloudManager::loadStorage() {
00067     switch (_currentStorageIndex) {
00068     case kStorageDropboxId:
00069         _activeStorage = Dropbox::DropboxStorage::loadFromConfig(kStoragePrefix + getStorageConfigName(_currentStorageIndex) + "_");
00070         break;
00071     case kStorageOneDriveId:
00072         _activeStorage = OneDrive::OneDriveStorage::loadFromConfig(kStoragePrefix + getStorageConfigName(_currentStorageIndex) + "_");
00073         break;
00074     case kStorageGoogleDriveId:
00075         _activeStorage = GoogleDrive::GoogleDriveStorage::loadFromConfig(kStoragePrefix + getStorageConfigName(_currentStorageIndex) + "_");
00076         break;
00077     case kStorageBoxId:
00078         _activeStorage = Box::BoxStorage::loadFromConfig(kStoragePrefix + getStorageConfigName(_currentStorageIndex) + "_");
00079         break;
00080     default:
00081         _activeStorage = nullptr;
00082     }
00083 
00084     if (!_activeStorage) {
00085         _currentStorageIndex = kStorageNoneId;
00086     }
00087 }
00088 
00089 void CloudManager::init() {
00090     //init configs structs
00091     for (uint32 i = 0; i < kStorageTotal; ++i) {
00092         Common::String name = getStorageConfigName(i);
00093         StorageConfig config;
00094         config.name = _(name);
00095         config.username = "";
00096         config.lastSyncDate = "";
00097         config.usedBytes = 0;
00098         if (ConfMan.hasKey(kStoragePrefix + name + "_username", ConfMan.kCloudDomain))
00099             config.username = ConfMan.get(kStoragePrefix + name + "_username", ConfMan.kCloudDomain);
00100         if (ConfMan.hasKey(kStoragePrefix + name + "_lastSync", ConfMan.kCloudDomain))
00101             config.lastSyncDate = ConfMan.get(kStoragePrefix + name + "_lastSync", ConfMan.kCloudDomain);
00102         if (ConfMan.hasKey(kStoragePrefix + name + "_usedBytes", ConfMan.kCloudDomain))
00103             config.usedBytes = ConfMan.get(kStoragePrefix + name + "_usedBytes", ConfMan.kCloudDomain).asUint64();
00104         _storages.push_back(config);
00105     }
00106 
00107     //load an active storage if there is any
00108     _currentStorageIndex = kStorageNoneId;
00109     if (ConfMan.hasKey("current_storage", ConfMan.kCloudDomain))
00110         _currentStorageIndex = ConfMan.getInt("current_storage", ConfMan.kCloudDomain);
00111 
00112     loadStorage();
00113 
00114     g_system->getEventManager()->getEventDispatcher()->registerSource(this, false);
00115 }
00116 
00117 void CloudManager::save() {
00118     for (uint32 i = 0; i < _storages.size(); ++i) {
00119         if (i == kStorageNoneId)
00120             continue;
00121         Common::String name = getStorageConfigName(i);
00122         ConfMan.set(kStoragePrefix + name + "_username", _storages[i].username, ConfMan.kCloudDomain);
00123         ConfMan.set(kStoragePrefix + name + "_lastSync", _storages[i].lastSyncDate, ConfMan.kCloudDomain);
00124         ConfMan.set(kStoragePrefix + name + "_usedBytes", Common::String::format("%lu", _storages[i].usedBytes), ConfMan.kCloudDomain);
00125     }
00126 
00127     ConfMan.set("current_storage", Common::String::format("%u", _currentStorageIndex), ConfMan.kCloudDomain);
00128     if (_activeStorage)
00129         _activeStorage->saveConfig(kStoragePrefix + getStorageConfigName(_currentStorageIndex) + "_");
00130     ConfMan.flushToDisk();
00131 }
00132 
00133 void CloudManager::replaceStorage(Storage *storage, uint32 index) {
00134     freeStorages();
00135     if (!storage)
00136         error("CloudManager::replaceStorage: NULL storage passed");
00137     if (index >= kStorageTotal)
00138         error("CloudManager::replaceStorage: invalid index passed");
00139     if (_activeStorage != nullptr && _activeStorage->isWorking()) {
00140         warning("CloudManager::replaceStorage: replacing Storage while the other is working");
00141         if (_activeStorage->isDownloading())
00142             _activeStorage->cancelDownload();
00143         if (_activeStorage->isSyncing())
00144             _activeStorage->cancelSync();
00145         removeStorage(_activeStorage);
00146     } else {
00147         delete _activeStorage;
00148     }
00149     _activeStorage = storage;
00150     _currentStorageIndex = index;
00151     save();
00152 
00153     //do what should be done on first Storage connect
00154     if (_activeStorage) {
00155         _activeStorage->info(nullptr, nullptr); //automatically calls setStorageUsername()
00156         _activeStorage->syncSaves(nullptr, nullptr);
00157     }
00158 }
00159 
00160 void CloudManager::removeStorage(Storage *storage) {
00161     // can't just delete it as it's mostly likely the one who calls the method
00162     // it would be freed on freeStorages() call (on next Storage connect or replace)
00163     _storagesToRemove.push_back(storage);
00164 }
00165 
00166 void CloudManager::freeStorages() {
00167     for (uint32 i = 0; i < _storagesToRemove.size(); ++i)
00168         delete _storagesToRemove[i];
00169     _storagesToRemove.clear();
00170 }
00171 
00172 void CloudManager::passNoStorageConnected(Networking::ErrorCallback errorCallback) const {
00173     if (errorCallback == nullptr)
00174         return;
00175     (*errorCallback)(Networking::ErrorResponse(nullptr, false, true, "No Storage connected!", -1));
00176 }
00177 
00178 Storage *CloudManager::getCurrentStorage() const {
00179     return _activeStorage;
00180 }
00181 
00182 uint32 CloudManager::getStorageIndex() const {
00183     return _currentStorageIndex;
00184 }
00185 
00186 Common::StringArray CloudManager::listStorages() const {
00187     Common::StringArray result;
00188     for (uint32 i = 0; i < _storages.size(); ++i) {
00189         result.push_back(_storages[i].name);
00190     }
00191     return result;
00192 }
00193 
00194 bool CloudManager::switchStorage(uint32 index) {
00195     if (index >= _storages.size()) {
00196         warning("CloudManager::switchStorage: invalid index passed");
00197         return false;
00198     }
00199 
00200     Storage *storage = getCurrentStorage();
00201     if (storage && storage->isWorking()) {
00202         warning("CloudManager::switchStorage: another storage is working now");
00203         return false;
00204     }
00205 
00206     _currentStorageIndex = index;
00207     loadStorage();
00208     save();
00209     return true;
00210 }
00211 
00212 Common::String CloudManager::getStorageUsername(uint32 index) {
00213     if (index >= _storages.size())
00214         return "";
00215     return _storages[index].username;
00216 }
00217 
00218 uint64 CloudManager::getStorageUsedSpace(uint32 index) {
00219     if (index >= _storages.size())
00220         return 0;
00221     return _storages[index].usedBytes;
00222 }
00223 
00224 Common::String CloudManager::getStorageLastSync(uint32 index) {
00225     if (index >= _storages.size())
00226         return "";
00227     if (index == _currentStorageIndex && isSyncing())
00228         return "";
00229     return _storages[index].lastSyncDate;
00230 }
00231 
00232 void CloudManager::setStorageUsername(uint32 index, Common::String name) {
00233     if (index >= _storages.size())
00234         return;
00235     _storages[index].username = name;
00236     save();
00237 }
00238 
00239 void CloudManager::setStorageUsedSpace(uint32 index, uint64 used) {
00240     if (index >= _storages.size())
00241         return;
00242     _storages[index].usedBytes = used;
00243     save();
00244 }
00245 
00246 void CloudManager::setStorageLastSync(uint32 index, Common::String date) {
00247     if (index >= _storages.size())
00248         return;
00249     _storages[index].lastSyncDate = date;
00250     save();
00251 }
00252 
00253 void CloudManager::connectStorage(uint32 index, Common::String code) {
00254     freeStorages();
00255 
00256     switch (index) {
00257     case kStorageDropboxId:
00258         new Dropbox::DropboxStorage(code);
00259         break;
00260     case kStorageOneDriveId:
00261         new OneDrive::OneDriveStorage(code);
00262         break;
00263     case kStorageGoogleDriveId:
00264         new GoogleDrive::GoogleDriveStorage(code);
00265         break;
00266     case kStorageBoxId:
00267         new Box::BoxStorage(code);
00268         break;
00269     }
00270     // in these constructors Storages request token using the passed code
00271     // when the token is received, they call replaceStorage()
00272     // or removeStorage(), if some error occurred
00273     // thus, no memory leak happens
00274 }
00275 
00276 Networking::Request *CloudManager::listDirectory(Common::String path, Storage::ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {
00277     Storage *storage = getCurrentStorage();
00278     if (storage) {
00279         return storage->listDirectory(path, callback, errorCallback, recursive);
00280     } else {
00281         passNoStorageConnected(errorCallback);
00282         delete callback;
00283         delete errorCallback;
00284     }
00285     return nullptr;
00286 }
00287 
00288 Networking::Request *CloudManager::downloadFolder(Common::String remotePath, Common::String localPath, Storage::FileArrayCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {
00289     Storage *storage = getCurrentStorage();
00290     if (storage) {
00291         return storage->downloadFolder(remotePath, localPath, callback, errorCallback, recursive);
00292     } else {
00293         passNoStorageConnected(errorCallback);
00294         delete callback;
00295         delete errorCallback;
00296     }
00297     return nullptr;
00298 }
00299 
00300 Networking::Request *CloudManager::info(Storage::StorageInfoCallback callback, Networking::ErrorCallback errorCallback) {
00301     Storage *storage = getCurrentStorage();
00302     if (storage) {
00303         return storage->info(callback, errorCallback);
00304     } else {
00305         passNoStorageConnected(errorCallback);
00306         delete callback;
00307         delete errorCallback;
00308     }
00309     return nullptr;
00310 }
00311 
00312 Common::String CloudManager::savesDirectoryPath() {
00313     Storage *storage = getCurrentStorage();
00314     if (storage)
00315         return storage->savesDirectoryPath();
00316     return "";
00317 }
00318 
00319 SavesSyncRequest *CloudManager::syncSaves(Storage::BoolCallback callback, Networking::ErrorCallback errorCallback) {
00320     Storage *storage = getCurrentStorage();
00321     if (storage) {
00322         setStorageLastSync(_currentStorageIndex, "???"); //TODO get the date
00323         return storage->syncSaves(callback, errorCallback);
00324     } else {
00325         passNoStorageConnected(errorCallback);
00326         delete callback;
00327         delete errorCallback;
00328     }
00329     return nullptr;
00330 }
00331 
00332 bool CloudManager::isWorking() const {
00333     Storage *storage = getCurrentStorage();
00334     if (storage)
00335         return storage->isWorking();
00336     return false;
00337 }
00338 
00339 bool CloudManager::couldUseLocalServer() {
00340 #ifdef USE_SDL_NET
00341     return Networking::LocalWebserver::getPort() == Networking::LocalWebserver::DEFAULT_SERVER_PORT;
00342 #else
00343     return false;
00344 #endif
00345 }
00346 
00348 
00349 bool CloudManager::isSyncing() const {
00350     Storage *storage = getCurrentStorage();
00351     if (storage)
00352         return storage->isSyncing();
00353     return false;
00354 }
00355 
00356 double CloudManager::getSyncDownloadingProgress() const {
00357     Storage *storage = getCurrentStorage();
00358     if (storage)
00359         return storage->getSyncDownloadingProgress();
00360     return 1;
00361 }
00362 
00363 double CloudManager::getSyncProgress() const {
00364     Storage *storage = getCurrentStorage();
00365     if (storage)
00366         return storage->getSyncProgress();
00367     return 1;
00368 }
00369 
00370 Common::Array<Common::String> CloudManager::getSyncingFiles() const {
00371     Storage *storage = getCurrentStorage();
00372     if (storage)
00373         return storage->getSyncingFiles();
00374     return Common::Array<Common::String>();
00375 }
00376 
00377 void CloudManager::cancelSync() const {
00378     Storage *storage = getCurrentStorage();
00379     if (storage)
00380         storage->cancelSync();
00381 }
00382 
00383 void CloudManager::setSyncTarget(GUI::CommandReceiver *target) const {
00384     Storage *storage = getCurrentStorage();
00385     if (storage)
00386         storage->setSyncTarget(target);
00387 }
00388 
00389 void CloudManager::showCloudDisabledIcon() {
00390     _icon.show(CloudIcon::kDisabled, 3000);
00391 }
00392 
00394 
00395 bool CloudManager::startDownload(Common::String remotePath, Common::String localPath) const {
00396     Storage *storage = getCurrentStorage();
00397     if (storage)
00398         return storage->startDownload(remotePath, localPath);
00399     return false;
00400 }
00401 
00402 void CloudManager::cancelDownload() const {
00403     Storage *storage = getCurrentStorage();
00404     if (storage)
00405         storage->cancelDownload();
00406 }
00407 
00408 void CloudManager::setDownloadTarget(GUI::CommandReceiver *target) const {
00409     Storage *storage = getCurrentStorage();
00410     if (storage)
00411         storage->setDownloadTarget(target);
00412 }
00413 
00414 bool CloudManager::isDownloading() const {
00415     Storage *storage = getCurrentStorage();
00416     if (storage)
00417         return storage->isDownloading();
00418     return false;
00419 }
00420 
00421 double CloudManager::getDownloadingProgress() const {
00422     Storage *storage = getCurrentStorage();
00423     if (storage)
00424         return storage->getDownloadingProgress();
00425     return 1;
00426 }
00427 
00428 uint64 CloudManager::getDownloadBytesNumber() const {
00429     Storage *storage = getCurrentStorage();
00430     if (storage)
00431         return storage->getDownloadBytesNumber();
00432     return 0;
00433 }
00434 
00435 uint64 CloudManager::getDownloadTotalBytesNumber() const {
00436     Storage *storage = getCurrentStorage();
00437     if (storage)
00438         return storage->getDownloadTotalBytesNumber();
00439     return 0;
00440 }
00441 
00442 uint64 CloudManager::getDownloadSpeed() const {
00443     Storage *storage = getCurrentStorage();
00444     if (storage)
00445         return storage->getDownloadSpeed();
00446     return 0;
00447 }
00448 
00449 Common::String CloudManager::getDownloadRemoteDirectory() const {
00450     Storage *storage = getCurrentStorage();
00451     if (storage)
00452         return storage->getDownloadRemoteDirectory();
00453     return "";
00454 }
00455 
00456 Common::String CloudManager::getDownloadLocalDirectory() const {
00457     Storage *storage = getCurrentStorage();
00458     if (storage)
00459         return storage->getDownloadLocalDirectory();
00460     return "";
00461 }
00462 
00463 bool CloudManager::pollEvent(Common::Event &event) {
00464     if (_icon.needsUpdate()) {
00465         if (_icon.getShownType() != CloudIcon::kDisabled) {
00466             if (isWorking()) {
00467                 _icon.show(CloudIcon::kSyncing);
00468             } else {
00469                 _icon.show(CloudIcon::kNone);
00470             }
00471         }
00472 
00473         _icon.update();
00474     }
00475 
00476     return false;
00477 }
00478 
00479 } // End of namespace Cloud


Generated on Sat Mar 23 2019 05:01:23 for ResidualVM by doxygen 1.7.1
curved edge   curved edge