Ejemplo n.º 1
0
void PlasmoidProtocol::restorePlasmoids()
{
    if (!m_systrayApplet) {
        return;
    }
    //First: remove all that are not allowed anymore
    QStringList tasksToDelete;
    foreach (const QString &task, m_tasks.keys()) {
        if (!m_allowedPlugins.contains(task)) {
            tasksToDelete << task;
        }
    }

    // Check if we want to remove applets based on formfactor
    foreach (const QString &task, m_tasks.keys()) {
        PlasmoidTask *plasmoidtask = qobject_cast<PlasmoidTask*>(m_tasks[task]);
        if (plasmoidtask) {
            KPluginMetaData md = plasmoidtask->pluginInfo().toMetaData();
            if (!md.formFactors().isEmpty() && !md.formFactors().contains(m_formFactor)) {
                if (!tasksToDelete.contains(task)) {
                    tasksToDelete << task;
                }
            }
        }
    }

    foreach (const QString &task, tasksToDelete) {
        cleanupTask(task);
    }
Ejemplo n.º 2
0
ThemeInfo::ThemeInfo( const KPluginMetaData& data )
    : id( data.pluginId() )
    , name( data.name() )
    , description( data.description() )
    , widget( nullptr )
{
}
Ejemplo n.º 3
0
void Device::reloadPlugins()
{
    QHash<QString, KdeConnectPlugin*> newPluginMap;
    QMultiMap<QString, KdeConnectPlugin*> newPluginsByIncomingInterface;
    QMultiMap<QString, KdeConnectPlugin*> newPluginsByOutgoingInterface;
    QSet<QString> supportedIncomingInterfaces;
    QSet<QString> supportedOutgoingInterfaces;
    QStringList unsupportedPlugins;

    if (isPaired() && isReachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices

        KConfigGroup pluginStates = KSharedConfig::openConfig(pluginsConfigFile())->group("Plugins");

        PluginLoader* loader = PluginLoader::instance();
        const bool deviceSupportsCapabilities = !m_incomingCapabilities.isEmpty() || !m_outgoingCapabilities.isEmpty();

        foreach (const QString& pluginName, loader->getPluginList()) {
            const KPluginMetaData service = loader->getPluginInfo(pluginName);
            const QSet<QString> incomingInterfaces = KPluginMetaData::readStringList(service.rawData(), "X-KdeConnect-SupportedPackageType").toSet();
            const QSet<QString> outgoingInterfaces = KPluginMetaData::readStringList(service.rawData(), "X-KdeConnect-OutgoingPackageType").toSet();

            const bool pluginEnabled = isPluginEnabled(pluginName);

            if (pluginEnabled) {
                supportedIncomingInterfaces += incomingInterfaces;
                supportedOutgoingInterfaces += outgoingInterfaces;
            }

            //If we don't find intersection with the received on one end and the sent on the other, we don't
            //let the plugin stay
            //Also, if no capabilities are specified on the other end, we don't apply this optimizaton, as
            //we assume that the other client doesn't know about capabilities.
            const bool capabilitiesSupported = deviceSupportsCapabilities && (!incomingInterfaces.isEmpty() || !outgoingInterfaces.isEmpty());
            if (capabilitiesSupported
                && (m_incomingCapabilities & outgoingInterfaces).isEmpty()
                && (m_outgoingCapabilities & incomingInterfaces).isEmpty()
            ) {
                qCWarning(KDECONNECT_CORE) << "not loading " << pluginName << "because of unmatched capabilities";
                unsupportedPlugins.append(pluginName);
                continue;
            }

            if (pluginEnabled) {
                KdeConnectPlugin* plugin = m_plugins.take(pluginName);

                if (!plugin) {
                    plugin = loader->instantiatePluginForDevice(pluginName, this);
                }

                foreach(const QString& interface, incomingInterfaces) {
                    newPluginsByIncomingInterface.insert(interface, plugin);
                }
                foreach(const QString& interface, outgoingInterfaces) {
                    newPluginsByOutgoingInterface.insert(interface, plugin);
                }

                newPluginMap[pluginName] = plugin;
            }
Ejemplo n.º 4
0
void Device::reloadPlugins()
{
    QHash<QString, KdeConnectPlugin*> newPluginMap;
    QMultiMap<QString, KdeConnectPlugin*> newPluginsByIncomingInterface;
    QMultiMap<QString, KdeConnectPlugin*> newPluginsByOutgoingInterface;

    if (isPaired() && isReachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices

        KConfigGroup pluginStates = KSharedConfig::openConfig(pluginsConfigFile())->group("Plugins");

        PluginLoader* loader = PluginLoader::instance();

        //Code borrowed from KWin
        foreach (const QString& pluginName, loader->getPluginList()) {
            QString enabledKey = pluginName + QString::fromLatin1("Enabled");

            bool isPluginEnabled = (pluginStates.hasKey(enabledKey) ? pluginStates.readEntry(enabledKey, false)
                                                            : loader->getPluginInfo(pluginName).isEnabledByDefault());

            if (isPluginEnabled) {
                KdeConnectPlugin* plugin = m_plugins.take(pluginName);
                QStringList incomingInterfaces, outgoingInterfaces;
                if (plugin) {
                    incomingInterfaces = m_pluginsByIncomingInterface.keys(plugin);
                    outgoingInterfaces = m_pluginsByOutgoingInterface.keys(plugin);
                } else {
                    const KPluginMetaData service = loader->getPluginInfo(pluginName);
                    incomingInterfaces = KPluginMetaData::readStringList(service.rawData(), "X-KdeConnect-SupportedPackageType");
                    outgoingInterfaces = KPluginMetaData::readStringList(service.rawData(), "X-KdeConnect-OutgoingPackageType");
                }

                //If we don't find intersection with the received on one end and the sent on the other, we don't
                //let the plugin stay
                //Also, if no capabilities are specified on the other end, we don't apply this optimizaton, as
                //we assume that the other client doesn't know about capabilities.
                if (!m_incomingCapabilities.isEmpty() && !m_outgoingCapabilities.isEmpty()
                    && (m_incomingCapabilities & outgoingInterfaces.toSet()).isEmpty()
                    && (m_outgoingCapabilities & incomingInterfaces.toSet()).isEmpty()
                ) {
                    delete plugin;
                    continue;
                }

                if (!plugin) {
                    plugin = loader->instantiatePluginForDevice(pluginName, this);
                }

                foreach(const QString& interface, incomingInterfaces) {
                    newPluginsByIncomingInterface.insert(interface, plugin);
                }
                foreach(const QString& interface, outgoingInterfaces) {
                    newPluginsByOutgoingInterface.insert(interface, plugin);
                }
                newPluginMap[pluginName] = plugin;
            }
Ejemplo n.º 5
0
void FrameBufferManager::loadPlugins()
{
    //qDebug();

    const QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(QStringLiteral("krfb"), [](const KPluginMetaData & md) {
            return md.serviceTypes().contains(QStringLiteral("krfb/framebuffer"));
        });

    QVectorIterator<KPluginMetaData> i(plugins);
    i.toBack();
    QSet<QString> unique;
    while (i.hasPrevious()) {
	KPluginMetaData data = i.previous();
        // only load plugins once, even if found multiple times!
        if (unique.contains(data.name()))
            continue;
	KPluginFactory *factory = KPluginLoader(data.fileName()).factory();
	
	if (!factory) {
		qDebug() << "KPluginFactory could not load the plugin:" << data.fileName();
	} else {
		qDebug() << "found plugin at " << data.fileName();
	}
	
	FrameBufferPlugin *plugin = factory->create<FrameBufferPlugin>(this);
	if (plugin) {
		m_plugins.insert(data.pluginId(), plugin);
		qDebug() << "Loaded plugin with name " << data.pluginId();
	} else {
		qDebug() << "unable to load pluign for " << data.fileName();
	}
        unique.insert (data.name());
    }
}
Ejemplo n.º 6
0
bool PluginEffectLoader::loadEffect(const KPluginMetaData &info, LoadEffectFlags flags)
{
    if (!info.isValid()) {
        qCDebug(KWIN_CORE) << "Plugin info is not valid";
        return false;
    }
    const QString name = info.pluginId();
    if (!flags.testFlag(LoadEffectFlag::Load)) {
        qCDebug(KWIN_CORE) << "Loading flags disable effect: " << name;
        return false;
    }
    if (m_loadedEffects.contains(name)) {
        qCDebug(KWIN_CORE) << name << " already loaded";
        return false;
    }
    EffectPluginFactory *effectFactory = factory(info);
    if (!effectFactory) {
        qCDebug(KWIN_CORE) << "Couldn't get an EffectPluginFactory for: " << name;
        return false;
    }

#ifndef KWIN_UNIT_TEST
    effects->makeOpenGLContextCurrent();
#endif
    if (!effectFactory->isSupported()) {
        qCDebug(KWIN_CORE) << "Effect is not supported: " << name;
        return false;
    }

    if (flags.testFlag(LoadEffectFlag::CheckDefaultFunction)) {
        if (!effectFactory->enabledByDefault()) {
            qCDebug(KWIN_CORE) << "Enabled by default function disables effect: " << name;
            return false;
        }
    }

    // ok, now we can try to create the Effect
    Effect *e = effectFactory->createEffect();
    if (!e) {
        qCDebug(KWIN_CORE) << "Failed to create effect: " << name;
        return false;
    }
    // insert in our loaded effects
    m_loadedEffects << name;
    connect(e, &Effect::destroyed, this,
        [this, name]() {
            m_loadedEffects.removeAll(name);
        }
    );
    qCDebug(KWIN_CORE) << "Successfully loaded plugin effect: " << name;
    emit effectLoaded(e, name);
    return true;
}
Ejemplo n.º 7
0
bool ScriptedEffectLoader::loadEffect(const KPluginMetaData &effect, LoadEffectFlags flags)
{
    const QString name = effect.pluginId();
    if (!flags.testFlag(LoadEffectFlag::Load)) {
        qCDebug(KWIN_CORE) << "Loading flags disable effect: " << name;
        return false;
    }
    if (m_loadedEffects.contains(name)) {
        qCDebug(KWIN_CORE) << name << "already loaded";
        return false;
    }

    if (!ScriptedEffect::supported()) {
        qCDebug(KWIN_CORE) << "Effect is not supported: " << name;
        return false;
    }

    ScriptedEffect *e = ScriptedEffect::create(effect);
    if (!e) {
        qCDebug(KWIN_CORE) << "Could not initialize scripted effect: " << name;
        return false;
    }
    connect(e, &ScriptedEffect::destroyed, this,
        [this, name]() {
            m_loadedEffects.removeAll(name);
        }
    );

    qCDebug(KWIN_CORE) << "Successfully loaded scripted effect: " << name;
    emit effectLoaded(e, name);
    m_loadedEffects << name;
    return true;
}
QString ViewerPluginInfo::saveName() const
{
    return QFileInfo(metaData.fileName()).baseName();
}
QString PluginEditorCheckBeforeSendInfo::saveName() const
{
    return QFileInfo(metaData.fileName()).baseName();
}
Ejemplo n.º 10
0
bool PackageJobThread::installPackage(const QString &src, const QString &dest, OperationType operation)
{
    QDir root(dest);
    if (!root.exists()) {
        QDir().mkpath(dest);
        if (!root.exists()) {
            d->errorMessage = i18n("Could not create package root directory: %1", dest);
            d->errorCode = Package::JobError::RootCreationError;
            //qWarning() << "Could not create package root directory: " << dest;
            return false;
        }
    }

    QFileInfo fileInfo(src);
    if (!fileInfo.exists()) {
        d->errorMessage = i18n("No such file: %1", src);
        d->errorCode = Package::JobError::PackageFileNotFoundError;
        return false;
    }

    QString path;
    QTemporaryDir tempdir;
    bool archivedPackage = false;

    if (fileInfo.isDir()) {
        // we have a directory, so let's just install what is in there
        path = src;
        // make sure we end in a slash!
        if (!path.endsWith('/')) {
            path.append('/');
        }
    } else {
        KArchive *archive = 0;
        QMimeDatabase db;
        QMimeType mimetype = db.mimeTypeForFile(src);
        if (mimetype.inherits(QStringLiteral("application/zip"))) {
            archive = new KZip(src);
        } else if (mimetype.inherits(QStringLiteral("application/x-compressed-tar")) ||
                   mimetype.inherits(QStringLiteral("application/x-tar")) ||
                   mimetype.inherits(QStringLiteral("application/x-bzip-compressed-tar")) ||
                   mimetype.inherits(QStringLiteral("application/x-xz")) ||
                   mimetype.inherits(QStringLiteral("application/x-lzma"))) {
            archive = new KTar(src);
        } else {
            //qWarning() << "Could not open package file, unsupported archive format:" << src << mimetype.name();
            d->errorMessage = i18n("Could not open package file, unsupported archive format: %1 %2", src, mimetype.name());
            d->errorCode = Package::JobError::UnsupportedArchiveFormatError;
            return false;
        }

        if (!archive->open(QIODevice::ReadOnly)) {
            //qWarning() << "Could not open package file:" << src;
            delete archive;
            d->errorMessage = i18n("Could not open package file: %1", src);
            d->errorCode = Package::JobError::PackageOpenError;
            return false;
        }

        archivedPackage = true;
        path = tempdir.path() + '/';

        d->installPath = path;

        const KArchiveDirectory *source = archive->directory();
        source->copyTo(path);

        QStringList entries = source->entries();
        if (entries.count() == 1) {
            const KArchiveEntry *entry = source->entry(entries[0]);
            if (entry->isDirectory()) {
                path.append(entry->name()).append("/");
            }
        }

        delete archive;
    }

    QDir packageDir(path);
    QFileInfoList entries = packageDir.entryInfoList(*metaDataFiles);
    KPluginMetaData meta;
    if (!entries.isEmpty()) {
        const QString metadataFilePath = entries.first().filePath();
        if (metadataFilePath.endsWith(QLatin1String(".desktop")))
            meta = KPluginMetaData(metadataFilePath);
        else {
            QFile f(metadataFilePath);
            if(!f.open(QIODevice::ReadOnly)){
                qWarning() << "Couldn't open metadata file" << src << path;
                d->errorMessage = i18n("Could not open metadata file: %1", src);
                d->errorCode = Package::JobError::MetadataFileMissingError;
                return false;
            }
            QJsonObject metadataObject = QJsonDocument::fromJson(f.readAll()).object();
            meta = KPluginMetaData(metadataObject, QString(), metadataFilePath);
        }
    }

    if (!meta.isValid()) {
        qDebug() << "No metadata file in package" << src << path;
        d->errorMessage = i18n("No metadata file in package: %1", src);
        d->errorCode = Package::JobError::MetadataFileMissingError;
        return false;
    }


    QString pluginName = meta.pluginId();
    qDebug() << "pluginname: " << meta.pluginId();
    if (pluginName.isEmpty()) {
        //qWarning() << "Package plugin name not specified";
        d->errorMessage = i18n("Package plugin name not specified: %1", src);
        d->errorCode = Package::JobError::PluginNameMissingError;
        return false;
    }

    // Ensure that package names are safe so package uninstall can't inject
    // bad characters into the paths used for removal.
    QRegExp validatePluginName("^[\\w-\\.]+$"); // Only allow letters, numbers, underscore and period.
    if (!validatePluginName.exactMatch(pluginName)) {
        //qDebug() << "Package plugin name " << pluginName << "contains invalid characters";
        d->errorMessage = i18n("Package plugin name %1 contains invalid characters", pluginName);
        d->errorCode = Package::JobError::PluginNameInvalidError;
        return false;
    }

    QString targetName = dest;
    if (targetName[targetName.size() - 1] != '/') {
        targetName.append('/');
    }
    targetName.append(pluginName);

    if (QFile::exists(targetName)) {
        if (operation == Update) {
            KPluginMetaData oldMeta(targetName + QLatin1String("/metadata.desktop"));

            if (oldMeta.serviceTypes() != meta.serviceTypes()) {
                d->errorMessage = i18n("The new package has a different type from the old version already installed.", meta.version(), meta.pluginId(), oldMeta.version());
                d->errorCode = Package::JobError::UpdatePackageTypeMismatchError;
            } else if (isVersionNewer(oldMeta.version(), meta.version())) {
                const bool ok = uninstallPackage(targetName);
                if (!ok) {
                    d->errorMessage = i18n("Impossible to remove the old installation of %1 located at %2. error: %3", pluginName, targetName, d->errorMessage);
                    d->errorCode = Package::JobError::OldVersionRemovalError;
                }
            } else {
                d->errorMessage = i18n("Not installing version %1 of %2. Version %3 already installed.", meta.version(), meta.pluginId(), oldMeta.version());
                d->errorCode = Package::JobError::NewerVersionAlreadyInstalledError;
            }
        } else {
            d->errorMessage = i18n("%1 already exists", targetName);
            d->errorCode = Package::JobError::PackageAlreadyInstalledError;
        }

        if (d->errorCode != KJob::NoError) {
            d->installPath = targetName;
            return false;
        }
    }

    //install dependencies
    const QStringList dependencies = KPluginMetaData::readStringList(meta.rawData(), QStringLiteral("X-KPackage-Dependencies"));
    for(const QString &dep : dependencies) {
        QUrl depUrl(dep);
        if (!installDependency(depUrl)) {
            d->errorMessage = i18n("Could not install dependency: %1", dep);
            d->errorCode = Package::JobError::PackageCopyError;
            return false;
        }
    }

    if (archivedPackage) {
        // it's in a temp dir, so just move it over.
        const bool ok = copyFolder(path, targetName);
        removeFolder(path);
        if (!ok) {
            //qWarning() << "Could not move package to destination:" << targetName;
            d->errorMessage = i18n("Could not move package to destination: %1", targetName);
            d->errorCode = Package::JobError::PackageMoveError;
            return false;
        }
    } else {
        // it's a directory containing the stuff, so copy the contents rather
        // than move them
        const bool ok = copyFolder(path, targetName);
        if (!ok) {
            //qWarning() << "Could not copy package to destination:" << targetName;
            d->errorMessage = i18n("Could not copy package to destination: %1", targetName);
            d->errorCode = Package::JobError::PackageCopyError;
            return false;
        }
    }

    if (archivedPackage) {
        // no need to remove the temp dir (which has been successfully moved if it's an archive)
        tempdir.setAutoRemove(false);
    }


    indexDirectory(dest, QStringLiteral("kpluginindex.json"));


    d->installPath = targetName;

    //qWarning() << "Not updating kbuildsycoca4, since that will go away. Do it yourself for now if needed.";
    return true;
}
Ejemplo n.º 11
0
void PanelPlugin::setPluginInfo(KPluginMetaData info)
{
    d->name=info.name();
    d->requiredExtensions=info.value(QLatin1String("RequiredExtensions")).split(QLatin1Char(','));
}