Android: Extract data for native style on startup
When Ministro is not in use, we need to extract style information on startup in order for the native Android style to work. The code to extract data from the device is contributed from the Ministro project. [ChangeLog][Android] Enable using native style also when Ministro deployment mechanism is not in use. Task-number: QTBUG-36019 Change-Id: I2afef5219b4e8fbb2f3e387cbc5e570da1f41011 Reviewed-by: BogDan Vatra <bogdan@kde.org> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>bb10
parent
00470662e3
commit
09ed9e3eae
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EXTRACT_H
|
||||
#define EXTRACT_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
// shamelessly stolen from ResourceTypes.h Android's sources
|
||||
/**
|
||||
* This chunk specifies how to split an image into segments for
|
||||
* scaling.
|
||||
*
|
||||
* There are J horizontal and K vertical segments. These segments divide
|
||||
* the image into J*K regions as follows (where J=4 and K=3):
|
||||
*
|
||||
* F0 S0 F1 S1
|
||||
* +-----+----+------+-------+
|
||||
* S2| 0 | 1 | 2 | 3 |
|
||||
* +-----+----+------+-------+
|
||||
* | | | | |
|
||||
* | | | | |
|
||||
* F2| 4 | 5 | 6 | 7 |
|
||||
* | | | | |
|
||||
* | | | | |
|
||||
* +-----+----+------+-------+
|
||||
* S3| 8 | 9 | 10 | 11 |
|
||||
* +-----+----+------+-------+
|
||||
*
|
||||
* Each horizontal and vertical segment is considered to by either
|
||||
* stretchable (marked by the Sx labels) or fixed (marked by the Fy
|
||||
* labels), in the horizontal or vertical axis, respectively. In the
|
||||
* above example, the first is horizontal segment (F0) is fixed, the
|
||||
* next is stretchable and then they continue to alternate. Note that
|
||||
* the segment list for each axis can begin or end with a stretchable
|
||||
* or fixed segment.
|
||||
*
|
||||
* The relative sizes of the stretchy segments indicates the relative
|
||||
* amount of stretchiness of the regions bordered by the segments. For
|
||||
* example, regions 3, 7 and 11 above will take up more horizontal space
|
||||
* than regions 1, 5 and 9 since the horizontal segment associated with
|
||||
* the first set of regions is larger than the other set of regions. The
|
||||
* ratios of the amount of horizontal (or vertical) space taken by any
|
||||
* two stretchable slices is exactly the ratio of their corresponding
|
||||
* segment lengths.
|
||||
*
|
||||
* xDivs and yDivs point to arrays of horizontal and vertical pixel
|
||||
* indices. The first pair of Divs (in either array) indicate the
|
||||
* starting and ending points of the first stretchable segment in that
|
||||
* axis. The next pair specifies the next stretchable segment, etc. So
|
||||
* in the above example xDiv[0] and xDiv[1] specify the horizontal
|
||||
* coordinates for the regions labeled 1, 5 and 9. xDiv[2] and
|
||||
* xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that
|
||||
* the leftmost slices always start at x=0 and the rightmost slices
|
||||
* always end at the end of the image. So, for example, the regions 0,
|
||||
* 4 and 8 (which are fixed along the X axis) start at x value 0 and
|
||||
* go to xDiv[0] and slices 2, 6 and 10 start at xDiv[1] and end at
|
||||
* xDiv[2].
|
||||
*
|
||||
* The array pointed to by the colors field lists contains hints for
|
||||
* each of the regions. They are ordered according left-to-right and
|
||||
* top-to-bottom as indicated above. For each segment that is a solid
|
||||
* color the array entry will contain that color value; otherwise it
|
||||
* will contain NO_COLOR. Segments that are completely transparent
|
||||
* will always have the value TRANSPARENT_COLOR.
|
||||
*
|
||||
* The PNG chunk type is "npTc".
|
||||
*/
|
||||
struct Res_png_9patch
|
||||
{
|
||||
Res_png_9patch() : wasDeserialized(false), xDivs(NULL),
|
||||
yDivs(NULL), colors(NULL) { }
|
||||
|
||||
int8_t wasDeserialized;
|
||||
int8_t numXDivs;
|
||||
int8_t numYDivs;
|
||||
int8_t numColors;
|
||||
|
||||
// These tell where the next section of a patch starts.
|
||||
// For example, the first patch includes the pixels from
|
||||
// 0 to xDivs[0]-1 and the second patch includes the pixels
|
||||
// from xDivs[0] to xDivs[1]-1.
|
||||
// Note: allocation/free of these pointers is left to the caller.
|
||||
int32_t* xDivs;
|
||||
int32_t* yDivs;
|
||||
|
||||
int32_t paddingLeft, paddingRight;
|
||||
int32_t paddingTop, paddingBottom;
|
||||
|
||||
enum {
|
||||
// The 9 patch segment is not a solid color.
|
||||
NO_COLOR = 0x00000001,
|
||||
|
||||
// The 9 patch segment is completely transparent.
|
||||
TRANSPARENT_COLOR = 0x00000000
|
||||
};
|
||||
// Note: allocation/free of this pointer is left to the caller.
|
||||
uint32_t* colors;
|
||||
|
||||
// Deserialize/Unmarshall the patch data
|
||||
static Res_png_9patch* deserialize(const void* data);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -12,7 +12,8 @@ JAVASOURCES += \
|
|||
$$PATHPREFIX/QtMessageDialogHelper.java \
|
||||
$$PATHPREFIX/QtNative.java \
|
||||
$$PATHPREFIX/QtNativeLibrariesDir.java \
|
||||
$$PATHPREFIX/QtSurface.java
|
||||
$$PATHPREFIX/QtSurface.java \
|
||||
$$PATHPREFIX/ExtractStyle.java
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_PREFIX]/jar
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -99,6 +99,7 @@ public class QtActivityDelegate
|
|||
private static final String APPLICATION_PARAMETERS_KEY = "application.parameters";
|
||||
private static final String STATIC_INIT_CLASSES_KEY = "static.init.classes";
|
||||
private static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level";
|
||||
private static final String EXTRACT_STYLE_KEY = "extract.android.style";
|
||||
|
||||
private static String m_environmentVariables = null;
|
||||
private static String m_applicationParameters = null;
|
||||
|
|
@ -426,6 +427,11 @@ public class QtActivityDelegate
|
|||
if (null == m_mainLib && libraries.size() > 0)
|
||||
m_mainLib = libraries.get(libraries.size() - 1);
|
||||
|
||||
if (loaderParams.containsKey(EXTRACT_STYLE_KEY)) {
|
||||
String path = loaderParams.getString(EXTRACT_STYLE_KEY);
|
||||
new ExtractStyle(m_activity, path);
|
||||
}
|
||||
|
||||
try {
|
||||
m_super_dispatchKeyEvent = m_activity.getClass().getMethod("super_dispatchKeyEvent", KeyEvent.class);
|
||||
m_super_onRestoreInstanceState = m_activity.getClass().getMethod("super_onRestoreInstanceState", Bundle.class);
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ public class QtActivity extends Activity
|
|||
private static final String MAIN_LIBRARY_KEY = "main.library";
|
||||
private static final String STATIC_INIT_CLASSES_KEY = "static.init.classes";
|
||||
private static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level";
|
||||
private static final String EXTRACT_STYLE_KEY = "extract.android.style";
|
||||
|
||||
/// Ministro server parameter keys
|
||||
private static final String REQUIRED_MODULES_KEY = "required.modules";
|
||||
|
|
@ -177,6 +178,7 @@ public class QtActivity extends Activity
|
|||
// * unstable - unstable repository, DO NOT use this repository in production,
|
||||
// this repository is used to push Qt snapshots.
|
||||
private String[] m_qtLibs = null; // required qt libs
|
||||
private int m_displayDensity = -1;
|
||||
|
||||
public QtActivity()
|
||||
{
|
||||
|
|
@ -629,6 +631,17 @@ public class QtActivity extends Activity
|
|||
m_activityInfo.metaData.getString("android.app.static_init_classes").split(":"));
|
||||
}
|
||||
loaderParams.putStringArrayList(NATIVE_LIBRARIES_KEY, libraryList);
|
||||
|
||||
|
||||
if (bundlingQtLibs) {
|
||||
String themePath = pluginsPrefix + "android-style/";
|
||||
String stylePath = themePath + m_displayDensity + "/";
|
||||
if (!(new File(stylePath)).exists())
|
||||
loaderParams.putString(EXTRACT_STYLE_KEY, stylePath);
|
||||
ENVIRONMENT_VARIABLES += "\tMINISTRO_ANDROID_STYLE_PATH=" + stylePath
|
||||
+ "\tQT_ANDROID_THEMES_ROOT_PATH=" + themePath;
|
||||
}
|
||||
|
||||
loaderParams.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES
|
||||
+ "\tQML2_IMPORT_PATH=" + pluginsPrefix + "/qml"
|
||||
+ "\tQML_IMPORT_PATH=" + pluginsPrefix + "/imports"
|
||||
|
|
@ -867,8 +880,10 @@ public class QtActivity extends Activity
|
|||
return;
|
||||
}
|
||||
|
||||
m_displayDensity = getResources().getDisplayMetrics().densityDpi;
|
||||
|
||||
ENVIRONMENT_VARIABLES += "\tQT_ANDROID_THEME=" + QT_ANDROID_DEFAULT_THEME
|
||||
+ "/\tQT_ANDROID_THEME_DISPLAY_DPI=" + getResources().getDisplayMetrics().densityDpi + "\t";
|
||||
+ "/\tQT_ANDROID_THEME_DISPLAY_DPI=" + m_displayDensity + "\t";
|
||||
|
||||
if (null == getLastNonConfigurationInstance()) {
|
||||
// if splash screen is defined, then show it
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ CONFIG += qpa/genericunixfontdatabase
|
|||
|
||||
OTHER_FILES += $$PWD/android.json
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
INCLUDEPATH += \
|
||||
$$PWD \
|
||||
$$QT_SOURCE_TREE/src/3rdparty/android
|
||||
|
||||
SOURCES += $$PWD/androidplatformplugin.cpp \
|
||||
$$PWD/androidjnimain.cpp \
|
||||
|
|
@ -48,7 +50,8 @@ SOURCES += $$PWD/androidplatformplugin.cpp \
|
|||
$$PWD/qandroidplatformrasterwindow.cpp \
|
||||
$$PWD/qandroidplatformbackingstore.cpp \
|
||||
$$PWD/qandroidplatformopenglcontext.cpp \
|
||||
$$PWD/qandroidplatformforeignwindow.cpp
|
||||
$$PWD/qandroidplatformforeignwindow.cpp \
|
||||
$$PWD/extract.cpp
|
||||
|
||||
HEADERS += $$PWD/qandroidplatformintegration.h \
|
||||
$$PWD/androidjnimain.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include <extract.h>
|
||||
#include <alloca.h>
|
||||
|
||||
#define LOG_TAG "extractSyleInfo"
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
|
||||
|
||||
extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(JNIEnv * env, jobject, Res_png_9patch* chunk)
|
||||
{
|
||||
Res_png_9patch::deserialize(chunk);
|
||||
//printChunkInformation(chunk);
|
||||
jintArray result;
|
||||
size_t size = 3+chunk->numXDivs+chunk->numYDivs+chunk->numColors;
|
||||
result = env->NewIntArray(size);
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
jint *data = (jint*)malloc(sizeof(jint)*size);
|
||||
size_t pos = 0;
|
||||
data[pos++]=chunk->numXDivs;
|
||||
data[pos++]=chunk->numYDivs;
|
||||
data[pos++]=chunk->numColors;
|
||||
for (int x = 0; x <chunk->numXDivs; x ++)
|
||||
data[pos++]=chunk->xDivs[x];
|
||||
for (int y = 0; y <chunk->numYDivs; y ++)
|
||||
data[pos++]=chunk->yDivs[y];
|
||||
for (int c = 0; c <chunk->numColors; c ++)
|
||||
data[pos++]=chunk->colors[c];
|
||||
env->SetIntArrayRegion(result, 0, size, data);
|
||||
free(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractChunkInfo(JNIEnv * env, jobject obj, jbyteArray chunkObj)
|
||||
{
|
||||
size_t chunkSize = env->GetArrayLength(chunkObj);
|
||||
void* storage = alloca(chunkSize);
|
||||
env->GetByteArrayRegion(chunkObj, 0, chunkSize,
|
||||
reinterpret_cast<jbyte*>(storage));
|
||||
|
||||
if (!env->ExceptionCheck())
|
||||
return Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(env, obj, static_cast<Res_png_9patch*>(storage));
|
||||
else
|
||||
env->ExceptionClear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The following part was shamelessly stolen from ResourceTypes.cpp from Android's sources
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
static void deserializeInternal(const void* inData, Res_png_9patch* outData) {
|
||||
char* patch = (char*) inData;
|
||||
if (inData != outData) {
|
||||
memmove(&outData->wasDeserialized, patch, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors
|
||||
memmove(&outData->paddingLeft, patch + 12, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors
|
||||
}
|
||||
outData->wasDeserialized = true;
|
||||
char* data = (char*)outData;
|
||||
data += sizeof(Res_png_9patch);
|
||||
outData->xDivs = (int32_t*) data;
|
||||
data += outData->numXDivs * sizeof(int32_t);
|
||||
outData->yDivs = (int32_t*) data;
|
||||
data += outData->numYDivs * sizeof(int32_t);
|
||||
outData->colors = (uint32_t*) data;
|
||||
}
|
||||
|
||||
Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
|
||||
{
|
||||
if (sizeof(void*) != sizeof(int32_t)) {
|
||||
LOGE("Cannot deserialize on non 32-bit system\n");
|
||||
return NULL;
|
||||
}
|
||||
deserializeInternal(inData, (Res_png_9patch*) inData);
|
||||
return (Res_png_9patch*) inData;
|
||||
}
|
||||
Loading…
Reference in New Issue