How to disable image loading in CEF/JCEF? - java

Is there a switch/flag that allows to do this? I spent hours finding those but couldn't find anything that works. The other thing I'm planning to do is intercept the cefRequest by adding my own CefRequestHandler, examine the resource type and if it matches RT_IMAGE, cancel the request. Everything seems easy except the part when I have to cancel a request. How do I stop/block/cancel a cefRequest? I probably should not be doing it this way but it doesn't work anyway:
public class CefClientRequestHandler extends CefRequestHandlerAdapter {
#Override
public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
if (cefRequest.getResourceType().equals(CefRequest.ResourceType.RT_IMAGE)) {
cefRequest.setURL("");
}
return false;
}
// more overides
}
Any ideas?

So here's a hack that works. The trick is to change the Request Method to HEAD, and because HEAD requests aren't returned the body, images won't be part of the response.
public class CefClientRequestHandler extends CefRequestHandlerAdapter {
#Override
public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
if (cefRequest.getResourceType().equals(RT_IMAGE)) {
cefRequest.setMethod("HEAD");
}
return false;
}
// other overridden methods here...
}
I believe that this approach should be avoided mainly because of the following two reasons:
Changing the method from GET to HEAD does not prevent CEF from making the request to the server. The overhead of opening a connection and handling a request is still there which makes it slower than simply blocking the request.
I'm not sure if images won't be displayed if they are available from browser cache. Currently, I don't know of any methods to test this. Suggestions are welcome.
Edit 1:
Changing URL didn't work in the example I posted in the question because I was passing an empty String as the new URL. If we set the URL to some address that is not an "active" domain name (e.g. https://absolutegarbage-sdjdjfbskdfb.com), the request for that resource fails immediately:
#Override
public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
if (cefRequest.getResourceType().equals(CefRequest.ResourceType.RT_IMAGE)) {
cefRequest.setURL("https://yghjbnbk.com");
System.out.println("LOL!");
}
return false;
}
As you can probably guess, this still is not the best solution. Please post an answer or comment if someone has found a better solution.
Edit 2: Finally I have a clean working solution, thanks to user amaitland. We just have to pass a command line switch while setting the CefAppHandler. We can do that by overriding the method onBeforeCommandLineProcessing like this:
CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
#Override
public void onBeforeCommandLineProcessing(String s, CefCommandLine cefCommandLine) {
cefCommandLine.appendSwitch("disable-image-loading");
}
#Override
public void stateHasChanged(CefApp.CefAppState state) {
if (state == CefApp.CefAppState.TERMINATED) System.exit(0);
}
});

Related

Google Fit Listen for Data Updates not working

I'm trying to implement a Google Fit Listener when data is updated into Google Fit services.
In this link of Google Fit documentation there is a simple example, however, it is not 100% clear. For that reason, I have two problems:
I don't know how to implement mResultCallback variable (there aren't any examples in this documentation).
When I define a simple ResultCallback (it seems to work but I'm not sure) and I launch the application, it gives me a result error code: java.lang.SecurityException: Signature check failed
The code within the HistortyApi lists one of android.permission.ACCESS_FINE_LOCATION or android.permission.BODY_SENSORS as being required.
Adding those permissions to my code hasn't resolved the same problem though.
Confirmed bug in Google Fit services. See discussion in https://plus.google.com/110141422948118561903/posts/Lqri4LVR7cD
mResultCallback is a ResultCallback<Status> so you need to implement a class of that type. Documentation is here, but there's only one method you need to implement:
public abstract void onResult (Status result)
The standard way is to do this using an anonymous class either when you declare mResultCallback or when you're using it as a parameter. Below is an example from Google's BasicRecordingAPI example:
Fitness.RecordingApi.subscribe(mClient, DataType.TYPE_ACTIVITY_SAMPLE)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
if (status.getStatusCode()
== FitnessStatusCodes.SUCCESS_ALREADY_SUBSCRIBED) {
Log.i(TAG, "Existing subscription for activity detected.");
} else {
Log.i(TAG, "Successfully subscribed!");
}
} else {
Log.i(TAG, "There was a problem subscribing.");
}
}
});
If you want to use a member variable you can simply make an assignment instead:
ResultCallback<Status> mResultCallback = new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
...
}
});
Of course you can define a non-anonymous class, but if you did that for every callback you had you would end up creating a LOT of classes.

Google Cast - Cannot Resolve mSelectedDevice

I am having a problem making a Google Cast Service. I can not seem to find what to use for mSelectedDevice. Both tutorials that I am using do not provide enough explanation for this, and neither go into detail of what mSelectedDevice should be.
public class CastMediaRouterCallback extends MediaRouter.Callback{
#Override
public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) {
mSelectedDevice = CastDevice.getFromBundle(info.getExtras());
String routeId = info.getId();
//Startd NanoHTTPD, Find URI of photo/video, and display on Cast device
}
#Override
public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) {
teardown();
mSelectedDevice = null;
}
}
(Tutorials I am using: https://developers.google.com/cast/docs/android_sender /// https://www.binpress.com/tutorial/building-an-android-google-cast-sender-app/161)
mSelecteDevice is an instance variable that is of type CastDevice. Not sure what you mean by "Google Cast Service" in your question but it seems you might be better off grabbing a sample project from oue GitHub repo as your starting point.

Multi Threading in web application

I have class which is used to display the current location in the bread crumb.
This class is getting initialised per user from the front end.
my question is do I need to synchronise the methods in this class if yes which are methods needs to be synchronised .There is some confusion. so please advise.
public class CrumbNav {
private Stack<Crumb> stack;
private Crumb crumb;
public CrumbNav() {
stack = new Stack<Crumb>();
crumb = new Crumb("Home");
stack.push(crumb);
}
public void addcrumb(String current) {
Crumb newCrumb = new Crumb(current);
if (stack.peek().equals(newCrumb)) {
return;
}
stack.push(newCrumb);
}
public void removeCurrent() {
stack.pop();
}
public void eraseTrail() {
stack.clear();
stack.push(crumb);
}
public void removeCrumbsClicked(Crumb selected) {
while (true) {
if (stack.peek().equals(selected) || stack.isEmpty())
break;
stack.pop();
}
}
public Crumb getLastBreadCrumb() {
return stack.lastElement();
}
public Crumb getPreviousCrumb() {
if (stack.size() > 1) {
return stack.get(stack.size() - 2);
}
return null;
}
public List<Crumb> getCrumbTrail() {
return stack.subList(0, stack.size());
}
}
It depends on what web framework you're using as to if the object is created per-thread, or as a singleton for the entire session. Spring will, by default, create a single instance and may require synchronization. Other web frameworks may not.
Note that in the "happy path" world, there's only one active thread rendering a page for any given user, but there's nothing stopping the user from rapid-fire clicking on different link initiating many connections and therefore threads.
(I mentioned this in comments, I think it's better to make it an answer.)
There are so many web framework in the industry, who knows how they gonna use your class? The best way is to test whether multiple thread gonna access the same instance concurrently.
Maintain a concurrent set in your class. Every time the method been called, add currentThread.thread_id into the set. Then output the set at last, seeing that whether it's been called from multiple threads. If so, then rewrite your class to a thread-safe version.
Tracking navigation is normally on a per user basis. This class contains storage of the navigation state - which is user specific state, so you need one instance per user session. The methods don't need to be synchronised unless there is the possibility of the same user re-entrantly entering the web server (as mentioned by PaulProgrammer).
Some frameworks will allow this. It can be prevented in Spring MVC by setting the synchronizeOnSession controller property, and there are likely similar techniques for other frameworks.

GWT SuggestBox: How do I force the SuggestBox to select the first item in the suggestion list?

I have a textbox and one suggestbox. I attach a value change and key up handler to the text box such that whatever the user types (or pastes) into the text box is echo-ed inside the suggestbox. I can get the suggestbox to display the suggestion list by calling showSuggestionList on each value change and key up event.
Now, how do I get the suggestbox to automatically choose the first item in the suggestion list?
One of the methods I tried is to programatically simulate key presses, i.e
suggestBox.setFocus(true);
NativeEvent enterEvent = Document.get().createKeyPressEvent(false, false, false, false, KeyCodes.KEY_ENTER);
DomEvent.fireNativeEvent(enterEvent, suggestBox);
textBox.setFocus(true);
This doesn't work at all. The enter key isn't simulated. Another possible solution is to extend SuggestionBox.SuggestionDisplay, but I'm not too sure how to that. Any pointers appreciated.
Update: I'm still working on this and trying various methods.
Here, I tried to implement my own SuggestionDisplay by subclassing DefaultSuggestionDisplay and overriding getCurrentSelection() to make accessible from my class. This doesn't work either. Null is returned.
private class CustomSuggestionDisplay extends DefaultSuggestionDisplay {
#Override
protected Suggestion getCurrentSelection() {
return super.getCurrentSelection();
}
}
suggestBox.setAutoSelectEnabled(true);
textBox.addKeyUpHandler(new KeyUpHandler() {
public void onKeyUp(KeyUpEvent event) {
suggestBox.setValue(textBox.getText(), true);
suggestBox.showSuggestionList();
if (suggestBox.isSuggestionListShowing()) {
String s = ((CustomSuggestionDisplay) suggestBox.getSuggestionDisplay()).getCurrentSelection().getDisplayString();
Window.alert(s);
}
}
});
Here, I tried to attach a value change handler to the SuggestBox, and casting the event type to SuggestOracle.Suggestion. Again, null is returned.
suggestBox.addValueChangeHandler(new ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
String s = ((SuggestOracle.Suggestion) event).getDisplayString();
Window.alert(s);
}
});
Use suggesBox.setAutoSelectEnabled(true)
Here more info about the SuggestBox of GWT:
You could try using addSelectionHandler in conjunction with setAutoSelectEnabled to receive an event whenever a suggestion is selected. You could also have your Oracle send a message when it suggests something, or your Display send a message when it displays a list:
public class AutomaticallySelectingSuggestionDisplay extends SuggestBox.DefaultSuggestionDisplay {
#Override
protected void showSuggestions(SuggestBox box, Collection<? extends SuggestOracle.Suggestion> suggestions, boolean isDisplayHtml, boolean isAutoSelectEnabled, SuggestBox.SuggestionCallback callback) {
super.showSuggestions(box, suggestions, isDisplayHtml, isAutoSelectEnabled, callback);
fireValueChangeEventWithFirstSuggestion(suggestions);
}
}
This idea feels a little muddled to me, so I hope you can find a solution just using event handlers.

Is this typically how Java interfaces are used to set up event handlers, and are there hidden drawbacks to this approach?

Hey all, I'm still relatively new to Java, and looking for a sanity check.
I've been studying this Java port of Cocos2D and noticed that the CCLayer class has built-in hooks to the Android native touch events. That's great, but what I'd really like is for objects like CCSprite to directly respond to touch events without having to listen for those events in the layer and iterate through all the children to find which ones happen to intersect the event's x/y coordinates. So I figured that this would be the perfect chance to test my understanding of how to set up some event handlers and make a subclass of CCSprite that actually listens for touches without needing to go through CCLayer to know about it. Furthermore, I wanted to be able to assign different behaviors to different CCSprite instances on an ad-hoc basis without explicitly subclassing further, much like Android Buttons don't need to be subclassed just to give them a handler for their touch events.
This is what I came up with on a first pass:
// My touch interface for all touchable CCNode objects.
package com.scriptocalypse.cocos2d;
public interface ITouchable {
boolean onCCTouchesBegan();
boolean onCCTouchesEnded();
boolean onCCTouchesMoved();
}
And now the class that uses the ITouchable interface for its callbacks...
public class CCTouchSprite extends CCSprite implements CCTouchDelegateProtocol {
protected ITouchable mTouchable;
public void setTouchable(ITouchable pTouchable){
mTouchable = pTouchable;
boolean enable = mTouchable != null;
this.setIsTouchEnabled(enable);
}
public void setIsTouchable(boolean pEnabled){
// code to enable and disable touches snipped...
}
/////
// And now implementing the CCTouchDelegateProtocol...
/////
public boolean ccTouchesBegan(MotionEvent event) {
Log.d("hi there", "touch me");
if(mTouchable != null){
mTouchable.onCCTouchesBegan();
}
return CCTouchDispatcher.kEventHandled; // TODO Auto-generated method stub
}
public boolean ccTouchesMoved(MotionEvent event) {
if(mTouchable != null){
mTouchable.onCCTouchesMoved();
}
return CCTouchDispatcher.kEventIgnored; // TODO Auto-generated method stub
}
public boolean ccTouchesEnded(MotionEvent event) {
Log.d("hi there", "not touch me");
if(mTouchable != null){
mTouchable.onCCTouchesEnded();
}
return CCTouchDispatcher.kEventIgnored; // TODO Auto-generated method stub
}
}
And finally, instantiate the class and implement the interface...
final CCTouchSprite sprite = new CCTouchSprite(tex);
sprite.setIsTouchEnabled(true);
sprite.setPosition(CGPoint.ccp(160,240));
sprite.setTouchable(new ITouchable(){
#Override
public boolean onCCTouchesBegan() {
Log.d("SWEET SUCCESS", "I got a touch through my interface!");
return true;
}
#Override
public boolean onCCTouchesEnded() {
Log.d("SWEET SUCCESS", "You stopped touching my interface!");
sprite.runAction(CCRotateBy.action(1, 360));
return false;
}
#Override
public boolean onCCTouchesMoved(){
Log.d("SWEET SUCCESS", "You moved the touch");
return false;
}
});
So all of this works. The subclass does successfully register with the Cocos2D touch dispatcher, which successfully calls those ccTouches functions and pass them MotionEvents, which in turn call my Interface functions if the interface has been instantiated.
Is this the "proper" way to do it (Define "it" as you see fit, ranging from using Interfaces to create event handlers to working with Cocos2D, to writing Java at all)? Are there drawbacks to this that I'm not aware of? Is this somehow worse for performance than iterating through all the CCNode objects that are children of CCLayer? If so, how can that possibly be?
I think you have got the basics for setting up a listener right. There are some things I would change though.
First, the setter setIsTouchable. It's weird. You need a listener object to pass touch events to right? So what is this setter going to do when you pass it true (as your example does)? You snipped the code, but setting a boolean field to true does not seem right here as it would put the sprite object in an inconsistent internal state. I would just drop that setter. The getter can just evaluate whether mTouchable is assigned or null.
Second, why limit yourself to one listener? Change mTouchable to mTouchables, being a list of ITouchables. Then change setTouchable to addTouchable and possibly add removeTouchable and clearTouchables methods. This way you can add multiple listeners for different behaviors having to respond to the same events. This is how most other event systems work as well. You then just change isTouchable to check whether the list is empty or not.
scriptoclypse... I really am not completely understanding your question, but you have not had any response and yes interfaces and events are very similar. At this level I can only respond in C#.

Categories