Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Beginning of Android intents handling #2276

Merged
merged 5 commits into from

3 participants

@theuni
Owner

I'm headed out of town, so I figured I'd go ahead and get some eyes on this and let some people start playing with it.

This is the start of cleanly handling intents on Android, so we can avoid a huge mess of jni as we start to do more.

Here, we add a new bridge that lets us call native from Java, which is much cleaner for more android-y interfaces like listeners and broadcasters.

Next step is to add functionality for waiting on messages, callbacks, etc, and to remove our jni code for sending intents in favor of adding it here.

Cory Fields added some commits
Cory Fields intents: Add a java class for listening to intent broadcasts 0330d13
Cory Fields intents: hook up a JNI_OnLoad for finding our java functions
This should be extended to do lots more, so that we can quickly add java code
and access it from native, without the mess that is jni.
d76fff5
@Montellese
Owner

Looks good AFAICT (apart from the whoopsies you mentioned yourself). Looks like we won't make it much further without some additional Java code.

@theuni theuni referenced this pull request from a commit in mcrosson/xbmc
Mike C [droid] Hide action bar during video playback c8b504e
@theuni theuni was assigned
Cory Fields added some commits
Cory Fields intents: add the very beginnings of an intents class
Implemented as a singleton, this will eventually have functions for setting up
receivers, callbacks, etc. Also, our broadcasting can move into here, to clean
up some of the mess in XBMCApp.
7672948
Cory Fields intents: Hook up our intents listener
For now, all it does is prints to the log
b23faf5
Cory Fields intents: add a sample listener for sdcard insert events 45d742f
@theuni theuni merged commit aae7f2d into xbmc:master
@theuni theuni deleted the theuni:intents branch
@koying
Collaborator

Isn't there a flaw in that we are bypassing initial caching/checking in "Splash"?
I.e. everything we might do in CAndroidIntents::ReceiveIntent is not guaranteed to happen on an initialized nor checked XBMC...

@theuni
Owner

By the time we land in JNI_Onload, libxbmc.so has been loaded and ctors have been called.

It is possible to receive an event before XBMC has actually started its loop, but that's a good thing, because we want to be able to block that until some intents (mount) are received anyway.

@koying
Collaborator

Sorry if I wasn't clear.
I meant we could receive a broadcast intent before having been thru the Splash at least once, so the caching wouldn't have happened. Or is it not a problem?

@koying koying commented on the diff
xbmc/android/activity/Intents.cpp
((27 lines not shown))
+
+void CAndroidIntents::ReceiveIntent(JNIEnv *env, const jobject &intent)
+{
+ std::string action = GetIntentAction(intent);
+ CLog::Log(LOGDEBUG,"CAndroidIntents::ReceiveIntent: %s", action.c_str());
+}
+
+std::string CAndroidIntents::GetIntentAction(const jobject &intent)
+{
+ std::string action;
+ JNIEnv *env;
+
+ if (!intent)
+ return "";
+
+ CXBMCApp::AttachCurrentThread(&env, NULL);
@koying Collaborator
koying added a note

Do we need this? Is the "env" from CAndroidIntents::ReceiveIntent invalid?

@theuni Owner
theuni added a note

See #2319

I had to do these in steps to keep everything compiling, that one's the last in the series. Will pull it later today.

But to answer your question, we can't assume they're the same. The classloader in the env can vary based on where it comes from, I plan to abstract that away a bit in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@theuni
Owner

Not a problem, we don't load any assets 'til we jump into CApp.

@theuni theuni referenced this pull request
Merged

Android JNI Manager #2383

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 22, 2013
  1. intents: hook up a JNI_OnLoad for finding our java functions

    Cory Fields authored
    This should be extended to do lots more, so that we can quickly add java code
    and access it from native, without the mess that is jni.
Commits on Mar 1, 2013
  1. intents: add the very beginnings of an intents class

    Cory Fields authored
    Implemented as a singleton, this will eventually have functions for setting up
    receivers, callbacks, etc. Also, our broadcasting can move into here, to clean
    up some of the mess in XBMCApp.
  2. intents: Hook up our intents listener

    Cory Fields authored
    For now, all it does is prints to the log
This page is out of date. Refresh to see the latest.
View
6 tools/android/packaging/xbmc/AndroidManifest.xml
@@ -45,6 +45,12 @@
android:name="android.app.lib_name"
android:value="xbmc" />
</activity>
+ <receiver android:name="XBMCBroadcastReceiver" >
+ <intent-filter>
+ <action android:name="android.intent.action.MEDIA_MOUNTED" />
+ <data android:scheme="file"/>
+ </intent-filter>
+ </receiver>
</application>
</manifest><!-- END_INCLUDE(manifest) -->
View
24 tools/android/packaging/xbmc/src/org/xbmc/xbmc/XBMCBroadcastReceiver.java
@@ -0,0 +1,24 @@
+package org.xbmc.xbmc;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class XBMCBroadcastReceiver extends BroadcastReceiver
+{
+ native void ReceiveIntent(Intent intent);
+ static
+ {
+ System.loadLibrary("xbmc");
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent)
+ {
+ String actionName = intent.getAction();
+ if (actionName != null)
+ {
+ ReceiveIntent(intent);
+ }
+ }
+}
View
55 xbmc/android/activity/Intents.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2013 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "Intents.h"
+#include "utils/log.h"
+#include "XBMCApp.h"
+
+CAndroidIntents::CAndroidIntents()
+{
+}
+
+void CAndroidIntents::ReceiveIntent(JNIEnv *env, const jobject &intent)
+{
+ std::string action = GetIntentAction(intent);
+ CLog::Log(LOGDEBUG,"CAndroidIntents::ReceiveIntent: %s", action.c_str());
+}
+
+std::string CAndroidIntents::GetIntentAction(const jobject &intent)
+{
+ std::string action;
+ JNIEnv *env;
+
+ if (!intent)
+ return "";
+
+ CXBMCApp::AttachCurrentThread(&env, NULL);
@koying Collaborator
koying added a note

Do we need this? Is the "env" from CAndroidIntents::ReceiveIntent invalid?

@theuni Owner
theuni added a note

See #2319

I had to do these in steps to keep everything compiling, that one's the last in the series. Will pull it later today.

But to answer your question, we can't assume they're the same. The classloader in the env can vary based on where it comes from, I plan to abstract that away a bit in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ jclass cIntent = env->GetObjectClass(intent);
+
+ //action = intent.getAction()
+ jmethodID mgetAction = env->GetMethodID(cIntent, "getAction", "()Ljava/lang/String;");
+ env->DeleteLocalRef(cIntent);
+ jstring sAction = (jstring)env->CallObjectMethod(intent, mgetAction);
+ const char *nativeString = env->GetStringUTFChars(sAction, 0);
+ action = std::string(nativeString);
+
+ env->ReleaseStringUTFChars(sAction, nativeString);
+ CXBMCApp::DetachCurrentThread();
+ return action;
+}
View
35 xbmc/android/activity/Intents.h
@@ -0,0 +1,35 @@
+#pragma once
+/*
+ * Copyright (C) 2013 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <string>
+#include <jni.h>
+
+class CAndroidIntents
+{
+public:
+ void ReceiveIntent(JNIEnv *env, const jobject &intent);
+ static CAndroidIntents& getInstance() {static CAndroidIntents temp; return temp;};
+
+private:
+ CAndroidIntents();
+ CAndroidIntents(CAndroidIntents const&);
+ void operator=(CAndroidIntents const&);
+ std::string GetIntentAction(const jobject &intent);
+};
View
50 xbmc/android/activity/JNI.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <string>
+#include <jni.h>
+#include "Intents.h"
+
+extern "C"{
+
+ static void jni_ReceiveIntent(JNIEnv *env, jobject thiz, jobject intent)
+ {
+ CAndroidIntents::getInstance().ReceiveIntent(env, intent);
+ }
+
+ static JNINativeMethod jniMethods[] =
+ {
+ {"ReceiveIntent", "(Landroid/content/Intent;)V", (void*)jni_ReceiveIntent}
+ };
+
+ // This is a special function called when libxbmc is loaded. It sets up our
+ // internal functions so that we can use them in native code much more simply.
+ // It loads a array of methods, params, and function-pointers.
+ jint JNI_OnLoad(JavaVM* vm, void* reserved)
+ {
+ JNIEnv* env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ return -1;
+ }
+ jclass jniClass = env->FindClass("org/xbmc/xbmc/XBMCBroadcastReceiver");
+ env->RegisterNatives(jniClass, jniMethods, sizeof(jniMethods) / sizeof(jniMethods[0]));
+
+ return JNI_VERSION_1_6;
+ }
+}
View
2  xbmc/android/activity/Makefile.in
@@ -16,6 +16,8 @@ SRCS += AndroidMouse.cpp
SRCS += GraphicBuffer.cpp
SRCS += EventLoop.cpp
SRCS += XBMCApp.cpp
+SRCS += JNI.cpp
+SRCS += Intents.cpp
OBJS += $(APP_GLUE) $(CPU_OBJ)
View
1  xbmc/android/activity/XBMCApp.h
@@ -104,6 +104,7 @@ class CXBMCApp : public IActivityHandler
friend class CAESinkAUDIOTRACK;
friend class CAndroidFeatures;
friend class CFileAndroidApp;
+ friend class CAndroidIntents;
static int AttachCurrentThread(JNIEnv** p_env, void* thr_args = NULL);
static int DetachCurrentThread();
Something went wrong with that request. Please try again.