2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-09-08 10:05:12 +00:00
Files
kdeconnect-android/src/org/kde/kdeconnect/Plugins/PluginFactory.java

235 lines
9.3 KiB
Java
Raw Normal View History

2014-11-16 23:14:06 -08:00
/*
* Copyright 2014 Albert Vaca Cintora <albertvaka@gmail.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) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.Plugins;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Log;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.Plugins.BatteryPlugin.BatteryPlugin;
2016-06-09 13:42:15 +02:00
import org.kde.kdeconnect.Plugins.ClibpoardPlugin.ClipboardPlugin;
Add contacts-reading plugin (Android side) Summary: Add a plugin to the KDE Connect Android application which supports reading the Android contacts databases and sending the requested data as vcards - Android automatically has support for exporting vcards with all the fields you would expect (phone, email, photo, etc.) - I add two custom fields, one for the modification timestamp and another for the NAME_RAW_CONTACT_ID so that the contacts can be correlated back to the Android database This does not (yet) support writing contacts back to the phone nor does it automatically listen to the phone's contacts database to change BUG: 367999 Test Plan: Connect the device to the desktop and verify that vcards are created in QStandardPaths::GenericDataLocation / kpeoplevcard". On my system this is ~/.local/share/kpeoplevcard Create a dummy contact on the device and verify it is synchronized (Currently not automatic, have to disconnect and reconnect or use dbus) Modify the dummy contact and verify the modifications are synchronized (Currently not automatic, have to disconnect and reconnect or use dbus) Delete the dummy contact and verify the deletion is synchronized (Currently not automatic, have to disconnect and reconnect or use dbus) Reviewers: #kde_connect, mtijink, nicolasfella Reviewed By: #kde_connect, nicolasfella Subscribers: MatMaul, philipc, kdeconnect, nicolasfella, andyholmes, mtijink Tags: #kde_connect Maniphest Tasks: T8283 Differential Revision: https://phabricator.kde.org/D9690
2018-05-30 18:33:23 -06:00
import org.kde.kdeconnect.Plugins.ContactsPlugin.ContactsPlugin;
import org.kde.kdeconnect.Plugins.FindMyPhonePlugin.FindMyPhonePlugin;
import org.kde.kdeconnect.Plugins.FindRemoteDevicePlugin.FindRemoteDevicePlugin;
import org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadPlugin;
import org.kde.kdeconnect.Plugins.MprisPlugin.MprisPlugin;
import org.kde.kdeconnect.Plugins.MprisReceiverPlugin.MprisReceiverPlugin;
import org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationsPlugin;
import org.kde.kdeconnect.Plugins.PingPlugin.PingPlugin;
import org.kde.kdeconnect.Plugins.PresenterPlugin.PresenterPlugin;
import org.kde.kdeconnect.Plugins.ReceiveNotificationsPlugin.ReceiveNotificationsPlugin;
import org.kde.kdeconnect.Plugins.RemoteKeyboardPlugin.RemoteKeyboardPlugin;
2016-06-09 13:42:15 +02:00
import org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandPlugin;
import org.kde.kdeconnect.Plugins.SftpPlugin.SftpPlugin;
import org.kde.kdeconnect.Plugins.SharePlugin.SharePlugin;
import org.kde.kdeconnect.Plugins.SystemvolumePlugin.SystemvolumePlugin;
2016-08-26 19:08:03 +02:00
import org.kde.kdeconnect.Plugins.TelepathyPlugin.TelepathyPlugin;
import org.kde.kdeconnect.Plugins.TelephonyPlugin.TelephonyPlugin;
2015-09-08 14:54:04 -07:00
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class PluginFactory {
public static class PluginInfo {
public PluginInfo(String displayName, String description, Drawable icon,
2015-09-08 14:54:04 -07:00
boolean enabledByDefault, boolean hasSettings, boolean listenToUnpaired,
String[] supportedPacketTypes, String[] outgoingPacketTypes) {
this.displayName = displayName;
this.description = description;
this.icon = icon;
this.enabledByDefault = enabledByDefault;
this.hasSettings = hasSettings;
this.listenToUnpaired = listenToUnpaired;
2015-09-08 14:54:04 -07:00
HashSet<String> incoming = new HashSet<>();
if (supportedPacketTypes != null) Collections.addAll(incoming, supportedPacketTypes);
this.supportedPacketTypes = Collections.unmodifiableSet(incoming);
2015-09-08 14:54:04 -07:00
HashSet<String> outgoing = new HashSet<>();
if (outgoingPacketTypes != null) Collections.addAll(outgoing, outgoingPacketTypes);
this.outgoingPacketTypes = Collections.unmodifiableSet(outgoing);
}
public String getDisplayName() {
return displayName;
}
public String getDescription() {
return description;
}
public Drawable getIcon() {
return icon;
}
public boolean hasSettings() {
return hasSettings;
}
public boolean isEnabledByDefault() {
return enabledByDefault;
}
public boolean listenToUnpaired() {
return listenToUnpaired;
}
public Set<String> getOutgoingPacketTypes() {
return outgoingPacketTypes;
2015-09-08 14:54:04 -07:00
}
public Set<String> getSupportedPacketTypes() {
return supportedPacketTypes;
2015-09-08 14:54:04 -07:00
}
private final String displayName;
private final String description;
private final Drawable icon;
private final boolean enabledByDefault;
private final boolean hasSettings;
private final boolean listenToUnpaired;
private final Set<String> supportedPacketTypes;
private final Set<String> outgoingPacketTypes;
2015-09-08 14:54:04 -07:00
}
private static final Map<String, Class> availablePlugins = new TreeMap<>();
private static final Map<String, PluginInfo> pluginInfoCache = new TreeMap<>();
static {
PluginFactory.registerPlugin(TelephonyPlugin.class);
PluginFactory.registerPlugin(PingPlugin.class);
PluginFactory.registerPlugin(MprisPlugin.class);
PluginFactory.registerPlugin(ClipboardPlugin.class);
PluginFactory.registerPlugin(BatteryPlugin.class);
PluginFactory.registerPlugin(SftpPlugin.class);
PluginFactory.registerPlugin(NotificationsPlugin.class);
PluginFactory.registerPlugin(ReceiveNotificationsPlugin.class);
PluginFactory.registerPlugin(MousePadPlugin.class);
PluginFactory.registerPlugin(PresenterPlugin.class);
PluginFactory.registerPlugin(SharePlugin.class);
2016-08-26 19:08:03 +02:00
PluginFactory.registerPlugin(TelepathyPlugin.class);
PluginFactory.registerPlugin(FindMyPhonePlugin.class);
PluginFactory.registerPlugin(RunCommandPlugin.class);
Add contacts-reading plugin (Android side) Summary: Add a plugin to the KDE Connect Android application which supports reading the Android contacts databases and sending the requested data as vcards - Android automatically has support for exporting vcards with all the fields you would expect (phone, email, photo, etc.) - I add two custom fields, one for the modification timestamp and another for the NAME_RAW_CONTACT_ID so that the contacts can be correlated back to the Android database This does not (yet) support writing contacts back to the phone nor does it automatically listen to the phone's contacts database to change BUG: 367999 Test Plan: Connect the device to the desktop and verify that vcards are created in QStandardPaths::GenericDataLocation / kpeoplevcard". On my system this is ~/.local/share/kpeoplevcard Create a dummy contact on the device and verify it is synchronized (Currently not automatic, have to disconnect and reconnect or use dbus) Modify the dummy contact and verify the modifications are synchronized (Currently not automatic, have to disconnect and reconnect or use dbus) Delete the dummy contact and verify the deletion is synchronized (Currently not automatic, have to disconnect and reconnect or use dbus) Reviewers: #kde_connect, mtijink, nicolasfella Reviewed By: #kde_connect, nicolasfella Subscribers: MatMaul, philipc, kdeconnect, nicolasfella, andyholmes, mtijink Tags: #kde_connect Maniphest Tasks: T8283 Differential Revision: https://phabricator.kde.org/D9690
2018-05-30 18:33:23 -06:00
PluginFactory.registerPlugin(ContactsPlugin.class);
PluginFactory.registerPlugin(RemoteKeyboardPlugin.class);
PluginFactory.registerPlugin(SystemvolumePlugin.class);
//PluginFactory.registerPlugin(MprisReceiverPlugin.class);
PluginFactory.registerPlugin(FindRemoteDevicePlugin.class);
}
public static PluginInfo getPluginInfo(Context context, String pluginKey) {
2015-09-08 14:54:04 -07:00
PluginInfo info = pluginInfoCache.get(pluginKey); //Is it cached?
2015-09-08 14:54:04 -07:00
if (info != null) {
return info;
}
try {
Plugin p = ((Plugin) availablePlugins.get(pluginKey).newInstance());
p.setContext(context, null);
info = new PluginInfo(p.getDisplayName(), p.getDescription(), p.getIcon(),
2015-09-08 14:54:04 -07:00
p.isEnabledByDefault(), p.hasSettings(), p.listensToUnpairedDevices(),
p.getSupportedPacketTypes(), p.getOutgoingPacketTypes());
pluginInfoCache.put(pluginKey, info); //Cache it
return info;
} catch (Exception e) {
Log.e("PluginFactory", "getPluginInfo exception");
2015-01-22 21:30:32 -08:00
e.printStackTrace();
throw new RuntimeException(e);
}
2015-09-08 14:54:04 -07:00
}
public static Set<String> getAvailablePlugins() {
return availablePlugins.keySet();
}
public static Plugin instantiatePluginForDevice(Context context, String pluginKey, Device device) {
Class c = availablePlugins.get(pluginKey);
if (c == null) {
Log.e("PluginFactory", "Plugin not found: " + pluginKey);
return null;
}
try {
Plugin plugin = (Plugin) c.newInstance();
plugin.setContext(context, device);
return plugin;
} catch (Exception e) {
Log.e("PluginFactory", "Could not instantiate plugin: " + pluginKey);
2015-01-22 21:30:32 -08:00
e.printStackTrace();
return null;
}
}
public static void registerPlugin(Class<? extends Plugin> pluginClass) {
try {
String pluginKey = Plugin.getPluginKey(pluginClass);
availablePlugins.put(pluginKey, pluginClass);
} catch (Exception e) {
Log.e("PluginFactory", "addPlugin exception");
e.printStackTrace();
}
}
public static Set<String> getIncomingCapabilities(Context context) {
HashSet<String> capabilities = new HashSet<>();
for (String pluginId : availablePlugins.keySet()) {
PluginInfo plugin = getPluginInfo(context, pluginId);
capabilities.addAll(plugin.getSupportedPacketTypes());
}
return capabilities;
}
public static Set<String> getOutgoingCapabilities(Context context) {
HashSet<String> capabilities = new HashSet<>();
for (String pluginId : availablePlugins.keySet()) {
PluginInfo plugin = getPluginInfo(context, pluginId);
capabilities.addAll(plugin.getOutgoingPacketTypes());
}
return capabilities;
}
public static Set<String> pluginsForCapabilities(Context context, Set<String> incoming, Set<String> outgoing) {
HashSet<String> plugins = new HashSet<>();
for (String pluginId : availablePlugins.keySet()) {
PluginInfo plugin = getPluginInfo(context, pluginId);
//Check incoming against outgoing
if (Collections.disjoint(outgoing, plugin.getSupportedPacketTypes())
&& Collections.disjoint(incoming, plugin.getOutgoingPacketTypes())) {
Log.i("PluginFactory", "Won't load " + pluginId + " because of unmatched capabilities");
continue; //No capabilities in common, do not load this plugin
}
plugins.add(pluginId);
}
return plugins;
}
}