Fix unpack resources on android

This commit is contained in:
Brad Davis 2018-01-10 13:33:43 -08:00
parent b1e95681a9
commit 10a67fd9f8

View file

@ -1,3 +1,7 @@
#include <functional>
#include <QtCore/QBuffer>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
@ -12,6 +16,8 @@
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <shared/Storage.h>
void tempMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
if (!message.isEmpty()) {
const char * local=message.toStdString().c_str();
@ -36,33 +42,65 @@ void tempMessageHandler(QtMsgType type, const QMessageLogContext& context, const
}
}
void unpackAndroidAssets() {
const QString SOURCE_PREFIX { "assets:/" };
const QString DEST_PREFIX = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/";
QStringList filesToCopy;
QString dateStamp;
{
QFile file("assets:/cache_assets.txt");
if (!file.open(QIODevice::ReadOnly)) {
throw std::runtime_error("Failed to open cache file list");
}
QTextStream in(&file);
dateStamp = DEST_PREFIX + "/" + in.readLine();
while (!in.atEnd()) {
QString line = in.readLine();
filesToCopy << line;
}
file.close();
}
qDebug() << "Checking date stamp" << dateStamp;
AAssetManager* g_assetManager = nullptr;
if (QFileInfo(dateStamp).exists()) {
void withAssetData(const char* filename, const std::function<void(off64_t, const void*)>& callback) {
auto asset = AAssetManager_open(g_assetManager, filename, AASSET_MODE_BUFFER);
if (!asset) {
throw std::runtime_error("Failed to open file");
}
auto buffer = AAsset_getBuffer(asset);
off64_t size = AAsset_getLength64(asset);
callback(size, buffer);
AAsset_close(asset);
}
QStringList readAssetLines(const char* filename) {
QStringList result;
withAssetData(filename, [&](off64_t size, const void* data){
QByteArray buffer = QByteArray::fromRawData((const char*)data, size);
{
QTextStream in(&buffer);
while (!in.atEnd()) {
QString line = in.readLine();
result << line;
}
}
});
return result;
}
void copyAsset(const char* sourceAsset, const QString& destFilename) {
withAssetData(sourceAsset, [&](off64_t size, const void* data){
QFile file(destFilename);
if (!file.open(QFile::ReadWrite | QIODevice::Truncate)) {
throw std::runtime_error("Unable to open output file for writing");
}
if (!file.resize(size)) {
throw std::runtime_error("Unable to resize output file");
}
auto mapped = file.map(0, size);
if (!mapped) {
throw std::runtime_error("Unable to map output file");
}
memcpy(mapped, data, size);
file.close();
});
}
void unpackAndroidAssets() {
const QString DEST_PREFIX = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/";
QStringList filesToCopy = readAssetLines("cache_assets.txt");
QString dateStamp = filesToCopy.takeFirst();
QString dateStampFilename = DEST_PREFIX + dateStamp;
qDebug() << "Checking date stamp" << dateStamp;
if (QFileInfo(dateStampFilename).exists()) {
return;
}
auto rootDir = QDir::root();
for (const auto& fileToCopy : filesToCopy) {
auto sourceFileName = SOURCE_PREFIX + fileToCopy;
auto destFileName = DEST_PREFIX + fileToCopy;
auto destFolder = QFileInfo(destFileName).absoluteDir();
if (!destFolder.exists()) {
@ -78,19 +116,18 @@ void unpackAndroidAssets() {
}
}
qDebug() << "Copying from" << sourceFileName << "to" << destFileName;
if (!QFile(sourceFileName).copy(destFileName)) {
throw std::runtime_error("Failed to unpack cache files");
}
qDebug() << "Copying asset " << fileToCopy << "to" << destFileName;
copyAsset(fileToCopy.toStdString().c_str(), destFileName);
}
{
qDebug() << "Writing date stamp" << dateStamp;
QFile file(dateStamp);
if (file.open(QIODevice::ReadWrite)) {
QTextStream(&file) << "touch" << endl;
file.close();
QFile file(dateStampFilename);
if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
throw std::runtime_error("Can't write date stamp");
}
QTextStream(&file) << "touch" << endl;
file.close();
}
}
@ -98,6 +135,7 @@ extern "C" {
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnCreate(JNIEnv* env, jobject obj, jobject instance, jobject asset_mgr) {
qDebug() << "nativeOnCreate On thread " << QThread::currentThreadId();
g_assetManager = AAssetManager_fromJava(env, asset_mgr);
auto oldMessageHandler = qInstallMessageHandler(tempMessageHandler);
unpackAndroidAssets();
qInstallMessageHandler(oldMessageHandler);