package com.o3dr.android.client.apis;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import com.o3dr.android.client.Drone;
import com.o3dr.services.android.lib.model.AbstractCommandListener;
import com.o3dr.services.android.lib.model.action.Action;
import java.util.concurrent.ConcurrentHashMap;
import static com.o3dr.services.android.lib.drone.action.CapabilityActions.*;
/**
* Allows to query the capabilities offered by the vehicle.
* Created by Fredia Huya-Kouadio on 7/5/15.
*/
public class CapabilityApi extends Api {
/**
* Feature support check error. The drone is disconnected.
*/
public static final int FEATURE_ERROR_DRONE_DISCONNECTED = -1;
/**
* Feature support check result. Indicate the feature is supported.
*/
public static final int FEATURE_SUPPORTED = 0;
/**
* Feature support check result. Indicate the feature is not supported.
*/
public static final int FEATURE_UNSUPPORTED = 1;
private static final ConcurrentHashMap<Drone, CapabilityApi> capabilityApiCache = new ConcurrentHashMap<>();
private static final Builder<CapabilityApi> apiBuilder = new Builder<CapabilityApi>() {
@Override
public CapabilityApi build(Drone drone) {
return new CapabilityApi(drone);
}
};
/**
* Retrieves a capability api instance.
* @param drone target vehicle.
* @return a CapabilityApi instance.
*/
public static CapabilityApi getApi(final Drone drone){
return getApi(drone, capabilityApiCache, apiBuilder);
}
private final Drone drone;
private CapabilityApi(Drone drone){
this.drone = drone;
}
/**
* Determine whether the given feature is supported.
* @param featureId Id of the feature to check.
* @param resultListener Callback to receive feature support status.
*/
public void checkFeatureSupport(final String featureId, final FeatureSupportListener resultListener){
if(TextUtils.isEmpty(featureId) || resultListener == null)
return;
if(!drone.isConnected()){
drone.post(new Runnable() {
@Override
public void run() {
resultListener.onFeatureSupportResult(featureId, FEATURE_ERROR_DRONE_DISCONNECTED, null);
}
});
return;
}
switch(featureId){
case FeatureIds.IMU_CALIBRATION:
drone.post(new Runnable() {
@Override
public void run() {
resultListener.onFeatureSupportResult(featureId, FEATURE_SUPPORTED, null);
}
});
break;
case FeatureIds.SOLO_VIDEO_STREAMING:
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
drone.post(new Runnable() {
@Override
public void run() {
resultListener.onFeatureSupportResult(featureId, FEATURE_UNSUPPORTED, null);
}
});
break;
}
//********FALL THROUGH ***********//
case FeatureIds.COMPASS_CALIBRATION:
case FeatureIds.KILL_SWITCH:
final Bundle params = new Bundle();
params.putString(EXTRA_FEATURE_ID, featureId);
drone.performAsyncActionOnDroneThread(new Action(ACTION_CHECK_FEATURE_SUPPORT, params),
new AbstractCommandListener() {
@Override
public void onSuccess() {
resultListener.onFeatureSupportResult(featureId, FEATURE_SUPPORTED, null);
}
@Override
public void onError(int executionError) {
resultListener.onFeatureSupportResult(featureId, FEATURE_UNSUPPORTED, null);
}
@Override
public void onTimeout() {
resultListener.onFeatureSupportResult(featureId, FEATURE_UNSUPPORTED, null);
}
});
break;
default:
drone.post(new Runnable() {
@Override
public void run() {
resultListener.onFeatureSupportResult(featureId, FEATURE_UNSUPPORTED, null);
}
});
break;
}
}
/**
* Defines the set of feature ids.
*/
public static final class FeatureIds {
/**
* Id for the video feature.
*/
public static final String SOLO_VIDEO_STREAMING = "feature_solo_video_streaming";
/**
* Id for the compass calibration feature.
*/
public static final String COMPASS_CALIBRATION = "feature_compass_calibration";
/**
* Id for the imu calibration feature.
*/
public static final String IMU_CALIBRATION = "feature_imu_calibration";
/**
* Id for the kill switch feature.
*/
public static final String KILL_SWITCH = "feature_kill_switch";
//Private to prevent instantiation.
private FeatureIds(){}
}
public interface FeatureSupportListener {
/**
* Callback for the result from checking feature support.
* @param featureId Id of the feature for which we're checking support.
* @param result Result of the feature support check.
* @param resultInfo Additional info about the level of support for the feature. Can be null.
*/
void onFeatureSupportResult(String featureId, int result, Bundle resultInfo);
}
}