/*
* 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.test.formulaeditor;
import android.graphics.Point;
import android.test.InstrumentationTestCase;
import android.util.Log;
import org.catrobat.catroid.ProjectManager;
import org.catrobat.catroid.content.Project;
import org.catrobat.catroid.content.Script;
import org.catrobat.catroid.content.SingleSprite;
import org.catrobat.catroid.content.Sprite;
import org.catrobat.catroid.content.StartScript;
import org.catrobat.catroid.content.bricks.Brick;
import org.catrobat.catroid.content.bricks.ChangeSizeByNBrick;
import org.catrobat.catroid.facedetection.FaceDetectionHandler;
import org.catrobat.catroid.facedetection.FaceDetector;
import org.catrobat.catroid.formulaeditor.Formula;
import org.catrobat.catroid.formulaeditor.FormulaElement;
import org.catrobat.catroid.formulaeditor.InternFormulaParser;
import org.catrobat.catroid.formulaeditor.InternToken;
import org.catrobat.catroid.formulaeditor.InternTokenType;
import org.catrobat.catroid.formulaeditor.InterpretationException;
import org.catrobat.catroid.formulaeditor.SensorHandler;
import org.catrobat.catroid.formulaeditor.SensorLoudness;
import org.catrobat.catroid.formulaeditor.Sensors;
import org.catrobat.catroid.test.utils.Reflection;
import org.catrobat.catroid.test.utils.Reflection.ParameterList;
import org.catrobat.catroid.test.utils.SimulatedSoundRecorder;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
public class ParserTestSensors extends InstrumentationTestCase {
private static final String TAG = ParserTestSensors.class.getSimpleName();
private Project project;
private Sprite firstSprite;
Script startScript1;
private float delta = 0.001f;
@Override
public void setUp() throws Exception {
super.setUp();
createProject();
ProjectManager.getInstance().setProject(project);
ProjectManager.getInstance().setCurrentSprite(firstSprite);
//For initialization
SensorLoudness.getSensorLoudness();
SensorLoudness loudnessSensor = (SensorLoudness) Reflection.getPrivateField(SensorLoudness.class, "instance");
SimulatedSoundRecorder simSoundRec = new SimulatedSoundRecorder("/dev/null");
Reflection.setPrivateField(loudnessSensor, "recorder", simSoundRec);
}
@Override
public void tearDown() throws Exception {
SensorHandler.stopSensorListeners();
Reflection.setPrivateField(SensorHandler.class, "instance", null);
Reflection.setPrivateField(SensorLoudness.class, "instance", null);
super.tearDown();
}
public void testSensorManagerNotInitialized() {
SensorHandler.registerListener(null);
SensorHandler.unregisterListener(null);
SensorHandler.startSensorListener(getInstrumentation().getTargetContext());
if (ProjectManager.getInstance().isCurrentProjectLandscapeMode()) {
assertEquals("SensorHandler not initialized value error", 0d,
Math.abs((Double) SensorHandler.getSensorValue(Sensors.Y_ACCELERATION)));
} else {
assertEquals("SensorHandler not initialized value error", 0d,
Math.abs((Double) SensorHandler.getSensorValue(Sensors.X_ACCELERATION)));
}
}
public void testSensorHandlerWithLookSensorValue() {
SensorHandler.startSensorListener(getInstrumentation().getTargetContext());
assertEquals("SensorHandler returned wrong value when Sensor is not found in List", 0d,
SensorHandler.getSensorValue(Sensors.OBJECT_BRIGHTNESS));
SensorHandler.stopSensorListeners();
}
public void testFaceDetection() {
SensorHandler.startSensorListener(getInstrumentation().getTargetContext());
FaceDetector faceDetector = (FaceDetector) Reflection.getPrivateField(FaceDetectionHandler.class,
"faceDetector");
assertNotNull("SensorHandler was not registered as a listener at FaceDetectionHandler", faceDetector);
assertEquals("Face detection status initial value error", 0d,
SensorHandler.getSensorValue(Sensors.FACE_DETECTED));
assertEquals("Face detection size initial value error", 0d, SensorHandler.getSensorValue(Sensors.FACE_SIZE));
Method[] methods = faceDetector.getClass().getSuperclass().getDeclaredMethods();
for (Method method : methods) {
Log.e(TAG, method.getName());
}
ParameterList parameters = new ParameterList(Boolean.TRUE);
Reflection.invokeMethod(faceDetector.getClass().getSuperclass(), faceDetector, "onFaceDetected", parameters);
int expectedFaceSize = (int) (Math.random() * 100);
int exampleScreenWidth = 320;
int exampleScreenHeight = 480;
int expectedFaceXPosition = (int) (-exampleScreenWidth / 2 + (Math.random() * exampleScreenWidth));
int expectedFaceYPosition = (int) (-exampleScreenHeight / 2 + (Math.random() * exampleScreenHeight));
parameters = new ParameterList(new Point(expectedFaceXPosition, expectedFaceYPosition),
expectedFaceSize);
Reflection.invokeMethod(faceDetector.getClass().getSuperclass(), faceDetector, "onFaceDetected", parameters);
Formula formula6 = createFormulaWithSensor(Sensors.FACE_DETECTED);
ChangeSizeByNBrick faceDetectionStatusBrick = new ChangeSizeByNBrick(formula6);
startScript1.addBrick(faceDetectionStatusBrick);
Formula formula7 = createFormulaWithSensor(Sensors.FACE_SIZE);
ChangeSizeByNBrick faceSizeBrick = new ChangeSizeByNBrick(formula7);
startScript1.addBrick(faceSizeBrick);
Formula formula8 = createFormulaWithSensor(Sensors.FACE_X_POSITION);
ChangeSizeByNBrick faceXPositionBrick = new ChangeSizeByNBrick(formula8);
startScript1.addBrick(faceXPositionBrick);
Formula formula9 = createFormulaWithSensor(Sensors.FACE_Y_POSITION);
ChangeSizeByNBrick faceYPositionBrick = new ChangeSizeByNBrick(formula9);
startScript1.addBrick(faceYPositionBrick);
assertEquals("Unexpected sensor value for face detection status (= 1 if face detected, 0 otherwise)", 1d,
interpretFormula(formula6));
assertEquals(
"Unexpected sensor value for face size (= width of the face (range: 0 to 100, where at 100 the face fills half the width of the cameras view)",
expectedFaceSize, interpretFormula(formula7), delta);
if (ProjectManager.getInstance().isCurrentProjectLandscapeMode()) {
assertEquals(
"Unexpected sensor value for face x position (= in portrait mode, the central x coordinate of the face if the camera input is projected fullscreen to the display (range: 0 to screen width) )",
expectedFaceXPosition, interpretFormula(formula9), delta);
assertEquals(
"Unexpected sensor value for face y position (= in portrait mode, the central y coordinate of the face if the camera input is projected fullscreen to the display (range: 0 to screen height) )",
expectedFaceYPosition, -interpretFormula(formula8), delta);
} else {
assertEquals(
"Unexpected sensor value for face x position (= in portrait mode, the central x coordinate of the face if the camera input is projected fullscreen to the display (range: 0 to screen width) )",
expectedFaceXPosition, interpretFormula(formula8), delta);
assertEquals(
"Unexpected sensor value for face y position (= in portrait mode, the central y coordinate of the face if the camera input is projected fullscreen to the display (range: 0 to screen height) )",
expectedFaceYPosition, -interpretFormula(formula9), delta);
}
SensorHandler.stopSensorListeners();
}
public void testMicRelease() {
SensorLoudness.getSensorLoudness();
SensorLoudness loudnessSensor = (SensorLoudness) Reflection.getPrivateField(SensorLoudness.class, "instance");
SimulatedSoundRecorder simulatedSoundRecorder = new SimulatedSoundRecorder("/dev/null");
Reflection.setPrivateField(loudnessSensor, "recorder", simulatedSoundRecorder);
SensorHandler.startSensorListener(getInstrumentation().getTargetContext());
assertEquals("LoudnessSensor dit not start recording, isRecording()", true, simulatedSoundRecorder.isRecording());
SensorHandler.stopSensorListeners();
assertEquals("LoudnessSensor did not stop recording, isRecording()", false, simulatedSoundRecorder.isRecording());
}
private Formula createFormulaWithSensor(Sensors sensor) {
List<InternToken> internTokenList = new LinkedList<InternToken>();
internTokenList.add(new InternToken(InternTokenType.SENSOR, sensor.name()));
InternFormulaParser internFormulaParser = new InternFormulaParser(internTokenList);
FormulaElement root = internFormulaParser.parseFormula();
return new Formula(root);
}
private void createProject() {
this.project = new Project(null, "testProject");
firstSprite = new SingleSprite("zwoosh");
startScript1 = new StartScript();
Brick changeBrick = new ChangeSizeByNBrick(10);
firstSprite.addScript(startScript1);
startScript1.addBrick(changeBrick);
project.getDefaultScene().addSprite(firstSprite);
}
private Double interpretFormula(Formula formula) {
try {
return formula.interpretDouble(firstSprite);
} catch (InterpretationException interpretationException) {
Log.d(getClass().getSimpleName(), "Formula interpretation for Formula failed.", interpretationException);
}
return Double.NaN;
}
}