package de.tu.darmstadt.seemoo.ansian.drawables;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import de.tu.darmstadt.seemoo.ansian.control.DataHandler;
import de.tu.darmstadt.seemoo.ansian.control.SourceControl;
import de.tu.darmstadt.seemoo.ansian.control.StateHandler;
import de.tu.darmstadt.seemoo.ansian.control.threads.SurfaceUpdateThread;
import de.tu.darmstadt.seemoo.ansian.model.preferences.ColorPreference;
import de.tu.darmstadt.seemoo.ansian.model.preferences.GuiPreferences;
import de.tu.darmstadt.seemoo.ansian.model.preferences.Preferences;
import de.tu.darmstadt.seemoo.ansian.model.sources.HackrfSource;
import de.tu.darmstadt.seemoo.ansian.model.sources.IQSourceInterface;
import de.tu.darmstadt.seemoo.ansian.model.sources.RtlsdrSource;
/**
* Drawable which shows performance and frequency information in AnalyzerSurface
*
*/
public class PerformanceInfoDrawable extends MyDrawable {
GuiPreferences guiPreferences = Preferences.GUI_PREFERENCE;
private int height;
private int width;
public PerformanceInfoDrawable(int height, int width) {
this.height = height;
this.width = width;
}
public void setDimensions(int height, int width) {
this.height = height;
this.width = width;
}
@SuppressLint("DefaultLocale")
@Override
public void draw(Canvas canvas) {
final float minDB = guiPreferences.getCurMinDB();
final float maxDB = guiPreferences.getCurMaxDB();
final long guiFrequency = guiPreferences.getFrequency();
final long demodFrequency = guiPreferences.getDemodFrequency();
final float squelch = guiPreferences.getSquelch();
final boolean showDebugInformation = guiPreferences.isShowDebugInformation();
// final boolean demodulationEnabled = StateHandler.isDemodulating();
final boolean displayRelativeFrequencies = guiPreferences.isDisplayRelativeFrequencies();
final int frameRate = SurfaceUpdateThread.getFrameRate();
final double load = SurfaceUpdateThread.getLoad();
Rect bounds = new Rect();
String text;
float yPos = height * 0.01f;
float rightBorder = width * 0.99f;
IQSourceInterface source = SourceControl.getSource();
// Source name and information
if (source != null) {
// Name
text = source.getName();
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, rightBorder - bounds.width(), yPos + bounds.height(),
ColorPreference.TEXT_SMALL_PAINT);
yPos += bounds.height() * 1.1f;
// Frequency
text = String.format("tuned to %4.6f MHz", guiFrequency / 1000000f);
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, rightBorder - bounds.width(), yPos + bounds.height(),
ColorPreference.TEXT_SMALL_PAINT);
yPos += bounds.height() * 1.1f;
// Center Frequency
if (displayRelativeFrequencies) {
text = String.format("centered at %4.6f MHz", guiFrequency / 1000000f);
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, rightBorder - bounds.width(), yPos + bounds.height(),
ColorPreference.TEXT_SMALL_PAINT);
yPos += bounds.height() * 1.1f;
}
// HackRF specific stuff:
if (source instanceof HackrfSource) {
text = String.format("shift=%4.6f MHz",
Preferences.MISC_PREFERENCE.getHackrfFrequencyShift() / 1000000f);
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, rightBorder - bounds.width(), yPos + bounds.height(),
ColorPreference.TEXT_SMALL_PAINT);
yPos += bounds.height() * 1.1f;
}
// RTLSDR specific stuff:
if (source instanceof RtlsdrSource) {
text = String.format("shift=%4.6f MHz",
Preferences.MISC_PREFERENCE.getRtlsdrFrequencyShift() / 1000000f);
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, rightBorder - bounds.width(), yPos + bounds.height(),
ColorPreference.TEXT_SMALL_PAINT);
yPos += bounds.height() * 1.1f;
text = "sps=" + SourceControl.getSource().getSampleRate();
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, rightBorder - bounds.width(), yPos + bounds.height(),
ColorPreference.TEXT_SMALL_PAINT);
yPos += bounds.height() * 1.1f;
}
}
// Draw the channel frequency if demodulation is enabled:
if (StateHandler.isDemodulating()) {
text = String.format("demod at %4.6f MHz", demodFrequency / 1000000f);
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, rightBorder - bounds.width(), yPos + bounds.height(),
ColorPreference.TEXT_SMALL_PAINT);
// increase yPos:
yPos += bounds.height() * 1.1f;
// Draw the average signal strength indicator if demodulation is
// enabled
float averageSignalStrength = DataHandler.getInstance().getLastFFTSample().getAverage(demodFrequency,
Preferences.GUI_PREFERENCE.getDemodBandwidth());
text = String.format("%2.1f dB", averageSignalStrength);
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
float indicatorWidth = width / 10;
float indicatorPosX = rightBorder - indicatorWidth;
float indicatorPosY = yPos + bounds.height();
float squelchTickPos = (squelch - minDB) / (maxDB - minDB) * indicatorWidth;
float signalWidth = (averageSignalStrength - minDB) / (maxDB - minDB) * indicatorWidth;
if (signalWidth < 0)
signalWidth = 0;
if (signalWidth > indicatorWidth)
signalWidth = indicatorWidth;
// draw signal rectangle:
guiPreferences.setSquelchSatisfied(squelch < averageSignalStrength);
canvas.drawRect(indicatorPosX, yPos + bounds.height() * 0.1f, indicatorPosX + signalWidth, indicatorPosY,
guiPreferences.isSquelchSatisfied() ? ColorPreference.SQUELCH_PAINT_SATISFIED
: ColorPreference.SQUELCH_PAINT);
// draw left border, right border, bottom line and squelch tick:
canvas.drawLine(indicatorPosX, indicatorPosY, indicatorPosX, yPos, ColorPreference.TEXT_PAINT);
canvas.drawLine(rightBorder, indicatorPosY, rightBorder, yPos, ColorPreference.TEXT_PAINT);
canvas.drawLine(indicatorPosX, indicatorPosY, rightBorder, indicatorPosY, ColorPreference.TEXT_PAINT);
canvas.drawLine(indicatorPosX + squelchTickPos, indicatorPosY + 2, indicatorPosX + squelchTickPos,
yPos + bounds.height() * 0.5f, ColorPreference.TEXT_PAINT);
// draw text:
canvas.drawText(text, indicatorPosX - bounds.width() * 1.1f, indicatorPosY,
ColorPreference.TEXT_SMALL_PAINT);
// increase yPos:
yPos += bounds.height() * 1.1f;
}
// Draw recording information
if (StateHandler.isRecording()) {
text = String.format("%4.6f MHz @ %2.3f MSps", source.getFrequency() / 1000000f,
source.getSampleRate() / 1000000f);
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, rightBorder - bounds.width(), yPos + bounds.height(),
ColorPreference.TEXT_SMALL_PAINT);
ColorPreference.DEFAULT_PAINT.setColor(Color.RED);
canvas.drawCircle(rightBorder - bounds.width() - (bounds.height() / 2) * 1.3f, yPos + bounds.height() / 2,
bounds.height() / 2, ColorPreference.DEFAULT_PAINT);
// increase yPos:
yPos += bounds.height() * 1.1f;
}
if (showDebugInformation) {
// Draw the FFT/s rate
text = frameRate + " FPS";
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, rightBorder - bounds.width(), yPos + bounds.height(),
ColorPreference.TEXT_SMALL_PAINT);
yPos += bounds.height() * 1.1f;
// Draw the load
text = String.format("%3.1f %%", load * 100);
ColorPreference.TEXT_SMALL_PAINT.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, rightBorder - bounds.width(), yPos + bounds.height(),
ColorPreference.TEXT_SMALL_PAINT);
yPos += bounds.height() * 1.1f;
}
}
}