I want to be able to test the Gluon PositionService from my laptop. Is this possible? Looking at the runtime dependencies, iOS and Android have this jar file included. The desktop dependencies don't have it though.
What is a workaround to be able to test this service from my laptop. I just want to be able to print out the location to the console right now. Is this a limitation of my laptop?
Given that the laptop/desktop machine doesn't include a GPS sensor, there is no sense on having a DesktopPositionService implementation.
But if you just want to test your code for mobile on your laptop, you can easily create a fake task that randomly provides a new position after a given period of time.
There are two simple ways to mock the PositionService on desktop.
One, by simply providing an alternative to the case where you don't actually have a PositionService implementation:
Services.get(PositionService.class)
.map(s -> {
// Mobile - real implementation
s.positionProperty().addListener((obs, ov, nv) ->
System.out.println(String.format("Lat: %.6f, Lon: %.6f", nv.getLatitude(), nv.getLongitude())));
return s.getPosition();
}).orElseGet(() -> {
if (Platform.isDesktop()) {
// Desktop - Mock implementation
PauseTransition pause = new PauseTransition(Duration.seconds(5));
pause.setOnFinished(t -> {
System.out.println(String.format("Lat: %.6f, Lon: %.6f", new Random().nextFloat() * 100, new Random().nextFloat() * 100));
pause.playFromStart();
});
pause.play();
}
return null;
});
And two, following the design of all the different plugins in Charm Down, by actually providing a PositionService implementation, creating the DesktopPositionService class in the Desktop/Java Package of your project under the package com.gluonhq.charm.down.plugins.desktop.
package com.gluonhq.charm.down.plugins.desktop;
import com.gluonhq.charm.down.plugins.Position;
import com.gluonhq.charm.down.plugins.PositionService;
import java.util.Random;
import javafx.animation.PauseTransition;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.util.Duration;
public class DesktopPositionService implements PositionService {
private final ReadOnlyObjectWrapper<Position> positionProperty = new ReadOnlyObjectWrapper<>();
public DesktopPositionService() {
mockPosition();
}
#Override
public ReadOnlyObjectProperty<Position> positionProperty() {
return positionProperty.getReadOnlyProperty();
}
#Override
public Position getPosition() {
return positionProperty.get();
}
private void mockPosition() {
PauseTransition pause = new PauseTransition(Duration.seconds(5));
pause.setOnFinished(t -> {
positionProperty.set(new Position(new Random().nextFloat() * 100, new Random().nextFloat() * 100));
pause.playFromStart();
});
pause.play();
}
}
So now this will work for both mobile (real sensor) and desktop (mock):
Services.get(PositionService.class)
.ifPresent(s ->
s.positionProperty().addListener((obs, ov, nv) ->
System.out.println(String.format("Lat: %.6f, Lon: %.6f", nv.getLatitude(), nv.getLongitude()))));
Related
I am trying to reuse karate scripts and perform load testing using gatling. The scenario defined is to load constant 50 users per second for 10 seconds. (To load test 500 users) However the number of requests per second does not exceed 20 requests per second in the gatling report. Please let me know if i am doing anything wrong.
ExampleTest.java code which executes Karate scripts
//package examples;
import com.intuit.karate.Results;
import com.intuit.karate.Runner;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.masterthought.cucumber.Configuration;
import net.masterthought.cucumber.ReportBuilder;
import org.apache.commons.io.FileUtils;
class ExamplesTest {
#Test
void testParallel() {
//System.setProperty("karate.env", "demo"); // ensure reset if other tests (e.g. mock) had set env in CI
Results results = Runner.path("classpath:examples").tags("~#ignore").parallel(10);
generateReport(results.getReportDir());
assertEquals(0, results.getFailCount(), results.getErrorMessages());
}
public static void generateReport(String karateOutputPath) {
Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] {"json"}, true);
List<String> jsonPaths = new ArrayList<String>(jsonFiles.size());
jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
Configuration config = new Configuration(new File("target"), "demo");
ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
reportBuilder.generateReports();
}
}
Scala Code to define load test scenarios.
package perf
import com.intuit.karate.gatling.PreDef._
import io.gatling.core.Predef._
import scala.concurrent.duration._
class KarateSimulate extends Simulation {
val protocol = karateProtocol(
"/v2/" -> Nil,
"/v2/" -> pauseFor("get" -> 0, "post" -> 25)
)
val userfeeder = csv("data/Token.csv").circular
val getScores = scenario("Get Scores for Students").feed(userfeeder).exec(karateFeature("classpath:examples/scores/student.feature"))
setUp(
getScores.inject(constantUsersPerSec(50) during (10 seconds)).protocols(protocol)
)
}
We updated the docs (in the develop branch) with tips on how to increase the thread-pool size if needed: https://github.com/intuit/karate/tree/develop/karate-gatling#increasing-thread-pool-size
Add a file called gatling-akka.conf to the root of the classpath (typically src/test/resources). Here is an example:
akka {
actor {
default-dispatcher {
type = Dispatcher
executor = "thread-pool-executor"
thread-pool-executor {
fixed-pool-size = 100
}
throughput = 1
}
}
}
Since we made some fixes recently, please try to build from source if the above does not work for 0.9.6.RC4, it is easy, here are the instructions: https://github.com/intuit/karate/wiki/Developer-Guide
If that does not work, it is important that you follow this process so that we can replicate: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue
Please see these links below for good examples of how others have worked with the Karate project team to replicate issues so that they can be fixed:
https://github.com/intuit/karate/issues/1668
https://github.com/intuit/karate/issues/845
As title said, I want to use xposed to log all methods called in an app from it start till I stop it. I only want to log Class name, Method name, don't want to hook all method.
I try this code, but get error getMethod not found.
findAndHookMethod("java.lang.Class", lpparam.classLoader, "getMethod", String.class, Object.class, new XC_MethodHook()
Thanks in advance!
There is no one line solution like what you seem to be searching.
Hooking all methods will let log what methods were called by app from it start till stop (sort of - see below), but if (for some reason) you don't want to hook all methods, the only solution I can think of is modifying the java VM itself (NOT something I would recommend.)
A solution that (sort of) works
What I did was first use apktool to decompile my apk and get the names of all the methods in all the classes.
Then I used xposed to hook into every single method of every class and print to the dlog the current function name.
Why it only sort of works
Xposed has an overhead whenever it hook a methods. For general usage of xposed apps, it isnt much. But when you start hooking each and every methods of an app, the overhead very quickly becomes ridiculously large - So much so that while the above methods works for small apps, for any large app it very quickly causes the app to hang and then crash.
An alternative that also sort-of works
FRIDA is a way to inject javascript to native apps. Here they show you how to log all function calls. While in the above link they log all function calls in a piece of python code, the same code also works for Android.
There is a way to log all Java methods.Modify XposedBridge.
Xposed hook java method through XposedBridge.java's method
"handleHookedMethod(Member method, int originalMethodId, Object additionalInfoObj, thisObject, Object[] args)"
Log.v(TAG, "className " + method.getClass().getName() + ",methodName " + method.getName());
As mentioned before Xposed is not the way to go in this situation due to its overhead.
The simplest solution is just to use dmtracedump as provided by Google. Most x86 Android images and emulator come with the debuggable flag on (ro.debuggable) so you can even use it for closed source apps.
Additionally other tools such as Emma are known to work with Android as well, but these might need modifications to the source code.
I found a solution.
See this code snippet below.
package com.kyunggi.logcalls;
import android.content.pm.*;
import android.util.*;
import dalvik.system.*;
import de.robv.android.xposed.*;
import de.robv.android.xposed.callbacks.XC_LoadPackage.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import android.app.*;
public class Main implements IXposedHookLoadPackage {
private String TAG = "LogCall";
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("com.android.bluetooth")) {
Log.i(TAG, "Not: " + lpparam.packageName);
return;
}
Log.i(TAG, "Yes " + lpparam.packageName);
//Modified https://d3adend.org/blog/?p=589
ApplicationInfo applicationInfo = AndroidAppHelper.currentApplicationInfo();
if (applicationInfo.processName.equals("com.android.bluetooth")) {
Set<String> classes = new HashSet<>();
DexFile dex;
try {
dex = new DexFile(applicationInfo.sourceDir);
Enumeration entries = dex.entries();
while (entries.hasMoreElements()) {
String entry = (String) entries.nextElement();
classes.add(entry);
}
dex.close();
} catch (IOException e) {
Log.e("HookDetection", e.toString());
}
for (String className : classes) {
boolean obex = false;
if (className.startsWith("com.android.bluetooth") || (obex = className.startsWith("javax.obex"))) {
try {
final Class clazz = lpparam.classLoader.loadClass(className);
for (final Method method : clazz.getDeclaredMethods()) {
if (obex) {
if (!Modifier.isPublic(method.getModifiers())) {
continue; //on javax.obex package, hook only public APIs
}
}
XposedBridge.hookMethod(method, new XC_MethodHook() {
final String methodNam = method.getName();
final String classNam = clazz.getName();
final StringBuilder sb = new StringBuilder("[");
final String logstr = "className " + classNam + ",methodName " + methodNam;
#Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
//Method method=(Method)param.args[0];
sb.setLength(0);
sb.append(logstr);
//Log.v(TAG,logstr);
for (Object o : param.args) {
String typnam = "";
String value = "null";
if (o != null) {
typnam = o.getClass().getName();
value = o.toString();
}
sb.append(typnam).append(" ").append(value).append(", ");
}
sb.append("]");
Log.v(TAG, sb.toString());
}
});
}
} catch (ClassNotFoundException e) {
Log.wtf("HookDetection", e.toString());
}
}
}
}
// ClassLoader rootcl=lpparam.classLoader.getSystemClassLoader();
//findAndHookMethod("de.robv.android.xposed.XposedBridge", rootcl, "handleHookedMethod", Member.class, int.class, Object.class, Object.class, Object[].class, );
}
}
I want to have 3 objects doing different things, so I want to get the source of the caller.
I am using lambda for that, and I am not using key frame, the animation is the same and cyclic so I don't need to specify different behavior for a different key frame.
Maybe I am doing something wrong with the lambda?
this is my code:
class MyClock extends ClockPane //clockpane extends pane
{
Timeline animation;
int id;
EventHandler<ActionEvent> eventHandler = e ->
{//startAnimationById();
System.out.println(e.getSource()==clockControl1.myclock.animation);
};
public MyClock(int c,int id)
{
super(c);
this.id=id;
animation = new Timeline(new KeyFrame(Duration.millis(1000),eventHandler));
animation.setCycleCount(Timeline.INDEFINITE);
animation.play();
}
the startanimationbyid method works using the id I defined to avoid this problem, but it surely does bug me.
I have 3 different objects of this type, each one is nested ina clockcontrol class
(in other words I have clockcontrol1 clockcontrol2 and 3 each one of these having a MyClock myclock in them)
The print I have there returns false for all the the clocks I have (total of 3) while as it is currently written I'd expect to get true for the first clock...I tried different variations of this, the one I post here is only the last variation, but I got false for all of my attempts.
Where did I mess things up?
The API for KeyFrame doesn't specify what the source of the ActionEvent will be. You could just do System.out.println(e.getSource()) to see (it seems that the source of the event is the KeyFrame object, not the animation), but there's no real guarantee it would always be what you expect.
If you want different instances of MyClock to behave differently, you can provide a parameter for the different behavior. In this case, you could use a Runnable to execute different code in the event handler:
class MyClock extends ClockPane //clockpane extends pane
{
Timeline animation;
// int id;
public MyClock(int c, Runnable handler)
{
super(c);
EventHandler<ActionEvent> eventHandler = e -> handler.run() ;
animation = new Timeline(new KeyFrame(Duration.millis(1000),eventHandler));
animation.setCycleCount(Timeline.INDEFINITE);
animation.play();
}
}
Then you can instantiate these as you need:
public class Controller1 {
// ...
MyClock clock = new MyClock(..., () -> {
// code to execute for this clock
});
}
and
public class Controller2 {
// ...
MyClock clock = new MyClock(..., () -> {
// code to execute for this clock
});
}
I am new to game development but familiar with programming languages. I have started using Flixel and have a working Breakout game with score and lives.
What I am trying to do is add a Start Screen before actually loading the game.
I have a create function that adds all the game elements to the stage:
override public function create():void
// all game elements
{
How can I add this pre-load Start Screen? I'm not sure if I have to add in the code to this create function or somewhere else and what code to actually add.
Eventually I would also like to add saving, loading, options and upgrades too. So any advice with that would be great.
Here is my main game.as:
package
{
import org.flixel.*;
public class Game extends FlxGame
{
private const resolution:FlxPoint = new FlxPoint(640, 480);
private const zoom:uint = 2;
private const fps:uint = 60;
public function Game()
{
super(resolution.x / zoom, resolution.y / zoom, PlayState, zoom);
FlxG.flashFramerate = fps;
}
}
}
Thanks.
The way that I usually do it is with a different FlxState - I use one for "Menu", the game itself, and the Game Over screen.
So make a new class that extends FlxState, call it maybe "MenuState" and then say:
super(resolution.x / zoom, resolution.y / zoom, MenuState, zoom);
Inside MenuState, on a button press or something, say:
FlxG.switchState(PlayState);
I am a beginner in java(fx).
How do you get the mouse location in x and y in JavaFX? I tried using AWT's MouseInfo(also imported it), but it's not working. I also saw the code for it in Ensembles(that dragging the ball-window in "advanced stage", that's what I need to do, drag my undecorated JavaFX stage), but it also doesn't work. I am using FXML with controller, and I guess that's the main problem. Should I switch back to the single-file simple JavaFX? I know FXML is better for laying out the UI, but I can't get many of such codes to work. Or do I need some other sort of code for my controller? Please give proper codes with comments wherever possible.
If you need a bit of my code to inspect, feel free to ask.
There are a few items in your question - I'll tackle them one at a time.
How do you get the mouse location in x and y in JavaFX?
Add a mouse event handler to the appropriate JavaFX component that you want to track the mouse location in. A JavaFX mouse event will report multiple different kinds of co-ordinates. The x and y co-ordinates are relative to the top left corner of the node whose location is being monitored. The sceneX and sceneY co-ordinates are relative to the scene's top left 0,0 co-ordinates. The screenX and screenY co-ordinates are relative to the top left 0,0 co-ordinates of the current screen.
These co-ordinates are documented in the MouseEvent documentation. There is extra information in understanding co-ordinate systems in the Node and Scene documentation.
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.*;
public class MouseLocationReporter extends Application {
private static final String OUTSIDE_TEXT = "Outside Label";
public static void main(String[] args) { launch(args); }
#Override public void start(final Stage stage) {
final Label reporter = new Label(OUTSIDE_TEXT);
Label monitored = createMonitoredLabel(reporter);
VBox layout = new VBox(10);
layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10px;");
layout.getChildren().setAll(
monitored,
reporter
);
layout.setPrefWidth(500);
stage.setScene(
new Scene(layout)
);
stage.show();
}
private Label createMonitoredLabel(final Label reporter) {
final Label monitored = new Label("Mouse Location Monitor");
monitored.setStyle("-fx-background-color: forestgreen; -fx-text-fill: white; -fx-font-size: 20px;");
monitored.setOnMouseMoved(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent event) {
String msg =
"(x: " + event.getX() + ", y: " + event.getY() + ") -- " +
"(sceneX: " + event.getSceneX() + ", sceneY: " + event.getSceneY() + ") -- " +
"(screenX: " + event.getScreenX()+ ", screenY: " + event.getScreenY() + ")";
reporter.setText(msg);
}
});
monitored.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent event) {
reporter.setText(OUTSIDE_TEXT);
}
});
return monitored;
}
}
I tried using AWT's MouseInfo(also imported it), but it's not working.
Don't do this. Mixing different graphical toolkits (for example Swing/AWT and JavaFX) is an advanced topic. In general, if you are writing a JavaFX application, avoid importing anything from the java.awt namespace and the javax.swing namespace. You only really need to use those if you have a large, existing Swing based application or framework that you need to inter-operate with your JavaFX application. In this case, you don't have that situation.
I also saw the code for it in Ensembles(that dragging the ball-window in "advanced stage", that's what I need to do, drag my undecorated JavaFX stage), but it also doesn't work.
I tried the Ensemble Advanced Stage sample and dragging that stage around worked for me.
Another sample for dragging an undecorated stage in JavaFX is in the answer to How to draw a clock with JavaFX 2? which has associated sample code. The method used to make the undecorated stage draggable for the clock sample is:
/** makes a stage draggable using a given node */
public static void makeDraggable(final Stage stage, final Node byNode) {
final Delta dragDelta = new Delta();
byNode.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
dragDelta.x = stage.getX() - mouseEvent.getScreenX();
dragDelta.y = stage.getY() - mouseEvent.getScreenY();
byNode.setCursor(Cursor.MOVE);
}
});
byNode.setOnMouseReleased(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
byNode.setCursor(Cursor.HAND);
}
});
byNode.setOnMouseDragged(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
stage.setX(mouseEvent.getScreenX() + dragDelta.x);
stage.setY(mouseEvent.getScreenY() + dragDelta.y);
}
});
byNode.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
byNode.setCursor(Cursor.HAND);
}
}
});
byNode.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
byNode.setCursor(Cursor.DEFAULT);
}
}
});
}
I am using FXML with controller, and I guess that's the main problem. Should I switch back to the single-file simple JavaFX? I know FXML is better for laying out the UI, but I can't get many of such codes to work.
Lack of understanding and familiarity with the underlying JavaFX APIs is probably your main problem rather than use of FXML. However the additional complexity fxml implies together with the lighter documentation and samples for it on the web may be contributing to your hardships. If use of FXML is making it difficult for you to understand how to get some JavaFX functions to work, I advise to stop using FXML for now. Code the logic by hand using the Java APIs and refer to the Oracle JavaFX tutorials and the Ensemble sample code when you encounter things which are difficult for you.
Once you are comfortable coding directly to the JavaFX API, switch back to using FXML for larger projects which contain many GUI elements. The FXML elements and attributes themselves are built almost completely upon reflection of the standard JavaFX APIs. So, if you understand the core JavaFX APIs, you also understand almost everything about FXML.
Please do not post follow up comments to this answer (as this answer is long enough as it is). If you have new questions, create a new question (one question per question).
What about using Robot for that purpose ?
http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/Robot.html
Using Robots, it is different from posting event to AWT event queue. Events are generated in the native event queue. Actually, with Robot.mouseMove you will not only set mouse position and not only get position.
For getting mouse position, you may stick to MouseInfo
import java.awt.MouseInfo;
// get the mouse's position
Point p = MouseInfo.getPointerInfo().getLocation();
It's not working: are you with Mac ? Which is your version of JavaFX ? seems to be issues corrected for FX8. For mac only, you may use
com.sun.glass.ui.Robot robot =
com.sun.glass.ui.Application.GetApplication().createRobot();
// getPosition of the mouse in Mac
int x = robot.getMouseX();
int y = robot.getMouseY();
JavaFx 8 WindowEvent doesn't provide the (x,y) location of the mouse, unfortunately. I solved this (and it works fine) by using the AWT MouseInfo like this:
Tooltip t = new Tooltip();
Tooltip.install(yournode, t);
t.setOnShowing(ev -> {// called just prior to being shown
Point mouse = java.awt.MouseInfo.getPointerInfo().getLocation();
Point2D local = yournode.screenToLocal(mouse.x, mouse.y);
// my app-specific code to get the chart's yaxis value
// then set the text as I want
double pitch = yaxis.getValueForDisplay(local.getY()).doubleValue();
double freq = AudioUtil.pitch2frequency(pitch);
t.setText(String.format("Pitch %.1f: %.1f Hz %.1f samples", pitch, freq, audio.rate / freq));
});