/*
HeartRateDeviceService
Copyright (c) 2015 NTT DOCOMO,INC.
Released under the MIT license
http://opensource.org/licenses/mit-license.php
*/
package org.deviceconnect.android.deviceplugin.heartrate;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import org.deviceconnect.android.deviceplugin.heartrate.ble.BleUtils;
import org.deviceconnect.android.deviceplugin.heartrate.data.HeartRateDevice;
import org.deviceconnect.android.deviceplugin.heartrate.profile.HeartRateHealthProfile;
import org.deviceconnect.android.deviceplugin.heartrate.profile.HeartRateServiceDiscoveryProfile;
import org.deviceconnect.android.deviceplugin.heartrate.profile.HeartRateSystemProfile;
import org.deviceconnect.android.deviceplugin.heartrate.service.HeartRateService;
import org.deviceconnect.android.event.EventManager;
import org.deviceconnect.android.logger.AndroidHandler;
import org.deviceconnect.android.message.DConnectMessageService;
import org.deviceconnect.android.profile.DConnectProfile;
import org.deviceconnect.android.profile.SystemProfile;
import org.deviceconnect.android.service.DConnectService;
import org.deviceconnect.android.service.DConnectServiceListener;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
/**
* This service provide Health Profile.
* @author NTT DOCOMO, INC.
*/
public class HeartRateDeviceService extends DConnectMessageService
implements DConnectServiceListener {
/** Logger. */
private final Logger mLogger = Logger.getLogger("heartrate.dplugin");
private DConnectProfile mHeartRateProfile;
/**
* Instance of HeartRateManager.
*/
private HeartRateManager mHeartRateManager;
/**
* Received a event that Bluetooth has been changed.
*/
private final BroadcastReceiver mSensorReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
if (state == BluetoothAdapter.STATE_ON) {
getManager().start();
} else if (state == BluetoothAdapter.STATE_OFF) {
getManager().stop();
}
}
}
};
private final HeartRateManager.OnHeartRateDiscoveryListener mOnDiscoveryListener
= new HeartRateManager.OnHeartRateDiscoveryListener() {
@Override
public void onDiscovery(final List<BluetoothDevice> devices) {
for (BluetoothDevice device : devices) {
retrieveService(device);
}
}
@Override
public void onConnected(final HeartRateDevice device) {
DConnectService service = retrieveService(device);
if (service != null) {
service.setOnline(true);
}
}
@Override
public void onConnectFailed(final BluetoothDevice device) {
// NOP.
}
@Override
public void onDisconnected(final HeartRateDevice device) {
DConnectService service = retrieveService(device);
if (service != null) {
service.setOnline(false);
}
}
};
/**
* Instance of handler.
*/
private final Handler mHandler = new Handler();
@Override
public void onCreate() {
super.onCreate();
Logger logger = Logger.getLogger("heartrate.dplugin");
if (BuildConfig.DEBUG) {
AndroidHandler handler = new AndroidHandler(logger.getName());
handler.setFormatter(new SimpleFormatter());
handler.setLevel(Level.ALL);
logger.addHandler(handler);
logger.setLevel(Level.ALL);
} else {
logger.setLevel(Level.OFF);
}
mLogger.fine("HeartRateDeviceService start.");
if (!BleUtils.isBLESupported(getContext())) {
mLogger.warning("BLE is not support.");
return;
}
mHeartRateManager = new HeartRateManager(getApplicationContext());
mHeartRateManager.addOnHeartRateDiscoveryListener(mOnDiscoveryListener);
addProfile(new HeartRateServiceDiscoveryProfile(getServiceProvider()));
mHeartRateProfile = new HeartRateHealthProfile(mHeartRateManager);
List<HeartRateDevice> devices = mHeartRateManager.getRegisterDevices();
for (HeartRateDevice device : devices) {
retrieveService(device);
}
getServiceProvider().addServiceListener(this);
registerBluetoothFilter();
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterBluetoothFilter();
getServiceProvider().removeServiceListener(this);
mHeartRateManager.removeOnHeartRateDiscoveryListener(mOnDiscoveryListener);
mHeartRateManager.stop();
mLogger.fine("HeartRateDeviceService end.");
}
@Override
public void onServiceAdded(final DConnectService service) {
if (BuildConfig.DEBUG) {
mLogger.info("onServiceAdded: " + service.getName());
}
// NOP.
}
@Override
public void onServiceRemoved(final DConnectService service) {
if (BuildConfig.DEBUG) {
mLogger.info("onServiceRemoved: " + service.getName());
}
getManager().disconnectBleDevice(service.getId());
}
@Override
public void onStatusChange(final DConnectService service) {
if (BuildConfig.DEBUG) {
mLogger.info("onStatusChange: " + service.getName());
}
// NOP.
}
@Override
protected void onManagerUninstalled() {
// Managerアンインストール検知時の処理。
if (BuildConfig.DEBUG) {
mLogger.info("Plug-in : onManagerUninstalled");
}
}
@Override
protected void onManagerTerminated() {
// Manager正常終了通知受信時の処理。
if (BuildConfig.DEBUG) {
mLogger.info("Plug-in : onManagerTerminated");
}
}
@Override
protected void onManagerEventTransmitDisconnected(final String sessionKey) {
// ManagerのEvent送信経路切断通知受信時の処理。
if (BuildConfig.DEBUG) {
mLogger.info("Plug-in : onManagerEventTransmitDisconnected");
}
if (sessionKey != null) {
EventManager.INSTANCE.removeEvents(sessionKey);
} else {
EventManager.INSTANCE.removeAll();
}
}
@Override
protected void onDevicePluginReset() {
// Device Plug-inへのReset要求受信時の処理。
if (BuildConfig.DEBUG) {
mLogger.info("Plug-in : onDevicePluginReset");
}
resetPluginResource();
}
/**
* リソースリセット処理.
*/
private void resetPluginResource() {
// 全イベント削除.
EventManager.INSTANCE.removeAll();
}
@Override
protected SystemProfile getSystemProfile() {
return new HeartRateSystemProfile();
}
/**
* Get a DConnectService from HeartRateDevice.
* @param device HeartRateDevice
* @return DConnectService
*/
private DConnectService retrieveService(final HeartRateDevice device) {
DConnectService service = getServiceProvider().getService(device.getAddress());
if (service == null) {
service = new HeartRateService(device);
service.addProfile(mHeartRateProfile);
getServiceProvider().addService(service);
}
return service;
}
/**
* Get a DConnectService from BluetoothDevice.
* @param device BluetoothDevice
* @return DConnectService
*/
private DConnectService retrieveService(final BluetoothDevice device) {
DConnectService service = getServiceProvider().getService(device.getAddress());
if (service == null) {
service = new HeartRateService(device);
service.addProfile(mHeartRateProfile);
getServiceProvider().addService(service);
}
return service;
}
/**
* Register a BroadcastReceiver of Bluetooth event.
*/
private void registerBluetoothFilter() {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mSensorReceiver, filter, null, mHandler);
}
/**
* Unregister a previously registered BroadcastReceiver.
*/
private void unregisterBluetoothFilter() {
unregisterReceiver(mSensorReceiver);
}
/**
* Gets a instance of HeartRateManager.
*
* @return HeartRateManager
*/
public HeartRateManager getManager() {
return mHeartRateManager;
}
}