Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Android access to activity  (Read 3440 times)

0 Members and 1 Guest are viewing this topic.

Fizix

  • Newbie
  • *
  • Posts: 18
    • View Profile
Android access to activity
« on: July 07, 2014, 01:28:40 pm »
The Android port handles the NativeActivity interface internally and wraps everything up nicely so that you can only have a main() in your code.

All the NativeActivity stuff is stored internally, but in some cases users might want access to those to make JNI calls.  Maybe to use Google Play or Google Play Games services.  Or even just some custom libraries that exist on the Java side of things.

You can get access to all those things through one simple interface, but there are a few problems with that.

The biggest problem is that it is not part of the "public" API of SFML.  Does SFML expose platform specific calls at all?

Second issue is that generally when those pointers are accessed, they main NativeActivity thread should be locked.  So you can't just expose the pointers, because they are "owned" by the NativeActivity thread.

A general guide is to have a locking interface like this:

  sf::ActivityStates* states = NativeActivityAttachToThread();  // Locks the mutex.
  // ...make your JNI calls...
  NativeActivityDetachFromThread();

Would there be an nice enough way to add this to SFML?

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 877
    • View Profile
Re: Android access to activity
« Reply #1 on: July 07, 2014, 04:27:44 pm »
Don't think returning the whole states object would be a good idea.

What would you need to be returned? A pointer to the JNI environment?

Would probably suggest something like this:

namespace sf {
class Environment {
    // This could take other generic environment things such as accessing environment strings like PATH
    static sf::String getString(const sf::String& name, const sf::String& default);
    ...
#ifdef ANDROID
    static void* lockJNI(const char major = 1, const char minor = 6);
    static void unlockJNI();
#endif
};
}
 

Why using #ifdef rather than dummy implementations? Because I think this is a very special case. The actual function call won't do anything by itself and you'd want to use it in conjunction with other JNI/Android only calls anyway. As such the surrounding/calling code should be excluded on other platforms anyway.

Sonkun

  • Full Member
  • ***
  • Posts: 241
    • View Profile
Re: Android access to activity
« Reply #2 on: July 08, 2014, 07:26:05 pm »
Without investigating, I can't give you a proper answer explaining how things should be handled. However, until we provide a solution, your best bet is to modify SFML and forward what you need from SFMLActivity (or expose stuff you need)

Actually, several times in the past (when porting the Python bindings to Android for example) I crossed the need to have these variables accessible from main() just like you but I didn't get further and added it to the list of things I need to investigate.

As for the Environment class solution, we don't like adding API elements just to solve case specific issues. Of course if that turns out to be the only solution, we will need to convince the SFML Team. Instead I was thinking about how the JNI environment instance is forwarded to loaded libraries (via On_Load) and was thinking about something similar for SFML. But again, I need to investigate that.
Interested in using SFML with Python ? Try out its Python binding!

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 877
    • View Profile
Re: Android access to activity
« Reply #3 on: October 12, 2014, 11:27:32 am »
To quote myself from GitHub:

Quote
Thought about this a bit more. I'd say leave  sf::Window::getSystemHandle() alone and instead add a new non-class function returning a system handle for the actual process (on desktop systems) or activity (Android).

Since this is a sf::Window member, it should really only return the native handle to that particular window. However, there could be something like sf::Application::getSystemHandle() returning a pointer or handle representing the actual process. Under Windows, this could be the handle of the active instance or process, on Android it would be a pointer to the current activity.

What do you think about this?

Fizix

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Android access to activity
« Reply #4 on: October 13, 2014, 03:47:50 am »
On Android you can only have one instance of sf::Window anyway, so you can't return a handle per window even if you wanted to.

Returning the activity from sf::Window::getSystemHandle() makes sense.

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 877
    • View Profile
Re: Android access to activity
« Reply #5 on: October 13, 2014, 08:37:14 am »
But so does returning the Window handle. Or is there some way to get from activity to window again? If so, that would be another solution I guess.

Fizix

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Android access to activity
« Reply #6 on: October 13, 2014, 01:16:39 pm »
Actually the thing we are trying to get at is the ActivityStates object, and not the activity handle or the window handle.

The ActivityStates object holds all relevant data for the currently running Android app/activity, so it work to make it the equivalent of a "process handle" on other platforms.

I guess the question is just what do you return for the other platforms, if anything at all.

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 877
    • View Profile
Re: Android access to activity
« Reply #7 on: October 13, 2014, 02:48:06 pm »
I'm aware of that, but passing the whole struct is out of question right now I guess, especially considering that's all subject to change and not exposed/public so far.

Fizix

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Android access to activity
« Reply #8 on: October 14, 2014, 12:42:30 am »
I'm aware of that, but passing the whole struct is out of question right now I guess, especially considering that's all subject to change and not exposed/public so far.

What is about to change?

There isn't much you can do with a handle to the ANativeWindow*, that SFML doesn't handle already, but for completeness, I guess returning it in sf::Window::getSystemHandle would be good.

This doesn't solve the problem of getting to the Java environment and making JNI calls though, but fitting that into the public interface is a bigger problem in itself I guess.