Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ClientLib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ext {
VERSION_MAJOR = 3
VERSION_MINOR = 0
VERSION_PATCH = 0
VERSION_SUFFIX = "alpha5"
VERSION_SUFFIX = "alpha6"

PUBLISH_ARTIFACT_ID = 'dronekit-android'
PUBLISH_VERSION = generateVersionName("", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_SUFFIX)
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ DroneManager connectDroneManager(ConnectionParameter connParams, String appId, D
}

Timber.d("Drone manager connection for " + appId);
droneMgr.connect(appId, listener, connParams.getTLogLoggingUri());
droneMgr.connect(appId, listener, connParams);
return droneMgr;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Pair;
Expand Down Expand Up @@ -54,8 +56,11 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentSkipListMap;

import timber.log.Timber;

Expand All @@ -68,7 +73,29 @@ public final class DroneApi extends IDroneApi.Stub implements DroneInterfaces.On
//The Reset ROI mission item was introduced in version 2.6.8. Any client library older than this do not support it.
private final static int RESET_ROI_LIB_VERSION = 206080;

private final Runnable eventsDispatcher = new Runnable() {
@Override
public void run() {
handler.removeCallbacks(this);

//Go through the events buffer and empty it
Set<Map.Entry<EventInfo, Bundle>> eventsToDispatch = eventsBuffer.entrySet();
for(Map.Entry<EventInfo, Bundle> entry: eventsToDispatch){
String event = entry.getKey().event;
Bundle extras = entry.getValue();
eventsToDispatch.remove(entry);
dispatchAttributeEvent(event, extras);
}

if(isEventsBufferingEnabled()) {
handler.postDelayed(this, connectionParams.getEventsDispatchingPeriod());
}
}
};

private final Context context;
private final Handler handler;
private final Bundle emptyBundle = Bundle.EMPTY;

private final ConcurrentLinkedQueue<IObserver> observersList;
private final ConcurrentLinkedQueue<IMavlinkObserver> mavlinkObserversList;
Expand All @@ -80,12 +107,15 @@ public final class DroneApi extends IDroneApi.Stub implements DroneInterfaces.On

private final DroidPlannerService service;

private final Map<EventInfo, Bundle> eventsBuffer = new ConcurrentSkipListMap<>();

private ConnectionParameter connectionParams;

DroneApi(DroidPlannerService dpService, IApiListener listener, String ownerId) {

this.service = dpService;
this.context = dpService.getApplicationContext();
handler = new Handler(Looper.getMainLooper());

this.ownerId = ownerId;

Expand Down Expand Up @@ -139,6 +169,10 @@ private Drone getDrone() {
return this.droneMgr.getDrone();
}

private boolean isEventsBufferingEnabled(){
return connectionParams != null && connectionParams.getEventsDispatchingPeriod() > 0L;
}

@Override
public Bundle getAttribute(String type) throws RemoteException {
Bundle carrier = new Bundle();
Expand Down Expand Up @@ -218,6 +252,10 @@ public void connect(ConnectionParameter connParams) {

this.connectionParams = connParams;
this.droneMgr = service.connectDroneManager(this.connectionParams, ownerId, this);

if(isEventsBufferingEnabled()) {
handler.postDelayed(eventsDispatcher, this.connectionParams.getEventsDispatchingPeriod());
}
}
} catch (ConnectionException e) {
LinkConnectionStatus connectionStatus = LinkConnectionStatus
Expand All @@ -232,6 +270,8 @@ public void disconnect() {
this.connectionParams = null;
this.droneMgr = null;

handler.removeCallbacks(eventsDispatcher);

}

private void checkForSelfRelease() {
Expand Down Expand Up @@ -385,21 +425,36 @@ private void notifyAttributeUpdate(List<Pair<String, Bundle>> attributesInfo) {
}

private void notifyAttributeUpdate(String attributeEvent, Bundle extrasBundle) {
if (observersList.isEmpty()) {
if (observersList.isEmpty() || attributeEvent == null) {
return;
}

if (attributeEvent != null) {
for (IObserver observer : observersList) {
if(AttributeEvent.STATE_CONNECTED.equals(attributeEvent) ||
AttributeEvent.STATE_DISCONNECTED.equals(attributeEvent) ||
!isEventsBufferingEnabled()){
//Dispatch the event immediately
dispatchAttributeEvent(attributeEvent, extrasBundle);
}
else{
if(extrasBundle == null)
extrasBundle = emptyBundle;
eventsBuffer.put(new EventInfo(attributeEvent), extrasBundle);
}
}

private void dispatchAttributeEvent(String attributeEvent, Bundle extrasBundle){
if(extrasBundle == emptyBundle)
extrasBundle = null;

for (IObserver observer : observersList) {
try {
observer.onAttributeUpdated(attributeEvent, extrasBundle);
} catch (RemoteException e) {
Timber.e(e, e.getMessage());
try {
observer.onAttributeUpdated(attributeEvent, extrasBundle);
} catch (RemoteException e) {
Timber.e(e, e.getMessage());
try {
removeAttributesObserver(observer);
} catch (RemoteException e1) {
Timber.e(e, e1.getMessage());
}
removeAttributesObserver(observer);
} catch (RemoteException e1) {
Timber.e(e, e1.getMessage());
}
}
}
Expand Down Expand Up @@ -735,4 +790,42 @@ public ClientInfo(String appId, int apiVersionCode, int clientVersionCode) {
this.clientVersionCode = clientVersionCode;
}
}

private static class EventInfo implements Comparable<EventInfo>{
final String event;
final long eventTimestamp;

EventInfo(String event){
this.event = event;
eventTimestamp = System.currentTimeMillis();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof EventInfo)) {
return false;
}

EventInfo eventInfo = (EventInfo) o;

return event != null ? event.equals(eventInfo.event) : eventInfo.event == null;

}

@Override
public int hashCode() {
return event != null ? event.hashCode() : 0;
}

@Override
public int compareTo(EventInfo another) {
if(this.event.equals(another.event))
return 0;

return this.eventTimestamp > another.eventTimestamp ? 1 : -1;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,53 +1,19 @@
package org.droidplanner.services.android.impl.core.drone;

import android.os.Handler;

import org.droidplanner.services.android.impl.core.drone.DroneInterfaces.DroneEventsType;
import org.droidplanner.services.android.impl.core.drone.DroneInterfaces.OnDroneListener;
import org.droidplanner.services.android.impl.core.drone.autopilot.MavLinkDrone;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;

public class DroneEvents extends DroneVariable<MavLinkDrone> {

private static final long EVENT_DISPATCHING_DELAY = 33l; //milliseconds

private final AtomicBoolean isDispatcherRunning = new AtomicBoolean(false);

private final Runnable eventDispatcher = new Runnable() {

@Override
public void run() {
handler.removeCallbacks(this);

final DroneEventsType event = eventQueue.poll();
if (event == null) {
isDispatcherRunning.set(false);
return;
}

for (OnDroneListener listener : droneListeners) {
listener.onDroneEvent(event, myDrone);
}

handler.removeCallbacks(this);
handler.postDelayed(this, EVENT_DISPATCHING_DELAY);

isDispatcherRunning.set(true);
}
};

private final Handler handler;
private final ConcurrentLinkedQueue<OnDroneListener> droneListeners = new ConcurrentLinkedQueue<OnDroneListener>();

public DroneEvents(MavLinkDrone myDrone, Handler handler) {
public DroneEvents(MavLinkDrone myDrone) {
super(myDrone);
this.handler = handler;
}

private final ConcurrentLinkedQueue<OnDroneListener> droneListeners = new ConcurrentLinkedQueue<OnDroneListener>();
private final ConcurrentLinkedQueue<DroneEventsType> eventQueue = new ConcurrentLinkedQueue<>();

public void addDroneListener(OnDroneListener listener) {
if (listener != null & !droneListeners.contains(listener))
droneListeners.add(listener);
Expand All @@ -63,11 +29,11 @@ public void removeAllDroneListeners(){
}

public void notifyDroneEvent(DroneEventsType event) {
if (event == null || droneListeners.isEmpty() || eventQueue.contains(event))
if (event == null || droneListeners.isEmpty())
return;

eventQueue.add(event);
if (isDispatcherRunning.compareAndSet(false, true))
handler.postDelayed(eventDispatcher, EVENT_DISPATCHING_DELAY);
for (OnDroneListener listener : droneListeners) {
listener.onDroneEvent(event, myDrone);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package org.droidplanner.services.android.impl.core.drone;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;

Expand Down Expand Up @@ -79,16 +77,16 @@ public void destroy() {

}

public synchronized void connect(String appId, DroneApi listener, Uri tlogLoggingUri) {
public synchronized void connect(String appId, DroneApi listener, ConnectionParameter connParams) {
if (listener == null || TextUtils.isEmpty(appId)) {
return;
}

connectedApps.put(appId, listener);
doConnect(appId, listener, tlogLoggingUri);
doConnect(appId, listener, connParams);
}

protected void doConnect(String appId, DroneApi listener, @Nullable Uri tlogLoggingUri) {
protected void doConnect(String appId, DroneApi listener, ConnectionParameter connParams) {

}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
import org.droidplanner.services.android.impl.core.mission.Mission;
import org.droidplanner.services.android.impl.core.model.AutopilotWarningParser;
import org.droidplanner.services.android.impl.utils.CommonApiUtils;
import org.droidplanner.services.android.impl.utils.prefs.DroidPlannerPrefs;
import org.droidplanner.services.android.impl.utils.video.VideoManager;

/**
Expand Down Expand Up @@ -121,7 +120,7 @@ public GenericMavLinkDrone(String droneId, Context context, Handler handler, Dat

this.logListener = logListener;

events = new DroneEvents(this, handler);
events = new DroneEvents(this);
heartbeat = initHeartBeat(handler);
this.type = new Type(this);
this.missionStats = new MissionStats(this);
Expand Down Expand Up @@ -418,11 +417,11 @@ public boolean executeAsyncAction(Action action, ICommandListener listener) {
private boolean updateVehicleDataStreamRate(Bundle data, ICommandListener listener) {
StreamRates streamRates = getStreamRates();
if(streamRates != null){
int rate = data.getInt(StateActions.EXTRA_VEHICLE_DATA_STREAM_RATE, DroidPlannerPrefs.DEFAULT_STREAM_RATE);
StreamRates.Rates rates = new StreamRates.Rates(rate);
streamRates.setRates(rates);

streamRates.setupStreamRatesFromPref();
int rate = data.getInt(StateActions.EXTRA_VEHICLE_DATA_STREAM_RATE, -1);
if(rate != -1) {
StreamRates.Rates rates = new StreamRates.Rates(rate);
streamRates.setRates(rates);
}
CommonApiUtils.postSuccessEvent(listener);
return true;
}
Expand Down
Loading