/*
* Catroid: An on-device visual programming system for Android devices
* Copyright (C) 2010-2016 The Catrobat Team
* (<http://developer.catrobat.org/credits>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* An additional term exception under section 7 of the GNU Affero
* General Public License, version 3, is available at
* http://developer.catrobat.org/license_additional_term
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.catrobat.catroid.drone;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.parrot.freeflight.drone.NavData;
import com.parrot.freeflight.receivers.DroneBatteryChangedReceiver;
import com.parrot.freeflight.receivers.DroneBatteryChangedReceiverDelegate;
import com.parrot.freeflight.receivers.DroneEmergencyChangeReceiver;
import com.parrot.freeflight.receivers.DroneEmergencyChangeReceiverDelegate;
import com.parrot.freeflight.service.DroneControlService;
import org.catrobat.catroid.R;
import org.catrobat.catroid.stage.StageActivity;
import org.catrobat.catroid.utils.ToastUtil;
public class DroneStageActivity extends StageActivity implements DroneBatteryChangedReceiverDelegate, DroneEmergencyChangeReceiverDelegate {
private DroneConnection droneConnection = null;
private DroneBatteryChangedReceiver droneBatteryReceiver;
private DroneEmergencyChangeReceiver droneEmergencyReceiver;
private boolean droneBatteryMessageShown = false;
private enum EmergencyMethod {
NOTHING,
TOAST,
ALERT
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (droneConnection == null && DroneServiceWrapper.checkARDroneAvailability()) {
droneConnection = new DroneConnection(this);
try {
droneConnection.initialise();
droneBatteryReceiver = new DroneBatteryChangedReceiver(this);
droneEmergencyReceiver = new DroneEmergencyChangeReceiver(this);
} catch (RuntimeException runtimeException) {
Log.e(TAG, "Failure during drone service startup", runtimeException);
ToastUtil.showError(this, R.string.error_no_drone_connected);
this.finish();
}
}
}
@Override
public void onPause() {
super.onPause();
DroneControlService droneControlService = DroneServiceWrapper.getInstance().getDroneService();
if (droneControlService != null) {
boolean flyingMode = droneControlService.getDroneNavData().flying;
if (flyingMode) {
droneControlService.triggerTakeOff();
}
}
if (droneControlService != null) {
//wait until drone is landed
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Log.e(getClass().getSimpleName(), "Error in Thread.sleep method!");
}
if (!droneControlService.getDroneNavData().flying) {
break;
}
}
}
if (droneConnection != null) {
droneConnection.pause();
}
unregisterReceivers();
}
@Override
public void onResume() {
super.onResume();
if (droneConnection != null) {
droneConnection.start();
}
registerReceivers();
}
@Override
protected void onDestroy() {
Log.d(getClass().getSimpleName(), "DroneStageActivity: onDestroy() wurde aufgerufen");
if (droneConnection != null) {
droneConnection.destroy();
}
droneBatteryMessageShown = false;
super.onDestroy();
}
private void registerReceivers() {
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this.getApplicationContext());
manager.registerReceiver(droneBatteryReceiver, new IntentFilter(DroneControlService.DRONE_BATTERY_CHANGED_ACTION));
manager.registerReceiver(droneEmergencyReceiver, new IntentFilter(DroneControlService.DRONE_EMERGENCY_STATE_CHANGED_ACTION));
}
private void unregisterReceivers() {
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this.getApplicationContext());
manager.unregisterReceiver(droneBatteryReceiver);
manager.unregisterReceiver(droneEmergencyReceiver);
}
@Override
public void onDroneBatteryChanged(int value) {
Log.d(TAG, "Battery Status = " + Integer.toString(value));
DroneControlService dcs = DroneServiceWrapper.getInstance().getDroneService();
if (dcs != null && (value < DroneInitializer.DRONE_BATTERY_THRESHOLD) && dcs.getDroneNavData().flying && !droneBatteryMessageShown) {
ToastUtil.showError(this, R.string.notification_low_battery + " " + Integer.toString(value));
droneBatteryMessageShown = true;
}
}
@Override
public void onDroneEmergencyChanged(int code) {
EmergencyMethod method = EmergencyMethod.NOTHING;
Log.d(getClass().getSimpleName(), "message code integer value: " + Integer.toString(code));
if (code == NavData.ERROR_STATE_NONE || code == NavData.ERROR_STATE_START_NOT_RECEIVED) {
return;
}
int messageID;
switch (code) {
case NavData.ERROR_STATE_EMERGENCY_VBAT_LOW:
messageID = R.string.drone_emergency_battery_low;
method = EmergencyMethod.ALERT;
Log.d(getClass().getSimpleName(), "message code: " + getResources().getString(R.string.drone_emergency_battery_low));
break;
case NavData.ERROR_STATE_ALERT_VBAT_LOW:
messageID = R.string.drone_alert_battery_low;
method = EmergencyMethod.TOAST;
Log.d(getClass().getSimpleName(), "message code: " + getResources().getString(R.string.drone_alert_battery_low));
break;
case NavData.ERROR_STATE_ALERT_CAMERA:
case NavData.ERROR_STATE_EMERGENCY_CAMERA:
messageID = R.string.drone_emergency_camera;
method = EmergencyMethod.TOAST;
Log.d(getClass().getSimpleName(), "message code: " + getResources().getString(R.string.drone_emergency_camera));
break;
case NavData.ERROR_STATE_EMERGENCY_ULTRASOUND:
messageID = R.string.drone_emergency_ultrasound;
method = EmergencyMethod.ALERT;
Log.d(getClass().getSimpleName(), "message code: " + getResources().getString(R.string.drone_emergency_ultrasound));
break;
case NavData.ERROR_STATE_ALERT_ULTRASOUND:
messageID = R.string.drone_alert_ultrasound;
method = EmergencyMethod.NOTHING;
Log.d(getClass().getSimpleName(), "message code: " + getResources().getString(R.string.drone_alert_ultrasound));
break;
case NavData.ERROR_STATE_ALERT_VISION:
messageID = R.string.drone_alert_vision;
method = EmergencyMethod.TOAST;
Log.d(getClass().getSimpleName(), "message code: " + getResources().getString(R.string.drone_alert_vision));
break;
case NavData.ERROR_STATE_EMERGENCY_ANGLE_OUT_OF_RANGE:
messageID = R.string.drone_emergency_angle;
method = EmergencyMethod.ALERT;
Log.d(getClass().getSimpleName(), "message code: " + getResources().getString(R.string.drone_emergency_angle));
break;
case NavData.ERROR_STATE_EMERGENCY_CUTOUT:
messageID = R.string.drone_emergency_cutout;
method = EmergencyMethod.ALERT;
Log.d(getClass().getSimpleName(), "message code: " + getResources().getString(R.string.drone_emergency_cutout));
break;
default:
Log.d(getClass().getSimpleName(), "message code (number): " + code);
return;
}
switch (method) {
case ALERT:
new AlertDialog.Builder(this)
.setTitle(R.string.drone_emergency_title)
.setMessage(messageID)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int id) {
}
})
.setCancelable(false)
.show();
break;
case TOAST:
ToastUtil.showError(this, messageID);
break;
}
}
}