/*
SpheroProfile.java
Copyright (c) 2014 NTT DOCOMO,INC.
Released under the MIT license
http://opensource.org/licenses/mit-license.php
*/
package org.deviceconnect.android.deviceplugin.sphero.profile;
import android.content.Intent;
import android.os.Bundle;
import com.orbotix.async.CollisionDetectedAsyncData;
import com.orbotix.async.DeviceSensorAsyncMessage;
import org.deviceconnect.android.deviceplugin.sphero.SpheroDeviceService;
import org.deviceconnect.android.deviceplugin.sphero.SpheroManager;
import org.deviceconnect.android.deviceplugin.sphero.data.DeviceInfo;
import org.deviceconnect.android.deviceplugin.sphero.data.DeviceInfo.DeviceCollisionListener;
import org.deviceconnect.android.deviceplugin.sphero.data.DeviceInfo.DeviceSensorListener;
import org.deviceconnect.android.event.Event;
import org.deviceconnect.android.event.EventError;
import org.deviceconnect.android.event.EventManager;
import org.deviceconnect.android.message.MessageUtils;
import org.deviceconnect.android.profile.DConnectProfile;
import org.deviceconnect.android.profile.api.DConnectApi;
import org.deviceconnect.android.profile.api.DeleteApi;
import org.deviceconnect.android.profile.api.GetApi;
import org.deviceconnect.android.profile.api.PutApi;
import org.deviceconnect.message.DConnectMessage;
import java.util.List;
/**
* spheroプロファイル.
* @author NTT DOCOMO, INC.
*/
public class SpheroProfile extends DConnectProfile {
/**
* プロファイル名.
*/
public static final String PROFILE_NAME = "sphero";
/**
* インターフェース : {@value} .
*/
public static final String INTER_QUATERNION = "quaternion";
/**
* インターフェース : {@value} .
*/
public static final String INTER_LOCATOR = "locator";
/**
* インターフェース : {@value} .
*/
public static final String INTER_COLLISION = "collision";
/**
* 属性 : {@value} .
*/
public static final String ATTR_ON_QUATERNION = "onQuaternion";
/**
* 属性 : {@value} .
*/
public static final String ATTR_ON_LOCATOR = "onLocator";
/**
* 属性 : {@value} .
*/
public static final String ATTR_ON_COLLISION = "onCollision";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_Q0 = "q0";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_Q1 = "q1";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_Q2 = "q2";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_Q3 = "q3";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_QUATERNION = "quaternion";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_INTERVAL = "interval";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_LOCATOR = "locator";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_POSITION_X = "positionX";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_POSITION_Y = "positionY";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_VELOCITY_X = "velocityX";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_VELOCITY_Y = "velocityY";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_COLLISION = "collision";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_IMPACT_ACCELERATION = "impactAcceleration";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_IMPACT_AXIS = "impactAxis";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_IMPACT_POWER = "impactPower";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_IMPACT_SPEED = "impactSpeed";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_IMPACT_TIMESTAMP = "impactTimestamp";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_X = "x";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_Y = "y";
/**
* パラメータ : {@value} .
*/
public static final String PARAM_Z = "z";
/**
* リクエストタイプ QUATERNION.
*/
private static final int TYPE_QUA = 1;
/**
* リクエストタイプ LOCATOR.
*/
private static final int TYPE_LOC = 2;
/**
* リクエストタイプ COLLISTION.
*/
private static final int TYPE_COL = 3;
/**
* コンストラクタ.
*/
public SpheroProfile() {
addApi(mGetOnQuaternionApi);
addApi(mGetOnCollisionApi);
addApi(mGetOnLocatorApi);
addApi(mPutOnQuaternionApi);
addApi(mPutOnCollisionApi);
addApi(mPutOnLocatorApi);
addApi(mDeleteOnQuaternionApi);
addApi(mDeleteOnCollisionApi);
addApi(mDeleteOnLocatorApi);
}
@Override
public String getProfileName() {
return PROFILE_NAME;
}
/**
* 各イベントの登録を行う.
* @param request リクエストパラメータ
* @param response レスポンスパラメータ
* @return 同期・非同期
*/
private boolean onPutRequest(final Intent request, final Intent response) {
String inter = getInterface(request);
String attribute = getAttribute(request);
int type = 0;
if (INTER_QUATERNION.equals(inter)) {
type = TYPE_QUA;
} else if (INTER_LOCATOR.equals(inter)) {
type = TYPE_LOC;
} else if (INTER_COLLISION.equals(inter)) {
type = TYPE_COL;
} else {
MessageUtils.setNotSupportAttributeError(response);
return true;
}
String serviceId = getServiceID(request);
DeviceInfo device = SpheroManager.INSTANCE.getDevice(serviceId);
if (device == null) {
MessageUtils.setNotFoundServiceError(response);
return true;
}
EventError error = EventManager.INSTANCE.addEvent(request);
boolean registeredEvent = false;
switch (error) {
case NONE:
registeredEvent = true;
setResult(response, DConnectMessage.RESULT_OK);
break;
case INVALID_PARAMETER:
MessageUtils.setInvalidRequestParameterError(response);
break;
default:
MessageUtils.setUnknownError(response);
break;
}
if (registeredEvent) {
switch (type) {
case TYPE_QUA:
case TYPE_LOC:
SpheroManager.INSTANCE.startSensor(device);
break;
case TYPE_COL:
SpheroManager.INSTANCE.startCollision(device);
break;
default:
break;
}
}
return true;
}
/**
* 各イベントの解除を行う.
* @param request リクエストパラメータ
* @param response レスポンスパラメータ
* @return 同期・非同期
*/
private boolean onDeleteRequest(final Intent request, final Intent response) {
String inter = getInterface(request);
String attribute = getAttribute(request);
int type = 0;
if (INTER_QUATERNION.equals(inter)) {
type = TYPE_QUA;
} else if (INTER_LOCATOR.equals(inter)) {
type = TYPE_LOC;
} else if (INTER_COLLISION.equals(inter)) {
type = TYPE_COL;
} else {
MessageUtils.setNotSupportAttributeError(response);
return true;
}
EventError error = EventManager.INSTANCE.removeEvent(request);
boolean removedEvent = false;
switch (error) {
case NONE:
removedEvent = true;
setResult(response, DConnectMessage.RESULT_OK);
break;
case INVALID_PARAMETER:
MessageUtils.setInvalidRequestParameterError(response);
break;
default:
MessageUtils.setUnknownError(response);
break;
}
String serviceId = getServiceID(request);
DeviceInfo device = SpheroManager.INSTANCE.getDevice(serviceId);
if (removedEvent) {
switch (type) {
case TYPE_QUA:
case TYPE_LOC:
if (device != null && !SpheroManager.INSTANCE.hasSensorEvent(device)) {
SpheroManager.INSTANCE.stopSensor(device);
}
break;
case TYPE_COL:
List<Event> events = EventManager.INSTANCE.getEventList(
serviceId, PROFILE_NAME,
INTER_COLLISION, ATTR_ON_COLLISION);
if (device != null && events.size() == 0) {
SpheroManager.INSTANCE.stopCollision(device);
}
break;
default:
break;
}
}
return true;
}
private final DConnectApi mPutOnQuaternionApi = new PutApi() {
@Override
public String getInterface() {
return INTER_QUATERNION;
}
@Override
public String getAttribute() {
return ATTR_ON_QUATERNION;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
return onPutRequest(request, response);
}
};
private final DConnectApi mDeleteOnQuaternionApi = new DeleteApi() {
@Override
public String getInterface() {
return INTER_QUATERNION;
}
@Override
public String getAttribute() {
return ATTR_ON_QUATERNION;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
return onDeleteRequest(request, response);
}
};
private final DConnectApi mPutOnLocatorApi = new PutApi() {
@Override
public String getInterface() {
return INTER_LOCATOR;
}
@Override
public String getAttribute() {
return ATTR_ON_LOCATOR;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
return onPutRequest(request, response);
}
};
private final DConnectApi mDeleteOnLocatorApi = new DeleteApi() {
@Override
public String getInterface() {
return INTER_LOCATOR;
}
@Override
public String getAttribute() {
return ATTR_ON_LOCATOR;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
return onDeleteRequest(request, response);
}
};
private final DConnectApi mPutOnCollisionApi = new PutApi() {
@Override
public String getInterface() {
return INTER_COLLISION;
}
@Override
public String getAttribute() {
return ATTR_ON_COLLISION;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
return onPutRequest(request, response);
}
};
private final DConnectApi mDeleteOnCollisionApi = new DeleteApi() {
@Override
public String getInterface() {
return INTER_COLLISION;
}
@Override
public String getAttribute() {
return ATTR_ON_COLLISION;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
return onDeleteRequest(request, response);
}
};
/**
* Spheroのクォータニオンを取得する.
* @param request リクエスト
* @param response レスポンス
* @param serviceId サービスID
* @return 即座に返却する場合はtrue、それ以外はfalse
*/
private final DConnectApi mGetOnQuaternionApi = new GetApi() {
@Override
public String getInterface() {
return INTER_QUATERNION;
}
@Override
public String getAttribute() {
return ATTR_ON_QUATERNION;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
String serviceId = getServiceID(request);
DeviceInfo device = SpheroManager.INSTANCE.getDevice(serviceId);
if (device == null) {
MessageUtils.setNotFoundServiceError(response);
return true;
}
SpheroManager.INSTANCE.startSensor(device, new DeviceSensorListener() {
@Override
public void sensorUpdated(final DeviceInfo info, final DeviceSensorAsyncMessage data, final long interval) {
SpheroDeviceService service = (SpheroDeviceService) getContext();
Bundle quaternion = SpheroManager.createQuaternion(data, interval);
setResult(response, DConnectMessage.RESULT_OK);
response.putExtra(SpheroProfile.PARAM_QUATERNION, quaternion);
service.sendResponse(response);
}
});
return false;
}
};
/**
* Spheroのlocatorを取得する.
* @param request リクエスト
* @param response レスポンス
* @param serviceId サービスID
* @return 即座に返却する場合はtrue、それ以外はfalse
*/
private final DConnectApi mGetOnLocatorApi = new GetApi() {
@Override
public String getInterface() {
return INTER_LOCATOR;
}
@Override
public String getAttribute() {
return ATTR_ON_LOCATOR;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
String serviceId = getServiceID(request);
DeviceInfo device = SpheroManager.INSTANCE.getDevice(serviceId);
if (device == null) {
MessageUtils.setNotFoundServiceError(response);
return true;
}
SpheroManager.INSTANCE.startSensor(device, new DeviceSensorListener() {
@Override
public void sensorUpdated(final DeviceInfo info, final DeviceSensorAsyncMessage data, final long interval) {
SpheroDeviceService service = (SpheroDeviceService) getContext();
Bundle locator = SpheroManager.createLocator(data);
setResult(response, DConnectMessage.RESULT_OK);
response.putExtra(SpheroProfile.PARAM_LOCATOR, locator);
service.sendResponse(response);
}
});
return false;
}
};
/**
* Spheroの衝突を取得する.
* @param request リクエスト
* @param response レスポンス
* @param serviceId サービスID
* @return 即座に返却する場合はtrue、それ以外はfalse
*/
private final DConnectApi mGetOnCollisionApi = new GetApi() {
@Override
public String getInterface() {
return INTER_COLLISION;
}
@Override
public String getAttribute() {
return ATTR_ON_COLLISION;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
String serviceId = getServiceID(request);
DeviceInfo device = SpheroManager.INSTANCE.getDevice(serviceId);
if (device == null) {
MessageUtils.setNotFoundServiceError(response);
return true;
}
SpheroManager.INSTANCE.startCollision(device, new DeviceCollisionListener() {
@Override
public void collisionDetected(final DeviceInfo info, final CollisionDetectedAsyncData data) {
SpheroDeviceService service = (SpheroDeviceService) getContext();
Bundle collision = SpheroManager.createCollision(data);
setResult(response, DConnectMessage.RESULT_OK);
response.putExtra(SpheroProfile.PARAM_COLLISION, collision);
service.sendResponse(response);
}
});
return false;
}
};
}