Move file provider domain management to specific class
authorClaudio Cambra <claudio.cambra@nextcloud.com>
Tue, 13 Dec 2022 15:53:36 +0000 (16:53 +0100)
committerClaudio Cambra <claudio.cambra@nextcloud.com>
Fri, 12 May 2023 05:21:07 +0000 (13:21 +0800)
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
src/gui/CMakeLists.txt
src/gui/macOS/fileprovider.h
src/gui/macOS/fileprovider_mac.mm
src/gui/macOS/fileproviderdomainmanager.h [new file with mode: 0644]
src/gui/macOS/fileproviderdomainmanager_mac.mm [new file with mode: 0644]
src/gui/macOS/fileproviderinterface.h [deleted file]

index 0311b3318d4e96a1e5cf01dbd40a850ddb14be80..726308289791ff4a0605136bf0d6cb618e3e80bb 100644 (file)
@@ -282,7 +282,9 @@ IF( APPLE )
     list(APPEND client_SRCS systray.mm)
     list(APPEND client_SRCS
         macOS/fileprovider.h
-        macOS/fileprovider_mac.mm)
+        macOS/fileprovider_mac.mm
+        macOS/fileproviderdomainmanager.h
+        macOS/fileproviderdomainmanager_mac.mm)
 
     if(SPARKLE_FOUND AND BUILD_UPDATER)
         # Define this, we need to check in updater.cpp
index 8c6ddc654797d134bebf50f0d49a35518a0116f6..24ec7f702c476939b387db1c25d04d775ec16dea 100644 (file)
  * for more details.
  */
 
-#ifndef FILEPROVIDER_H
-#define FILEPROVIDER_H
+#pragma once
 
 #include <QObject>
-#include <QScopedPointer>
 
 namespace OCC {
 
-class AccountState;
-
 namespace Mac {
 
 // NOTE: For the file provider extension to work, the app bundle will
@@ -31,23 +27,11 @@ class FileProvider : public QObject
 {
 public:
     static FileProvider *instance();
-    ~FileProvider() override;
-
-    void setupFileProviderDomains();
-
-private slots:
-    void addFileProviderDomainForAccount(AccountState *accountState);
-    void removeFileProviderDomainForAccount(AccountState *accountState);
-    void setFileProviderForAccountIsConnected(AccountState *accountState);
+    ~FileProvider() = default;
 
 private:
     explicit FileProvider(QObject *parent = nullptr);
-    static FileProvider *_instance;
-    class Private;
-    QScopedPointer<Private> d;
 };
 
 } // namespace Mac
 } // namespace OCC
-
-#endif
index a29efa354e08aeb0c6314fcc2c10e13f565fd33b..65d34da19904f297cb1521e8044763bf205b220d 100644 (file)
  * for more details.
  */
 
-
 #import <Foundation/Foundation.h>
-#import <FileProvider/FileProvider.h>
 
 #include <QLoggingCategory>
 
-#include "gui/accountmanager.h"
-#include "gui/accountstate.h"
-#include "libsync/account.h"
 #include "fileprovider.h"
+#include "fileproviderdomainmanager.h"
 
 namespace OCC {
 
@@ -29,126 +25,15 @@ Q_LOGGING_CATEGORY(lcMacFileProvider, "nextcloud.gui.macfileprovider", QtInfoMsg
 
 namespace Mac {
 
-FileProvider *FileProvider::_instance = nullptr;
-
-class FileProvider::Private {
-  public:
-    Private()
-    {
-    }
-
-    ~Private() = default;
-
-    void addFileProviderDomain(const AccountState *accountState)
-    {
-        const QString accountDisplayName = accountState->account()->displayName();
-        const QString accountId = accountState->account()->id();
-
-        qCDebug(lcMacFileProvider) << "Adding new file provider domain for account with id: " << accountId;
-
-        if(_registeredDomains.contains(accountId) && _registeredDomains.value(accountId) != nil) {
-            qCDebug(lcMacFileProvider) << "File provider domain for account with id already exists: " << accountId;
-            return;
-        }
-
-        NSFileProviderDomain *fileProviderDomain = [[NSFileProviderDomain alloc] initWithIdentifier:accountId.toNSString() displayName:accountDisplayName.toNSString()];
-        [NSFileProviderManager addDomain:fileProviderDomain completionHandler:^(NSError *error) {
-            if(error) {
-                qCDebug(lcMacFileProvider) << "Error adding file provider domain: " << [error code] << [error localizedDescription];
-            }
-        }];
-
-        _registeredDomains.insert(accountId, fileProviderDomain);
-    }
-
-    void removeFileProviderDomain(const AccountState *accountState)
-    {
-        const QString accountId = accountState->account()->id();
-        qCDebug(lcMacFileProvider) << "Removing file provider domain for account with id: " << accountId;
-
-        if(!_registeredDomains.contains(accountId)) {
-            qCDebug(lcMacFileProvider) << "File provider domain not found for id: " << accountId;
-            return;
-        }
-
-        NSFileProviderDomain* fileProviderDomain = _registeredDomains[accountId];
-
-        [NSFileProviderManager removeDomain:fileProviderDomain completionHandler:^(NSError *error) {
-            if(error) {
-                qCDebug(lcMacFileProvider) << "Error removing file provider domain: " << [error code] << [error localizedDescription];
-            }
-        }];
-
-        NSFileProviderDomain* domain = _registeredDomains.take(accountId);
-        [domain release];
-    }
-
-    void removeAllFileProviderDomains()
-    {
-        qCDebug(lcMacFileProvider) << "Removing all file provider domains.";
-
-        [NSFileProviderManager removeAllDomainsWithCompletionHandler:^(NSError *error) {
-            if(error) {
-                qCDebug(lcMacFileProvider) << "Error removing all file provider domains: " << [error code] << [error localizedDescription];
-            }
-        }];
-    }
-
-    void setFileProviderDomainConnected(const AccountState *accountState)
-    {
-        const QString accountDisplayName = accountState->account()->displayName();
-        const QString accountId = accountState->account()->id();
-        const bool accountIsConnected = accountState->isConnected();
-
-        qCDebug(lcMacFileProvider) << "Account state for account changed: " << accountDisplayName << accountIsConnected;
-
-        if(!_registeredDomains.contains(accountId)) {
-            qCDebug(lcMacFileProvider) << "File provider domain not found for id: " << accountId;
-            return;
-        }
-
-        NSFileProviderDomain* accountDomain = _registeredDomains.value(accountId);
-        NSFileProviderManager* providerManager = [NSFileProviderManager managerForDomain:accountDomain];
-
-        if(accountIsConnected) {
-            [providerManager reconnectWithCompletionHandler:^(NSError *error) {
-                if(error) {
-                    qCDebug(lcMacFileProvider) << "Error reconnecting file provider domain: " << accountDisplayName << [error code] << [error localizedDescription];
-                }
-            }];
-        } else {
-            NSString* reason = @"Nextcloud account disconnected.";
-            const auto isTemporary = accountState->state() != AccountState::SignedOut && accountState->state() != AccountState::ConfigurationError;
-            NSFileProviderManagerDisconnectionOptions disconnectOption = isTemporary ? 0 : NSFileProviderManagerDisconnectionOptionsTemporary;
-
-            [providerManager disconnectWithReason:reason options:disconnectOption completionHandler:^(NSError *error) {
-                if(error) {
-                    qCDebug(lcMacFileProvider) << "Error disconnecting file provider domain: " << accountDisplayName << [error code] << [error localizedDescription];
-                }
-            }];
-        }
-    }
-
-private:
-    QHash<QString, NSFileProviderDomain*> _registeredDomains;
-};
+static FileProvider *_instance = nullptr;
 
 FileProvider::FileProvider(QObject *parent)
     : QObject(parent)
 {
-    d.reset(new FileProvider::Private());
-
-    connect(AccountManager::instance(), &AccountManager::accountAdded,
-            this, &FileProvider::addFileProviderDomainForAccount);
-    connect(AccountManager::instance(), &AccountManager::accountRemoved,
-            this, &FileProvider::removeFileProviderDomainForAccount);
-
-    setupFileProviderDomains(); // Initially fetch accounts in manager
-}
-
-FileProvider::~FileProvider()
-{
-    d->removeAllFileProviderDomains();
+    const auto domainManager = FileProviderDomainManager::instance();
+    if (domainManager) {
+        qCDebug(lcMacFileProvider()) << "Initialized file provider domain manager";
+    }
 }
 
 FileProvider *FileProvider::instance()
@@ -159,30 +44,5 @@ FileProvider *FileProvider::instance()
     return _instance;
 }
 
-void FileProvider::setupFileProviderDomains()
-{
-    for(auto &accountState : AccountManager::instance()->accounts()) {
-        addFileProviderDomainForAccount(accountState.data());
-    }
-}
-
-void FileProvider::addFileProviderDomainForAccount(AccountState *accountState)
-{
-    d->addFileProviderDomain(accountState);
-
-    connect(accountState, &AccountState::isConnectedChanged,
-            this, [this, accountState]{ setFileProviderForAccountIsConnected(accountState); });
-}
-
-void FileProvider::removeFileProviderDomainForAccount(AccountState* accountState)
-{
-    d->removeFileProviderDomain(accountState);
-}
-
-void FileProvider::setFileProviderForAccountIsConnected(AccountState *accountState)
-{
-    d->setFileProviderDomainConnected(accountState);
-}
-
 } // namespace Mac
 } // namespace OCC
diff --git a/src/gui/macOS/fileproviderdomainmanager.h b/src/gui/macOS/fileproviderdomainmanager.h
new file mode 100644 (file)
index 0000000..a788bf8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 by Claudio Cambra <claudio.cambra@nextcloud.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#pragma once
+
+#include <QObject>
+
+namespace OCC {
+
+class AccountState;
+
+namespace Mac {
+
+class FileProviderDomainManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    static FileProviderDomainManager *instance();
+    ~FileProviderDomainManager() override;
+
+private slots:
+    void setupFileProviderDomains();
+
+    void addFileProviderDomainForAccount(OCC::AccountState *accountState);
+    void removeFileProviderDomainForAccount(OCC::AccountState *accountState);
+    void setFileProviderForAccountIsConnected(OCC::AccountState *accountState);
+
+private:
+    explicit FileProviderDomainManager(QObject *parent = nullptr);
+    static FileProviderDomainManager *_instance;
+    class Private;
+    QScopedPointer<Private> d;
+
+};
+
+} // namespace Mac
+
+} // namespace OCC
diff --git a/src/gui/macOS/fileproviderdomainmanager_mac.mm b/src/gui/macOS/fileproviderdomainmanager_mac.mm
new file mode 100644 (file)
index 0000000..6e67076
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2022 by Claudio Cambra <claudio.cambra@nextcloud.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "fileproviderdomainmanager.h"
+
+#import <FileProvider/FileProvider.h>
+
+#include <QLoggingCategory>
+
+#include "gui/accountmanager.h"
+#include "gui/accountstate.h"
+#include "libsync/account.h"
+
+namespace OCC {
+
+Q_LOGGING_CATEGORY(lcMacFileProviderDomainManager, "nextcloud.gui.macfileproviderdomainmanager", QtInfoMsg)
+
+namespace Mac {
+
+FileProviderDomainManager *FileProviderDomainManager::_instance = nullptr;
+
+class FileProviderDomainManager::Private {
+  public:
+    Private()
+    {
+    }
+
+    ~Private() = default;
+
+    void addFileProviderDomain(const AccountState *accountState)
+    {
+        const QString accountDisplayName = accountState->account()->displayName();
+        const QString accountId = accountState->account()->id();
+
+        qCDebug(lcMacFileProviderDomainManager) << "Adding new file provider domain for account with id: " << accountId;
+
+        if(_registeredDomains.contains(accountId) && _registeredDomains.value(accountId) != nil) {
+            qCDebug(lcMacFileProviderDomainManager) << "File provider domain for account with id already exists: " << accountId;
+            return;
+        }
+
+        NSFileProviderDomain *fileProviderDomain = [[NSFileProviderDomain alloc] initWithIdentifier:accountId.toNSString()
+                                                                                        displayName:accountDisplayName.toNSString()];
+        [NSFileProviderManager addDomain:fileProviderDomain completionHandler:^(NSError *error) {
+            if(error) {
+                qCDebug(lcMacFileProviderDomainManager) << "Error adding file provider domain: "
+                                                        << [error code]
+                                                        << [error localizedDescription];
+            }
+        }];
+
+        _registeredDomains.insert(accountId, fileProviderDomain);
+    }
+
+    void removeFileProviderDomain(const AccountState *accountState)
+    {
+        const QString accountId = accountState->account()->id();
+        qCDebug(lcMacFileProviderDomainManager) << "Removing file provider domain for account with id: " << accountId;
+
+        if(!_registeredDomains.contains(accountId)) {
+            qCDebug(lcMacFileProviderDomainManager) << "File provider domain not found for id: " << accountId;
+            return;
+        }
+
+        NSFileProviderDomain* fileProviderDomain = _registeredDomains[accountId];
+
+        [NSFileProviderManager removeDomain:fileProviderDomain completionHandler:^(NSError *error) {
+            if(error) {
+                qCDebug(lcMacFileProviderDomainManager) << "Error removing file provider domain: "
+                                                        << [error code]
+                                                        << [error localizedDescription];
+            }
+        }];
+
+        NSFileProviderDomain* domain = _registeredDomains.take(accountId);
+        [domain release];
+    }
+
+    void removeAllFileProviderDomains()
+    {
+        qCDebug(lcMacFileProviderDomainManager) << "Removing all file provider domains.";
+
+        [NSFileProviderManager removeAllDomainsWithCompletionHandler:^(NSError *error) {
+            if(error) {
+                qCDebug(lcMacFileProviderDomainManager) << "Error removing all file provider domains: "
+                                                        << [error code]
+                                                        << [error localizedDescription];
+            }
+        }];
+    }
+
+    void setFileProviderDomainConnected(const AccountState *accountState)
+    {
+        const QString accountDisplayName = accountState->account()->displayName();
+        const QString accountId = accountState->account()->id();
+        const bool accountIsConnected = accountState->isConnected();
+
+        qCDebug(lcMacFileProviderDomainManager) << "Account state for account changed: "
+                                                << accountDisplayName
+                                                << accountIsConnected;
+
+        if(!_registeredDomains.contains(accountId)) {
+            qCDebug(lcMacFileProviderDomainManager) << "File provider domain not found for id: " << accountId;
+            return;
+        }
+
+        NSFileProviderDomain* accountDomain = _registeredDomains.value(accountId);
+        NSFileProviderManager* providerManager = [NSFileProviderManager managerForDomain:accountDomain];
+
+        if(accountIsConnected) {
+            [providerManager reconnectWithCompletionHandler:^(NSError *error) {
+                if(error) {
+                    qCDebug(lcMacFileProviderDomainManager) << "Error reconnecting file provider domain: "
+                                                            << accountDisplayName
+                                                            << [error code]
+                                                            << [error localizedDescription];
+                }
+            }];
+        } else {
+            NSString* reason = @"Nextcloud account disconnected.";
+            const auto isTemporary = accountState->state() != AccountState::SignedOut &&
+                                     accountState->state() != AccountState::ConfigurationError;
+            NSFileProviderManagerDisconnectionOptions disconnectOption = isTemporary ? 0 : NSFileProviderManagerDisconnectionOptionsTemporary;
+
+            [providerManager disconnectWithReason:reason options:disconnectOption completionHandler:^(NSError *error) {
+                if(error) {
+                    qCDebug(lcMacFileProviderDomainManager) << "Error disconnecting file provider domain: "
+                                               << accountDisplayName
+                                               << [error code]
+                                               << [error localizedDescription];
+                }
+            }];
+        }
+    }
+
+private:
+    QHash<QString, NSFileProviderDomain*> _registeredDomains;
+};
+
+FileProviderDomainManager::FileProviderDomainManager(QObject *parent)
+    : QObject(parent)
+{
+    d.reset(new FileProviderDomainManager::Private());
+
+    connect(AccountManager::instance(), &AccountManager::accountAdded,
+            this, &FileProviderDomainManager::addFileProviderDomainForAccount);
+    connect(AccountManager::instance(), &AccountManager::accountRemoved,
+            this, &FileProviderDomainManager::removeFileProviderDomainForAccount);
+
+    setupFileProviderDomains(); // Initially fetch accounts in manager
+}
+
+FileProviderDomainManager::~FileProviderDomainManager()
+{
+    d->removeAllFileProviderDomains();
+}
+
+FileProviderDomainManager *FileProviderDomainManager::instance()
+{
+    if (!_instance) {
+        _instance = new FileProviderDomainManager();
+    }
+    return _instance;
+}
+
+void FileProviderDomainManager::setupFileProviderDomains()
+{
+    for(auto &accountState : AccountManager::instance()->accounts()) {
+        addFileProviderDomainForAccount(accountState.data());
+    }
+}
+
+void FileProviderDomainManager::addFileProviderDomainForAccount(AccountState *accountState)
+{
+    d->addFileProviderDomain(accountState);
+
+    connect(accountState, &AccountState::isConnectedChanged,
+            this, [this, accountState]{ setFileProviderForAccountIsConnected(accountState); });
+}
+
+void FileProviderDomainManager::removeFileProviderDomainForAccount(AccountState* accountState)
+{
+    d->removeFileProviderDomain(accountState);
+}
+
+void FileProviderDomainManager::setFileProviderForAccountIsConnected(AccountState *accountState)
+{
+    d->setFileProviderDomainConnected(accountState);
+}
+
+} // namespace Mac
+
+} // namespace OCC
diff --git a/src/gui/macOS/fileproviderinterface.h b/src/gui/macOS/fileproviderinterface.h
deleted file mode 100644 (file)
index fe722ae..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef FILEPROVIDERINTERFACE_H
-#define FILEPROVIDERINTERFACE_H
-
-#endif // FILEPROVIDERINTERFACE_H