/* LinkingDeviceService.java Copyright (c) 2016 NTT DOCOMO,INC. Released under the MIT license http://opensource.org/licenses/mit-license.php */ package org.deviceconnect.android.deviceplugin.linking; import android.content.Intent; import android.util.Log; import org.deviceconnect.android.deviceplugin.linking.beacon.LinkingBeaconManager; import org.deviceconnect.android.deviceplugin.linking.beacon.LinkingBeaconUtil; import org.deviceconnect.android.deviceplugin.linking.beacon.data.LinkingBeacon; import org.deviceconnect.android.deviceplugin.linking.beacon.profile.BeaconUtil; import org.deviceconnect.android.deviceplugin.linking.beacon.service.LinkingBeaconService; import org.deviceconnect.android.deviceplugin.linking.linking.LinkingDevice; import org.deviceconnect.android.deviceplugin.linking.linking.LinkingDeviceManager; import org.deviceconnect.android.deviceplugin.linking.linking.service.LinkingDeviceService; import org.deviceconnect.android.deviceplugin.linking.profile.LinkingServiceDiscoveryProfile; import org.deviceconnect.android.deviceplugin.linking.profile.LinkingSystemProfile; import org.deviceconnect.android.event.Event; import org.deviceconnect.android.event.EventManager; import org.deviceconnect.android.event.cache.MemoryCacheController; import org.deviceconnect.android.message.DConnectMessageService; import org.deviceconnect.android.profile.DeviceOrientationProfile; import org.deviceconnect.android.profile.KeyEventProfile; import org.deviceconnect.android.profile.ProximityProfile; import org.deviceconnect.android.profile.SystemProfile; import org.deviceconnect.android.service.DConnectService; import java.util.List; /** * Linking device plug-in. * * @author NTT DOCOMO, INC. */ public class LinkingDevicePluginService extends DConnectMessageService { private static final String TAG = "LinkingPlugIn"; @Override public void onCreate() { super.onCreate(); EventManager.INSTANCE.setController(new MemoryCacheController()); addProfile(new LinkingServiceDiscoveryProfile(this, getServiceProvider())); createLinkingDeviceList(); createLinkingBeaconList(); } @Override public int onStartCommand(final Intent intent, final int flags, final int startId) { if (intent != null) { String action = intent.getAction(); if (LinkingBeaconUtil.ACTION_BEACON_SCAN_RESULT.equals(action) || LinkingBeaconUtil.ACTION_BEACON_SCAN_STATE.equals(action)) { LinkingApplication app = (LinkingApplication) getApplication(); LinkingBeaconManager mgr = app.getLinkingBeaconManager(); try { mgr.onReceivedBeacon(intent); } catch (Exception e) { if (BuildConfig.DEBUG) { Log.w(TAG, "", e); } } return START_STICKY; } } return super.onStartCommand(intent, flags, startId); } @Override protected SystemProfile getSystemProfile() { return new LinkingSystemProfile(); } @Override public void onManagerTerminated() { if (BuildConfig.DEBUG) { Log.d(TAG, "onManagerTerminated"); } ((LinkingApplication) getApplication()).resetManager(); removeAllServices(); } @Override public void onManagerEventTransmitDisconnected(final String sessionKey) { if (BuildConfig.DEBUG) { Log.d(TAG, "onManagerEventTransmitDisconnected: " + sessionKey); } cleanupSession(sessionKey); } @Override public void onDevicePluginReset() { if (BuildConfig.DEBUG) { Log.d(TAG, "onDevicePluginReset"); } ((LinkingApplication) getApplication()).resetManager(); resetService(); } @Override public void onManagerUninstalled() { if (BuildConfig.DEBUG) { Log.d(TAG, "onManagerUninstalled"); } ((LinkingApplication) getApplication()).resetManager(); removeAllServices(); } public void cleanupSession(final String sessionKey) { if (sessionKey == null) { if (BuildConfig.DEBUG) { Log.w(TAG, "cleanupSession: sessionKey is null."); } return; } List<Event> events = EventManager.INSTANCE.getEventList(sessionKey); for (Event event : events) { if (BuildConfig.DEBUG) { Log.d(TAG, "event=" + event); } EventManager.INSTANCE.removeEvent(event); stopDeviceOrientation(event); stopProximity(event); stopKeyEvent(event); } stopBeacon(); } public void refreshDevices() { createLinkingDeviceList(); createLinkingBeaconList(); cleanupDConnectService(); } private void createLinkingDeviceList() { for (LinkingDevice device : getLinkingDeviceManager().getDevices()) { DConnectService service = findDConnectService(device.getBdAddress()); if (service == null) { if (BuildConfig.DEBUG) { Log.i(TAG, "Added Device: " + device.getDisplayName()); } getServiceProvider().addService(new LinkingDeviceService(device)); } else { ((LinkingDeviceService) service).setLinkingDevice(device); } } } private void createLinkingBeaconList() { for (LinkingBeacon beacon : getLinkingBeaconManager().getLinkingBeacons()) { DConnectService service = findDConnectService(beacon.getServiceId()); if (service == null) { if (BuildConfig.DEBUG) { Log.i(TAG, "Added Beacon: " + beacon.getDisplayName()); } getServiceProvider().addService(new LinkingBeaconService(this, beacon)); } else { ((LinkingBeaconService) service).setLinkingBeacon(beacon); } } } private void cleanupDConnectService() { for (DConnectService service : getServiceProvider().getServiceList()) { if (!containsLinkingDevices(service.getId()) && !containsLinkingBeacons(service.getId())) { removeService(service); } } } private void removeAllServices() { List<DConnectService> services = getServiceProvider().getServiceList(); for (DConnectService service : services) { removeService(service); } } private void removeService(final DConnectService service) { if (BuildConfig.DEBUG) { Log.i(TAG, "Remove Service: " + service.getName()); } if (service instanceof LinkingDestroy) { ((LinkingDestroy) service).onDestroy(); } getServiceProvider().removeService(service); } private boolean containsLinkingDevices(final String id) { for (LinkingDevice device : getLinkingDeviceManager().getDevices()) { if (device.getBdAddress().equals(id)) { return true; } } return false; } private boolean containsLinkingBeacons(final String id) { for (LinkingBeacon beacon : getLinkingBeaconManager().getLinkingBeacons()) { if (beacon.getServiceId().equals(id)) { return true; } } return false; } private DConnectService findDConnectService(final String id) { for (DConnectService service : getServiceProvider().getServiceList()) { if (service.getId().equals(id)) { return service; } } return null; } private void resetService() { removeAllServices(); createLinkingDeviceList(); createLinkingBeaconList(); } private void stopDeviceOrientation(final Event event) { if (!DeviceOrientationProfile.PROFILE_NAME.equalsIgnoreCase(event.getProfile()) || !DeviceOrientationProfile.ATTRIBUTE_ON_DEVICE_ORIENTATION.equalsIgnoreCase(event.getAttribute())) { return; } if (BuildConfig.DEBUG) { Log.i(TAG, "stopDeviceOrientation"); } LinkingDeviceManager mgr = getLinkingDeviceManager(); String serviceId = event.getServiceId(); List<Event> events = EventManager.INSTANCE.getEventList( serviceId, DeviceOrientationProfile.PROFILE_NAME, null, DeviceOrientationProfile.ATTRIBUTE_ON_DEVICE_ORIENTATION); if (events.isEmpty()) { mgr.disableListenSensor(mgr.findDeviceByBdAddress(serviceId), null); } else { if (BuildConfig.DEBUG) { Log.d(TAG, "events=" + events.size()); } } } private void stopProximity(final Event event) { if (!ProximityProfile.PROFILE_NAME.equalsIgnoreCase(event.getProfile()) || !ProximityProfile.ATTRIBUTE_ON_DEVICE_PROXIMITY.equalsIgnoreCase(event.getAttribute())) { return; } if (BuildConfig.DEBUG) { Log.i(TAG, "stopProximity"); } LinkingDeviceManager mgr = getLinkingDeviceManager(); String serviceId = event.getServiceId(); List<Event> events = EventManager.INSTANCE.getEventList( serviceId, ProximityProfile.PROFILE_NAME, null, ProximityProfile.ATTRIBUTE_ON_DEVICE_PROXIMITY); if (events.isEmpty()) { mgr.disableListenRange(mgr.findDeviceByBdAddress(serviceId), null); } else { if (BuildConfig.DEBUG) { Log.d(TAG, "events=" + events.size()); } } } private void stopKeyEvent(final Event event) { if (!KeyEventProfile.PROFILE_NAME.equalsIgnoreCase(event.getProfile()) || !KeyEventProfile.ATTRIBUTE_ON_DOWN.equalsIgnoreCase(event.getAttribute())) { return; } if (BuildConfig.DEBUG) { Log.i(TAG, "disableListenButtonEvent"); } LinkingDeviceManager mgr = getLinkingDeviceManager(); String serviceId = event.getServiceId(); List<Event> events = EventManager.INSTANCE.getEventList( serviceId, KeyEventProfile.PROFILE_NAME, null, KeyEventProfile.ATTRIBUTE_ON_DOWN); if (events.isEmpty()) { mgr.disableListenButtonEvent(mgr.findDeviceByBdAddress(serviceId), null); } else { if (BuildConfig.DEBUG) { Log.d(TAG, "events=" + events.size()); } } } private void stopBeacon() { if (BeaconUtil.isEmptyEvent(getLinkingBeaconManager())) { if (BuildConfig.DEBUG) { Log.i(TAG, "stop beacon"); } getLinkingBeaconManager().stopBeaconScan(); } } private LinkingDeviceManager getLinkingDeviceManager() { LinkingApplication app = getLinkingApplication(); return app.getLinkingDeviceManager(); } private LinkingBeaconManager getLinkingBeaconManager() { LinkingApplication app = getLinkingApplication(); return app.getLinkingBeaconManager(); } private LinkingApplication getLinkingApplication() { return (LinkingApplication) getApplication(); } }