/* DConnectServiceManager.java Copyright (c) 2016 NTT DOCOMO,INC. Released under the MIT license http://opensource.org/licenses/mit-license.php */ package org.deviceconnect.android.service; import android.content.Context; import org.deviceconnect.android.profile.DConnectProfile; import org.deviceconnect.android.profile.spec.DConnectPluginSpec; import org.deviceconnect.android.profile.spec.DConnectProfileSpec; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * Device Connect APIサービス管理インターフェースのデフォルト実装. * @author NTT DOCOMO, INC. */ public class DConnectServiceManager implements DConnectServiceProvider, DConnectService.OnStatusChangeListener { /** * プラグインがサポートするスペックを管理するクラス. */ private DConnectPluginSpec mPluginSpec; /** * コンテキスト. */ private Context mContext; /** * デバイスプラグインが持っているサービスリスト. */ private final Map<String, DConnectService> mDConnectServices = Collections.synchronizedMap(new HashMap<String, DConnectService>()); /** * サービス通知リスナーリスト. */ private final List<DConnectServiceListener> mServiceListeners = Collections.synchronizedList(new ArrayList<DConnectServiceListener>()); /** * コンテキストを設定する. * @param context コンテキスト */ public void setContext(final Context context) { mContext = context; } /** * コンテキストを取得する. * @return コンテキスト */ public Context getContext() { return mContext; } /** * プラグインがサポートするスペックを管理するクラスを設定する. * * @param pluginSpec プラグインがサポートするスペック */ public void setPluginSpec(final DConnectPluginSpec pluginSpec) { if (pluginSpec == null) { throw new NullPointerException("pluginSpec is null."); } mPluginSpec = pluginSpec; } @Override public void addService(final DConnectService service) { service.setOnStatusChangeListener(this); service.setContext(mContext); if (mPluginSpec != null) { for (DConnectProfile profile : service.getProfileList()) { DConnectProfileSpec profileSpec = mPluginSpec.findProfileSpec(profile.getProfileName().toLowerCase()); if (profileSpec != null) { profile.setProfileSpec(profileSpec); } } } for (DConnectProfile profile : service.getProfileList()) { profile.setContext(mContext); } mDConnectServices.put(service.getId(), service); notifyOnServiceAdded(service); } @Override public boolean removeService(final DConnectService service) { return removeService(service.getId()) != null; } @Override public DConnectService removeService(final String serviceId) { if (serviceId == null) { return null; } DConnectService removed = mDConnectServices.remove(serviceId); if (removed != null) { notifyOnServiceRemoved(removed); } return removed; } @Override public DConnectService getService(final String serviceId) { if (serviceId == null) { return null; } return mDConnectServices.get(serviceId); } @Override public List<DConnectService> getServiceList() { List<DConnectService> list = new ArrayList<DConnectService>(); list.addAll(mDConnectServices.values()); return list; } @Override public void removeAllServices() { mDConnectServices.clear(); } @Override public boolean hasService(final String serviceId) { return getService(serviceId) != null; } @Override public void addServiceListener(final DConnectServiceListener listener) { synchronized (mServiceListeners) { if (!mServiceListeners.contains(listener)) { mServiceListeners.add(listener); } } } @Override public void removeServiceListener(final DConnectServiceListener listener) { synchronized (mServiceListeners) { for (Iterator<DConnectServiceListener> it = mServiceListeners.iterator(); ; it.hasNext()) { if (it.next() == listener) { it.remove(); break; } } } } /** * サービスが追加されたことをリスナーに通知する. * * @param service 追加されたサービス */ private void notifyOnServiceAdded(final DConnectService service) { synchronized (mServiceListeners) { for (DConnectServiceListener l : mServiceListeners) { l.onServiceAdded(service); } } } /** * サービスが削除されたことをリスナーに通知する. * * @param service 削除されたサービス */ private void notifyOnServiceRemoved(final DConnectService service) { synchronized (mServiceListeners) { for (DConnectServiceListener l : mServiceListeners) { l.onServiceRemoved(service); } } } /** * サービスのステータスが変更されたことをリスナーに通知する. * * @param service ステータスが変更されたサービス */ private void notifyOnStatusChange(final DConnectService service) { synchronized (mServiceListeners) { for (DConnectServiceListener l : mServiceListeners) { l.onStatusChange(service); } } } @Override public void onStatusChange(final DConnectService service) { notifyOnStatusChange(service); } }