Handle damage tracking and redrawing properly in the "desktop" Android app
In the damaged() method do a callback up to Java code in Desktop that invalidates the view. For now store the view in a static field, but need to do that in a cleaner way eventually. There might in some circumstancest be several instances of the Desktop activity present. Obviously should also run just one LO thread. Get rid of the temporary self-invalidattion in onDraw() silliness. Start the LO thread that runs soffice_main() from Java, not from native code. Apparently only threads created from Java have proper class loaders in Android. No need for an own DoReleaseYield() in AndroidSalInstance, the one in the SvpSalInstance base class does what needs to be done. Change-Id: I4cb85b352fca1f1375f726620ec8c93d2047f113
This commit is contained in:
parent
8ba203c726
commit
0ce2d740a2
5 changed files with 88 additions and 44 deletions
|
@ -112,10 +112,11 @@ lo_get_libmap(void)
|
|||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// We need to pull these in, too, as they aren't in any of the libs we
|
||||
// link with -Wl,--whole-archive.
|
||||
extern void Java_org_libreoffice_experimental_desktop_Desktop_spawnMain();
|
||||
volatile void *p = (void *) Java_org_libreoffice_experimental_desktop_Desktop_spawnMain;
|
||||
// Guard against possible function-level link-time pruning of
|
||||
// "unused" code. We need to pull these in, too, as they aren't in
|
||||
// any of the libs we link with -Wl,--whole-archive. Is this necessary?
|
||||
extern void Java_org_libreoffice_experimental_desktop_Desktop_runMain();
|
||||
volatile void *p = (void *) Java_org_libreoffice_experimental_desktop_Desktop_runMain;
|
||||
|
||||
extern void Java_org_libreoffice_experimental_desktop_Desktop_renderVCL();
|
||||
p = (void *) Java_org_libreoffice_experimental_desktop_Desktop_renderVCL;
|
||||
|
|
|
@ -41,10 +41,10 @@ public class Desktop
|
|||
{
|
||||
private static final String TAG = "LODesktop";
|
||||
|
||||
/* implementend by desktop */
|
||||
private static native void spawnMain();
|
||||
/* In desktop */
|
||||
private static native void runMain();
|
||||
|
||||
/* implementend by vcl */
|
||||
/* In vcl */
|
||||
public static native void renderVCL(Bitmap bitmap);
|
||||
public static native void setViewSize(int width, int height);
|
||||
public static native void key(char c);
|
||||
|
@ -70,6 +70,28 @@ public class Desktop
|
|||
Bootstrap.putenv("SAL_LOG=+WARN+INFO");
|
||||
}
|
||||
|
||||
// This sucks, we need to experiment and think, can an app process
|
||||
// have several instances of this Activity active?
|
||||
static BitmapView theView;
|
||||
|
||||
// This is called back from LO in the LO thread
|
||||
static public void callbackDamaged()
|
||||
{
|
||||
synchronized (theView) {
|
||||
if (!invalidatePosted)
|
||||
theView.post(new Runnable() {
|
||||
@Override public void run() {
|
||||
synchronized (theView) {
|
||||
theView.invalidate();
|
||||
invalidatePosted = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
invalidatePosted = true;
|
||||
}
|
||||
}
|
||||
static boolean invalidatePosted;
|
||||
|
||||
@Override public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -111,9 +133,22 @@ public class Desktop
|
|||
initBootstrapContext();
|
||||
|
||||
Log.i(TAG, "onCreate - set content view");
|
||||
setContentView(new BitmapView());
|
||||
theView = new BitmapView();
|
||||
setContentView(theView);
|
||||
|
||||
spawnMain();
|
||||
// Start a Java thread to run soffice_main(). We don't
|
||||
// want to start the thread from native code becauce
|
||||
// native threads apparently have no Java class loaders in
|
||||
// Android, or someghin. So for instance FindClass fails.
|
||||
|
||||
// See https://groups.google.com/group/android-ndk/msg/a0793f009e6e71f7?dmode=source
|
||||
// .
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override public void run() {
|
||||
runMain();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace(System.err);
|
||||
|
@ -199,9 +234,6 @@ public class Desktop
|
|||
canvas.drawBitmap(mBitmap, 0, 0, null);
|
||||
canvas.restore();
|
||||
renderedOnce = true;
|
||||
|
||||
// re-call ourselves a bit later ...
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override public boolean onKeyDown(int keyCode, KeyEvent event)
|
||||
|
@ -302,6 +334,7 @@ public class Desktop
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim:set shiftwidth=4 softtabstop=4 expandtab:
|
||||
|
|
|
@ -91,27 +91,19 @@ extern "C" int DESKTOP_DLLPUBLIC soffice_main()
|
|||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
class MainThread : public salhelper::Thread
|
||||
{
|
||||
public:
|
||||
MainThread() : salhelper::Thread("vcl-mainloop") { launch(); }
|
||||
virtual void execute()
|
||||
{
|
||||
int nRet;
|
||||
do {
|
||||
nRet = soffice_main();
|
||||
LOGI("soffice_main returned %d", nRet );
|
||||
} while (nRet == 81 || nRet == 79); // pretend to re-start.
|
||||
exit (nRet);
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" SAL_JNI_EXPORT void JNICALL
|
||||
Java_org_libreoffice_experimental_desktop_Desktop_spawnMain(JNIEnv* /* env */,
|
||||
jobject /* dummy */)
|
||||
Java_org_libreoffice_experimental_desktop_Desktop_runMain(JNIEnv* /* env */,
|
||||
jobject /* clazz */)
|
||||
{
|
||||
new MainThread();
|
||||
int nRet;
|
||||
do {
|
||||
nRet = soffice_main();
|
||||
LOGI("soffice_main returned %d", nRet );
|
||||
} while (nRet == 81 || nRet == 79); // pretend to re-start.
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOGTAG, __VA_ARGS__))
|
||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOGTAG, __VA_ARGS__))
|
||||
|
||||
static bool bHitIdle = false;
|
||||
|
||||
// Horrible hack
|
||||
static int viewWidth = 1, viewHeight = 1;
|
||||
|
||||
|
@ -305,13 +303,15 @@ void AndroidSalInstance::RedrawWindows(ANativeWindow *pWindow, ANativeWindow_Buf
|
|||
|
||||
if (pBuffer && pWindow)
|
||||
ANativeWindow_unlockAndPost(pWindow);
|
||||
|
||||
mbQueueReDraw = false;
|
||||
}
|
||||
|
||||
void AndroidSalInstance::damaged(AndroidSalFrame */* frame */)
|
||||
{
|
||||
mbQueueReDraw = true;
|
||||
// Call the Java layer to post an invalidate if necessary
|
||||
// static public void org.libreoffice.experimental.desktop.Desktop.callbackDamaged();
|
||||
|
||||
if (m_nDesktopClass != 0 && m_nCallbackDamaged != 0)
|
||||
m_pJNIEnv->CallStaticVoidMethod(m_nDesktopClass, m_nCallbackDamaged);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -583,8 +583,19 @@ extern "C" {
|
|||
|
||||
AndroidSalInstance::AndroidSalInstance( SalYieldMutex *pMutex )
|
||||
: SvpSalInstance( pMutex )
|
||||
, mbQueueReDraw( false )
|
||||
{
|
||||
int res = (lo_get_javavm())->AttachCurrentThread(&m_pJNIEnv, NULL);
|
||||
LOGI("AttachCurrentThread res=%d env=%p", res, m_pJNIEnv);
|
||||
|
||||
m_nDesktopClass = m_pJNIEnv->FindClass("org/libreoffice/experimental/desktop/Desktop");
|
||||
if (m_nDesktopClass == 0)
|
||||
LOGE("Could not find Desktop class");
|
||||
else {
|
||||
m_nCallbackDamaged = m_pJNIEnv->GetStaticMethodID(m_nDesktopClass, "callbackDamaged", "()V");
|
||||
if (m_nCallbackDamaged == 0)
|
||||
LOGE("Could not find the callbackDamaged method");
|
||||
}
|
||||
|
||||
LOGI("created Android Sal Instance thread: %d",
|
||||
(int)pthread_self());
|
||||
}
|
||||
|
@ -600,6 +611,8 @@ void AndroidSalInstance::Wakeup()
|
|||
LOGI("busted - no global looper");
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void AndroidSalInstance::DoReleaseYield (int nTimeoutMS)
|
||||
{
|
||||
if (!bHitIdle)
|
||||
|
@ -655,6 +668,8 @@ void AndroidSalInstance::DoReleaseYield (int nTimeoutMS)
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool AndroidSalInstance::AnyInput( sal_uInt16 nType )
|
||||
{
|
||||
if( (nType & VCL_INPUT_TIMER) != 0 )
|
||||
|
@ -847,9 +862,6 @@ Java_org_libreoffice_experimental_desktop_Desktop_renderVCL(JNIEnv *env,
|
|||
jobject /* clazz */,
|
||||
jobject bitmap)
|
||||
{
|
||||
if (!bHitIdle)
|
||||
return;
|
||||
|
||||
AndroidBitmapInfo info;
|
||||
void* pixels;
|
||||
int ret;
|
||||
|
|
|
@ -30,9 +30,7 @@
|
|||
#ifndef ANDROID_SALINST_H
|
||||
#define ANDROID_SALINST_H
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/input.h>
|
||||
#include <android/native_window.h>
|
||||
#include <headless/svpinst.hxx>
|
||||
|
@ -43,6 +41,17 @@ class AndroidSalInstance : public SvpSalInstance
|
|||
{
|
||||
void BlitFrameToWindow(ANativeWindow_Buffer *pOutBuffer,
|
||||
const basebmp::BitmapDeviceSharedPtr& aDev);
|
||||
|
||||
// This JNIEnv is valid only in the thread where this
|
||||
// AndroidSalInstance object is created, which is the "LO" thread
|
||||
// in which soffice_main() runs
|
||||
JNIEnv *m_pJNIEnv;
|
||||
|
||||
// The Desktop class
|
||||
jclass m_nDesktopClass;
|
||||
|
||||
jmethodID m_nCallbackDamaged;
|
||||
|
||||
public:
|
||||
AndroidSalInstance( SalYieldMutex *pMutex );
|
||||
virtual ~AndroidSalInstance();
|
||||
|
@ -66,9 +75,6 @@ public:
|
|||
SalFrame *getFocusFrame() const;
|
||||
|
||||
void damaged(AndroidSalFrame *frame);
|
||||
protected:
|
||||
virtual void DoReleaseYield( int nTimeoutMS );
|
||||
bool mbQueueReDraw;
|
||||
};
|
||||
|
||||
#endif // ANDROID_SALINST_H
|
||||
|
|
Loading…
Reference in a new issue