package org.droidplanner.android.activities.helpers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import com.o3dr.android.client.Drone;
import com.o3dr.services.android.lib.drone.attribute.AttributeEvent;
import org.droidplanner.android.DroidPlannerApp;
import org.droidplanner.android.R;
import org.droidplanner.android.dialogs.SlideToUnlockDialog;
import org.droidplanner.android.dialogs.YesNoDialog;
import org.droidplanner.android.dialogs.YesNoWithPrefsDialog;
import org.droidplanner.android.fragments.SettingsFragment;
import org.droidplanner.android.proxy.mission.MissionProxy;
import org.droidplanner.android.utils.Utils;
import org.droidplanner.android.utils.prefs.DroidPlannerPrefs;
import org.droidplanner.android.utils.unit.UnitManager;
import org.droidplanner.android.utils.unit.systems.UnitSystem;
/**
* Parent class for the app activity classes.
*/
public abstract class SuperUI extends AppCompatActivity implements DroidPlannerApp.ApiListener {
private static final IntentFilter superIntentFilter = new IntentFilter();
static {
superIntentFilter.addAction(AttributeEvent.STATE_CONNECTED);
superIntentFilter.addAction(AttributeEvent.STATE_DISCONNECTED);
superIntentFilter.addAction(SettingsFragment.ACTION_ADVANCED_MENU_UPDATED);
}
private final BroadcastReceiver superReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
switch (action) {
case AttributeEvent.STATE_CONNECTED:
onDroneConnected();
break;
case AttributeEvent.STATE_DISCONNECTED:
onDroneDisconnected();
break;
case SettingsFragment.ACTION_ADVANCED_MENU_UPDATED:
supportInvalidateOptionsMenu();
break;
}
}
};
private ScreenOrientation screenOrientation = new ScreenOrientation(this);
private LocalBroadcastManager lbm;
/**
* Handle to the app preferences.
*/
protected DroidPlannerPrefs mAppPrefs;
protected UnitSystem unitSystem;
protected DroidPlannerApp dpApp;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Context context = getApplicationContext();
dpApp = (DroidPlannerApp) getApplication();
lbm = LocalBroadcastManager.getInstance(context);
mAppPrefs = new DroidPlannerPrefs(context);
unitSystem = UnitManager.getUnitSystem(context);
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
/*
* Used to supplant wake lock acquisition (previously in
* org.droidplanner.android.service .MAVLinkService) as suggested by the
* android android.os.PowerManager#newWakeLock documentation.
*/
if (mAppPrefs.keepScreenOn()) {
getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
setVolumeControlStream(AudioManager.STREAM_MUSIC);
screenOrientation.unlock();
Utils.updateUILanguage(context);
}
@Override
public void onDestroy() {
super.onDestroy();
lbm = null;
}
protected LocalBroadcastManager getBroadcastManager() {
return lbm;
}
@Override
public void onApiConnected() {
invalidateOptionsMenu();
getBroadcastManager().registerReceiver(superReceiver, superIntentFilter);
if (dpApp.getDrone().isConnected())
onDroneConnected();
else
onDroneDisconnected();
lbm.sendBroadcast(new Intent(MissionProxy.ACTION_MISSION_PROXY_UPDATE));
}
@Override
public void onApiDisconnected() {
getBroadcastManager().unregisterReceiver(superReceiver);
onDroneDisconnected();
}
private void onDroneConnected() {
invalidateOptionsMenu();
screenOrientation.requestLock();
}
private void onDroneDisconnected() {
invalidateOptionsMenu();
screenOrientation.unlock();
}
@Override
protected void onStart() {
super.onStart();
unitSystem = UnitManager.getUnitSystem(getApplicationContext());
dpApp.addApiListener(this);
maxVolumeIfEnabled();
}
@Override
public void onStop() {
super.onStop();
dpApp.removeApiListener(this);
}
private void maxVolumeIfEnabled() {
if (mAppPrefs.maxVolumeOnStart()) {
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_super_activiy, menu);
final MenuItem toggleConnectionItem = menu.findItem(R.id.menu_connect);
Drone dpApi = dpApp.getDrone();
if (dpApi != null && dpApi.isConnected()) {
menu.setGroupEnabled(R.id.menu_group_connected, true);
menu.setGroupVisible(R.id.menu_group_connected, true);
final boolean isAdvancedEnabled = mAppPrefs.isAdvancedMenuEnabled();
final MenuItem advancedSubMenu = menu.findItem(R.id.menu_advanced);
advancedSubMenu.setEnabled(isAdvancedEnabled);
advancedSubMenu.setVisible(isAdvancedEnabled);
//Enable specific sub items within the advanced menu section.
final MenuItem killSwitchItem = menu.findItem(R.id.menu_kill_switch);
final boolean isKillEnabled = mAppPrefs.isKillSwitchEnabled();
killSwitchItem.setEnabled(isKillEnabled);
killSwitchItem.setVisible(isKillEnabled);
final boolean areMissionMenusEnabled = enableMissionMenus();
final MenuItem sendMission = menu.findItem(R.id.menu_upload_mission);
sendMission.setEnabled(areMissionMenusEnabled);
sendMission.setVisible(areMissionMenusEnabled);
final MenuItem loadMission = menu.findItem(R.id.menu_download_mission);
loadMission.setEnabled(areMissionMenusEnabled);
loadMission.setVisible(areMissionMenusEnabled);
toggleConnectionItem.setTitle(R.string.menu_disconnect);
} else {
menu.setGroupEnabled(R.id.menu_group_connected, false);
menu.setGroupVisible(R.id.menu_group_connected, false);
toggleConnectionItem.setTitle(R.string.menu_connect);
}
return super.onCreateOptionsMenu(menu);
}
protected boolean enableMissionMenus() {
return false;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final Drone dpApi = dpApp.getDrone();
switch (item.getItemId()) {
case R.id.menu_connect:
toggleDroneConnection();
return true;
case R.id.menu_upload_mission: {
final MissionProxy missionProxy = dpApp.getMissionProxy();
if (missionProxy.getItems().isEmpty() || missionProxy.hasTakeoffAndLandOrRTL()) {
missionProxy.sendMissionToAPM(dpApi);
} else {
YesNoWithPrefsDialog dialog = YesNoWithPrefsDialog.newInstance(
getApplicationContext(), "Mission Upload",
"Do you want to append a Takeoff and RTL to your " + "mission?", "Ok",
"Skip", new YesNoDialog.Listener() {
@Override
public void onYes() {
missionProxy.addTakeOffAndRTL();
missionProxy.sendMissionToAPM(dpApi);
}
@Override
public void onNo() {
missionProxy.sendMissionToAPM(dpApi);
}
}, getString(R.string.pref_auto_insert_mission_takeoff_rtl_land_key));
if (dialog != null) {
dialog.show(getSupportFragmentManager(), "Mission Upload check.");
}
}
return true;
}
case R.id.menu_download_mission:
dpApi.loadWaypoints();
return true;
case R.id.menu_kill_switch:
SlideToUnlockDialog unlockDialog = SlideToUnlockDialog.newInstance("disable vehicle", new Runnable() {
@Override
public void run() {
dpApp.getDrone().arm(false);
}
});
unlockDialog.show(getSupportFragmentManager(), "Slide to use the Kill Switch");
return true;
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void toggleDroneConnection() {
final Drone drone = dpApp.getDrone();
if (drone != null && drone.isConnected())
dpApp.disconnectFromDrone();
else
dpApp.connectToDrone();
}
}