/* * Geopaparazzi - Digital field mapping on Android based devices * Copyright (C) 2016 HydroloGIS (www.hydrologis.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 3 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. * * 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 eu.geopaparazzi.library.plugin; import android.app.Service; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.IBinder; import java.util.ArrayList; import java.util.List; import eu.geopaparazzi.library.core.ResourcesManager; import eu.geopaparazzi.library.plugin.types.IMenuEntryList; /** * @author Cesar Martinez Izquierdo (www.scolab.es) */ public abstract class PluginLoader { protected final Context context; protected String serviceName = null; private int numberOfPlugins; protected PluginServiceConnection pluginServiceConn = new PluginServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { super.onServiceConnected(name, service); processService(service); } }; private List<PluginLoaderListener> listeners = new ArrayList<PluginLoaderListener>(); private boolean isLoadComplete = false; protected abstract void doProcessService(IBinder binder); public PluginLoader(Context context, String serviceName) { this.context = context; this.serviceName = serviceName; } public void addListener(PluginLoaderListener listener) { listeners.add(listener); } public void removeListener(PluginLoaderListener listener) { listeners.remove(listener); } public void connect() { PackageManager packageManager = context.getPackageManager(); Intent intent = new Intent(this.serviceName); try { String packageName = ResourcesManager.getInstance(context).getPackageName(); intent.setPackage(packageName); } catch (Exception e) { e.printStackTrace(); } List<ResolveInfo> menuProviders = packageManager.queryIntentServices(intent, PackageManager.GET_RESOLVED_FILTER); numberOfPlugins = menuProviders.size(); for (int i = 0; i < menuProviders.size(); ++i) { ResolveInfo info = menuProviders.get(i); ServiceInfo sinfo = info.serviceInfo; String packageName = sinfo.packageName; String className = sinfo.name; ComponentName component = new ComponentName(packageName, className); Intent explicitIntent = new Intent(intent); explicitIntent.setComponent(component); context.bindService(explicitIntent, pluginServiceConn, Service.BIND_AUTO_CREATE); } } private synchronized void processService(IBinder binder) { doProcessService(binder); numberOfPlugins = numberOfPlugins - 1; if (numberOfPlugins == 0) { // all the plugins have been processed if (pluginServiceConn.isBound()) { context.unbindService(pluginServiceConn); } onLoadComplete(); isLoadComplete = true; for (PluginLoaderListener listener : listeners) { listener.pluginLoaded(this); } } } public void disconnect() { pluginServiceConn.disconnect(context); } public boolean isLoadComplete() { return isLoadComplete; } protected abstract void onLoadComplete(); }