Small refactoring of the Android "desktop app" code, no functional change

Move the native methods out to a separate AppSupport class so that they aren't
in our "experimenal" Desktop app's namespace. Don't hardcode the name of that
class in the native code, but have the app register the class to which the
damage callbacks should be done.

Possibly the AppSupport and Bootstrap classes should be combined. Later.

Also, the "android" part of the package name is superfluous; it is
Android-specific code, no information gained by having an "android" part in
the package name.

Change-Id: Iddf55c8034ead7693887ace8438deb002c5eea9f
This commit is contained in:
Tor Lillqvist 2013-04-19 18:46:34 +03:00
parent a88ac70840
commit 07c1b61933
6 changed files with 97 additions and 72 deletions

View File

@ -0,0 +1,31 @@
// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
//
// This file is part of the LibreOffice project.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Native functions that are used by "desktop" approach apps. That means apps
// that have a "real" LibreOffice "main loop" running (headless).
package org.libreoffice.android;
import android.graphics.Bitmap;
public final class AppSupport
{
/* In desktop */
public static native void runMain();
/* In vcl */
public static native void renderVCL(Bitmap bitmap);
public static native void registerForDamageCallback(Class destinationClass);
public static native void setViewSize(int width, int height);
public static native void key(char c);
public static native void touch(int action, int x, int y);
public static native void zoom(float scale, int x, int y);
public static native void scroll(int x, int y);
}
// vim:set shiftwidth=4 softtabstop=4 expandtab:

View File

@ -151,11 +151,11 @@ lo_get_libmap(void)
// Guard against possible function-level link-time pruning of // Guard against possible function-level link-time pruning of
// "unused" code. We need to pull these in, too, as they aren't in // "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? // any of the libs we link with -Wl,--whole-archive. Is this necessary?
extern void Java_org_libreoffice_experimental_desktop_Desktop_runMain(); extern void Java_org_libreoffice_android_AppSupport_runMain();
volatile void *p = (void *) Java_org_libreoffice_experimental_desktop_Desktop_runMain; volatile void *p = (void *) Java_org_libreoffice_android_AppSupport_runMain;
extern void Java_org_libreoffice_experimental_desktop_Desktop_renderVCL(); extern void Java_org_libreoffice_android_AppSupport_renderVCL();
p = (void *) Java_org_libreoffice_experimental_desktop_Desktop_renderVCL; p = (void *) Java_org_libreoffice_android_AppSupport_renderVCL;
return map; return map;
} }

View File

@ -10,5 +10,4 @@
# Project target. # Project target.
target=android-14 target=android-14
# Use the Bootstrap class
android.library.reference.1=../../Bootstrap android.library.reference.1=../../Bootstrap

View File

@ -34,6 +34,7 @@ import android.view.inputmethod.InputMethodManager;
import com.sun.star.awt.Key; import com.sun.star.awt.Key;
import org.libreoffice.android.AppSupport;
import org.libreoffice.android.Bootstrap; import org.libreoffice.android.Bootstrap;
public class Desktop public class Desktop
@ -41,17 +42,6 @@ public class Desktop
{ {
private static final String TAG = "LODesktop"; private static final String TAG = "LODesktop";
/* In desktop */
private static native void runMain();
/* 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);
public static native void touch(int action, int x, int y);
public static native void zoom(float scale, int x, int y);
public static native void scroll(int x, int y);
/** /**
* This class contains the state that is initialized once and never changes * This class contains the state that is initialized once and never changes
* (not specific to a document or a view). * (not specific to a document or a view).
@ -142,6 +132,8 @@ public class Desktop
theView = new BitmapView(); theView = new BitmapView();
setContentView(theView); setContentView(theView);
AppSupport.registerForDamageCallback(getClass());
// Start a Java thread to run soffice_main(). We don't // Start a Java thread to run soffice_main(). We don't
// want to start the thread from native code becauce // want to start the thread from native code becauce
// native threads apparently have no Java class loaders in // native threads apparently have no Java class loaders in
@ -152,7 +144,7 @@ public class Desktop
new Thread(new Runnable() { new Thread(new Runnable() {
@Override public void run() { @Override public void run() {
runMain(); AppSupport.runMain();
} }
}).start(); }).start();
} }
@ -223,7 +215,7 @@ public class Desktop
@Override public void onScaleEnd(ScaleGestureDetector detector) @Override public void onScaleEnd(ScaleGestureDetector detector)
{ {
accumulatedScale *= detector.getScaleFactor(); accumulatedScale *= detector.getScaleFactor();
Desktop.zoom(accumulatedScale, (int) pivotX, (int) pivotY); AppSupport.zoom(accumulatedScale, (int) pivotX, (int) pivotY);
accumulatedScale = 1; accumulatedScale = 1;
pivotX = pivotY = 0; pivotX = pivotY = 0;
scalingInProgress = false; scalingInProgress = false;
@ -237,9 +229,9 @@ public class Desktop
if (mBitmap == null) { if (mBitmap == null) {
Log.i(TAG, "calling Bitmap.createBitmap(" + getWidth() + ", " + getHeight() + ", Bitmap.Config.ARGB_8888)"); Log.i(TAG, "calling Bitmap.createBitmap(" + getWidth() + ", " + getHeight() + ", Bitmap.Config.ARGB_8888)");
mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
setViewSize(getWidth(), getHeight()); AppSupport.setViewSize(getWidth(), getHeight());
} }
renderVCL(mBitmap); AppSupport.renderVCL(mBitmap);
if (scrollInProgress) { if (scrollInProgress) {
canvas.save(); canvas.save();
canvas.translate(translateX, translateY); canvas.translate(translateX, translateY);
@ -269,16 +261,16 @@ public class Desktop
case KeyEvent.KEYCODE_7: case KeyEvent.KEYCODE_7:
case KeyEvent.KEYCODE_8: case KeyEvent.KEYCODE_8:
case KeyEvent.KEYCODE_9: case KeyEvent.KEYCODE_9:
Desktop.key((char) ('0' + keyCode - KeyEvent.KEYCODE_0)); AppSupport.key((char) ('0' + keyCode - KeyEvent.KEYCODE_0));
return true; return true;
case KeyEvent.KEYCODE_DEL: case KeyEvent.KEYCODE_DEL:
Desktop.key((char) Key.BACKSPACE); AppSupport.key((char) Key.BACKSPACE);
return true; return true;
case KeyEvent.KEYCODE_ENTER: case KeyEvent.KEYCODE_ENTER:
Desktop.key((char) Key.RETURN); AppSupport.key((char) Key.RETURN);
return true; return true;
case KeyEvent.KEYCODE_TAB: case KeyEvent.KEYCODE_TAB:
Desktop.key((char) Key.TAB); AppSupport.key((char) Key.TAB);
return true; return true;
default: default:
return false; return false;
@ -301,7 +293,7 @@ public class Desktop
// the scroll must have ended. // the scroll must have ended.
if (scrollInProgress) { if (scrollInProgress) {
Desktop.scroll((int) translateX, (int) translateY); AppSupport.scroll((int) translateX, (int) translateY);
translateX = translateY = 0; translateX = translateY = 0;
scrollInProgress = false; scrollInProgress = false;
scrollJustEnded = true; scrollJustEnded = true;
@ -339,7 +331,7 @@ public class Desktop
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
Desktop.touch(event.getActionMasked(), (int) event.getX(), (int) event.getY()); AppSupport.touch(event.getActionMasked(), (int) event.getX(), (int) event.getY());
break; break;
} }
} }
@ -370,7 +362,7 @@ public class Desktop
@Override public boolean commitText(CharSequence text, int newCursorPosition) { @Override public boolean commitText(CharSequence text, int newCursorPosition) {
for (int i = 0; i < text.length(); i++) { for (int i = 0; i < text.length(); i++) {
Desktop.key(text.charAt(i)); AppSupport.key(text.charAt(i));
} }
return true; return true;
} }

View File

@ -93,8 +93,8 @@ extern "C" int DESKTOP_DLLPUBLIC soffice_main()
#ifdef ANDROID #ifdef ANDROID
extern "C" SAL_JNI_EXPORT void JNICALL extern "C" SAL_JNI_EXPORT void JNICALL
Java_org_libreoffice_experimental_desktop_Desktop_runMain(JNIEnv* /* env */, Java_org_libreoffice_android_AppSupport_runMain(JNIEnv* /* env */,
jobject /* clazz */) jobject /* clazz */)
#else #else
extern "C" extern "C"
void void

View File

@ -46,6 +46,8 @@
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOGTAG, __VA_ARGS__)) #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOGTAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOGTAG, __VA_ARGS__)) #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOGTAG, __VA_ARGS__))
static jclass appClass = 0;
// Horrible hack // Horrible hack
static int viewWidth = 1, viewHeight = 1; static int viewWidth = 1, viewHeight = 1;
@ -144,29 +146,21 @@ void AndroidSalInstance::RedrawWindows(ANativeWindow_Buffer *pBuffer)
void AndroidSalInstance::damaged(AndroidSalFrame */* frame */) void AndroidSalInstance::damaged(AndroidSalFrame */* frame */)
{ {
static bool beenHere = false; static bool beenHere = false;
static jclass nDesktopClass = 0;
static jmethodID nCallbackDamaged = 0; static jmethodID nCallbackDamaged = 0;
// Check if we are running in the experimental Desktop app // Check if we are running in an app that has registered for damage callbacks
if (!beenHere) { // static public void callbackDamaged();
nDesktopClass = m_pJNIEnv->FindClass("org/libreoffice/experimental/desktop/Desktop"); // Call the Java layer to post an invalidate if necessary
if (nDesktopClass == 0) {
LOGI("Could not find Desktop class (this is normal if this isn't the \"desktop\" app)"); if (appClass != 0 && !beenHere) {
// We don't want the exception to kill the app nCallbackDamaged = m_pJNIEnv->GetStaticMethodID(appClass, "callbackDamaged", "()V");
m_pJNIEnv->ExceptionClear(); if (nCallbackDamaged == 0)
} else { LOGE("Could not find the callbackDamaged method");
nCallbackDamaged = m_pJNIEnv->GetStaticMethodID(nDesktopClass, "callbackDamaged", "()V");
if (nCallbackDamaged == 0)
LOGE("Could not find the callbackDamaged method");
}
beenHere = true; beenHere = true;
} }
// Call the Java layer to post an invalidate if necessary if (appClass != 0 && nCallbackDamaged != 0)
// static public void org.libreoffice.experimental.desktop.Desktop.callbackDamaged(); m_pJNIEnv->CallStaticVoidMethod(appClass, nCallbackDamaged);
if (nDesktopClass != 0 && nCallbackDamaged != 0)
m_pJNIEnv->CallStaticVoidMethod(nDesktopClass, nCallbackDamaged);
} }
void AndroidSalInstance::GetWorkArea( Rectangle& rRect ) void AndroidSalInstance::GetWorkArea( Rectangle& rRect )
@ -408,9 +402,9 @@ int AndroidSalSystem::ShowNativeDialog( const OUString& rTitle,
// public static native void renderVCL(Bitmap bitmap); // public static native void renderVCL(Bitmap bitmap);
extern "C" SAL_JNI_EXPORT void JNICALL extern "C" SAL_JNI_EXPORT void JNICALL
Java_org_libreoffice_experimental_desktop_Desktop_renderVCL(JNIEnv *env, Java_org_libreoffice_android_AppSupport_renderVCL(JNIEnv *env,
jobject /* clazz */, jobject /* clazz */,
jobject bitmap) jobject bitmap)
{ {
AndroidBitmapInfo info; AndroidBitmapInfo info;
void* pixels; void* pixels;
@ -459,12 +453,21 @@ typedef struct ANativeWindow_Buffer {
AndroidBitmap_unlockPixels(env, bitmap); AndroidBitmap_unlockPixels(env, bitmap);
} }
// public static native void registerForDamageCallback(Class destinationClass);
extern "C" SAL_JNI_EXPORT void JNICALL
Java_org_libreoffice_android_AppSupport_registerForDamageCallback(JNIEnv * env,
jobject /* clazz */,
jclass destinationClass)
{
appClass = (jclass) env->NewGlobalRef(destinationClass);
}
// public static native void setViewSize(int width, int height); // public static native void setViewSize(int width, int height);
extern "C" SAL_JNI_EXPORT void JNICALL extern "C" SAL_JNI_EXPORT void JNICALL
Java_org_libreoffice_experimental_desktop_Desktop_setViewSize(JNIEnv * /* env */, Java_org_libreoffice_android_AppSupport_setViewSize(JNIEnv * /* env */,
jobject /* clazz */, jobject /* clazz */,
jint width, jint width,
jint height) jint height)
{ {
// Horrible // Horrible
viewWidth = width; viewWidth = width;
@ -473,9 +476,9 @@ Java_org_libreoffice_experimental_desktop_Desktop_setViewSize(JNIEnv * /* env */
// public static native void key(char c); // public static native void key(char c);
extern "C" SAL_JNI_EXPORT void JNICALL extern "C" SAL_JNI_EXPORT void JNICALL
Java_org_libreoffice_experimental_desktop_Desktop_key(JNIEnv * /* env */, Java_org_libreoffice_android_AppSupport_key(JNIEnv * /* env */,
jobject /* clazz */, jobject /* clazz */,
jchar c) jchar c)
{ {
SalFrame *pFocus = AndroidSalInstance::getInstance()->getFocusFrame(); SalFrame *pFocus = AndroidSalInstance::getInstance()->getFocusFrame();
if (pFocus) { if (pFocus) {
@ -489,11 +492,11 @@ Java_org_libreoffice_experimental_desktop_Desktop_key(JNIEnv * /* env */,
// public static native void touch(int action, int x, int y); // public static native void touch(int action, int x, int y);
extern "C" SAL_JNI_EXPORT void JNICALL extern "C" SAL_JNI_EXPORT void JNICALL
Java_org_libreoffice_experimental_desktop_Desktop_touch(JNIEnv * /* env */, Java_org_libreoffice_android_AppSupport_touch(JNIEnv * /* env */,
jobject /* clazz */, jobject /* clazz */,
jint action, jint action,
jint x, jint x,
jint y) jint y)
{ {
SalFrame *pFocus = AndroidSalInstance::getInstance()->getFocusFrame(); SalFrame *pFocus = AndroidSalInstance::getInstance()->getFocusFrame();
if (pFocus) { if (pFocus) {
@ -514,7 +517,7 @@ Java_org_libreoffice_experimental_desktop_Desktop_touch(JNIEnv * /* env */,
nEvent = VCLEVENT_WINDOW_MOUSEMOVE; nEvent = VCLEVENT_WINDOW_MOUSEMOVE;
break; break;
default: default:
LOGE("Java_org_libreoffice_experimental_desktop_Desktop_touch: Invalid action %d", action); LOGE("AppSupport.touch: Invalid action %d", action);
return; return;
} }
Application::PostMouseEvent(nEvent, pFocus->GetWindow(), &aEvent); Application::PostMouseEvent(nEvent, pFocus->GetWindow(), &aEvent);
@ -525,11 +528,11 @@ Java_org_libreoffice_experimental_desktop_Desktop_touch(JNIEnv * /* env */,
// public static native void zoom(float scale, int x, int y); // public static native void zoom(float scale, int x, int y);
extern "C" SAL_JNI_EXPORT void JNICALL extern "C" SAL_JNI_EXPORT void JNICALL
Java_org_libreoffice_experimental_desktop_Desktop_zoom(JNIEnv * /* env */, Java_org_libreoffice_android_AppSupport_zoom(JNIEnv * /* env */,
jobject /* clazz */, jobject /* clazz */,
jfloat scale, jfloat scale,
jint x, jint x,
jint y) jint y)
{ {
SalFrame *pFocus = AndroidSalInstance::getInstance()->getFocusFrame(); SalFrame *pFocus = AndroidSalInstance::getInstance()->getFocusFrame();
if (pFocus) { if (pFocus) {
@ -543,10 +546,10 @@ Java_org_libreoffice_experimental_desktop_Desktop_zoom(JNIEnv * /* env */,
// public static native void scroll(int x, int y); // public static native void scroll(int x, int y);
extern "C" SAL_JNI_EXPORT void JNICALL extern "C" SAL_JNI_EXPORT void JNICALL
Java_org_libreoffice_experimental_desktop_Desktop_scroll(JNIEnv * /* env */, Java_org_libreoffice_android_AppSupport_scroll(JNIEnv * /* env */,
jobject /* clazz */, jobject /* clazz */,
jint x, jint x,
jint y) jint y)
{ {
SalFrame *pFocus = AndroidSalInstance::getInstance()->getFocusFrame(); SalFrame *pFocus = AndroidSalInstance::getInstance()->getFocusFrame();
if (pFocus) { if (pFocus) {