Android: Use APK assets for HostInterface::OpenPackagePath
This commit is contained in:
parent
feadc83050
commit
12caa79178
|
@ -35,6 +35,7 @@ static jmethodID s_AndroidHostInterface_constructor;
|
|||
static jfieldID s_AndroidHostInterface_field_mNativePointer;
|
||||
static jmethodID s_AndroidHostInterface_method_reportError;
|
||||
static jmethodID s_AndroidHostInterface_method_reportMessage;
|
||||
static jmethodID s_AndroidHostInterface_method_openAssetStream;
|
||||
static jmethodID s_EmulationActivity_method_reportError;
|
||||
static jmethodID s_EmulationActivity_method_reportMessage;
|
||||
static jmethodID s_EmulationActivity_method_onEmulationStarted;
|
||||
|
@ -78,6 +79,36 @@ std::string JStringToString(JNIEnv* env, jstring str)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<GrowableMemoryByteStream> ReadInputStreamToMemory(JNIEnv* env, jobject obj, u32 chunk_size/* = 65536*/)
|
||||
{
|
||||
std::unique_ptr<GrowableMemoryByteStream> bs = std::make_unique<GrowableMemoryByteStream>(nullptr, 0);
|
||||
u32 position = 0;
|
||||
|
||||
jclass cls = env->GetObjectClass(obj);
|
||||
jmethodID read_method = env->GetMethodID(cls, "read", "([B)I");
|
||||
Assert(read_method);
|
||||
|
||||
jbyteArray temp = env->NewByteArray(chunk_size);
|
||||
for (;;)
|
||||
{
|
||||
int bytes_read = env->CallIntMethod(obj, read_method, temp);
|
||||
if (bytes_read <= 0)
|
||||
break;
|
||||
|
||||
if ((position + static_cast<u32>(bytes_read)) > bs->GetMemorySize())
|
||||
{
|
||||
const u32 new_size = std::max<u32>(bs->GetMemorySize() * 2, position + static_cast<u32>(bytes_read));
|
||||
bs->ResizeMemory(new_size);
|
||||
}
|
||||
|
||||
env->GetByteArrayRegion(temp, 0, bytes_read, reinterpret_cast<jbyte*>(bs->GetMemoryPointer() + position));
|
||||
position += static_cast<u32>(bytes_read);
|
||||
}
|
||||
|
||||
bs->Resize(position);
|
||||
return bs;
|
||||
}
|
||||
} // namespace AndroidHelpers
|
||||
|
||||
AndroidHostInterface::AndroidHostInterface(jobject java_object, jobject context_object, std::string user_directory)
|
||||
|
@ -159,6 +190,23 @@ float AndroidHostInterface::GetFloatSettingValue(const char* section, const char
|
|||
return m_settings_interface.GetFloatValue(section, key, default_value);
|
||||
}
|
||||
|
||||
std::unique_ptr<ByteStream> AndroidHostInterface::OpenPackageFile(const char *path, u32 flags)
|
||||
{
|
||||
Log_DevPrintf("OpenPackageFile(%s, %x)", path, flags);
|
||||
if (flags & (BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_WRITE))
|
||||
return {};
|
||||
|
||||
JNIEnv* env = AndroidHelpers::GetJNIEnv();
|
||||
jobject stream = env->CallObjectMethod(m_java_object, s_AndroidHostInterface_method_openAssetStream, env->NewStringUTF(path));
|
||||
if (!stream)
|
||||
{
|
||||
Log_ErrorPrintf("Package file '%s' not found", path);
|
||||
return {};
|
||||
}
|
||||
|
||||
return AndroidHelpers::ReadInputStreamToMemory(env, stream, 65536);
|
||||
}
|
||||
|
||||
void AndroidHostInterface::SetUserDirectory()
|
||||
{
|
||||
// Already set in constructor.
|
||||
|
@ -707,6 +755,8 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||
env->GetMethodID(s_AndroidHostInterface_class, "reportError", "(Ljava/lang/String;)V")) == nullptr ||
|
||||
(s_AndroidHostInterface_method_reportMessage =
|
||||
env->GetMethodID(s_AndroidHostInterface_class, "reportMessage", "(Ljava/lang/String;)V")) == nullptr ||
|
||||
(s_AndroidHostInterface_method_openAssetStream =
|
||||
env->GetMethodID(s_AndroidHostInterface_class, "openAssetStream", "(Ljava/lang/String;)Ljava/io/InputStream;")) == nullptr ||
|
||||
(emulation_activity_class = env->FindClass("com/github/stenzek/duckstation/EmulationActivity")) == nullptr ||
|
||||
(s_EmulationActivity_method_reportError =
|
||||
env->GetMethodID(emulation_activity_class, "reportError", "(Ljava/lang/String;)V")) == nullptr ||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "android_settings_interface.h"
|
||||
#include "common/event.h"
|
||||
#include "common/progress_callback.h"
|
||||
#include "common/byte_stream.h"
|
||||
#include "frontend-common/common_host_interface.h"
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
|
@ -35,6 +36,7 @@ public:
|
|||
bool GetBoolSettingValue(const char* section, const char* key, bool default_value = false) override;
|
||||
int GetIntSettingValue(const char* section, const char* key, int default_value = 0) override;
|
||||
float GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f) override;
|
||||
std::unique_ptr<ByteStream> OpenPackageFile(const char* path, u32 flags) override;
|
||||
|
||||
bool IsEmulationThreadRunning() const { return m_emulation_thread.joinable(); }
|
||||
bool IsEmulationThreadPaused() const;
|
||||
|
@ -105,4 +107,5 @@ namespace AndroidHelpers {
|
|||
JNIEnv* GetJNIEnv();
|
||||
AndroidHostInterface* GetNativeClass(JNIEnv* env, jobject obj);
|
||||
std::string JStringToString(JNIEnv* env, jstring str);
|
||||
std::unique_ptr<GrowableMemoryByteStream> ReadInputStreamToMemory(JNIEnv* env, jobject obj, u32 chunk_size = 65536);
|
||||
} // namespace AndroidHelpers
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package com.github.stenzek.duckstation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class AndroidHostInterface {
|
||||
public final static int DISPLAY_ALIGNMENT_TOP_OR_LEFT = 0;
|
||||
public final static int DISPLAY_ALIGNMENT_CENTER = 1;
|
||||
|
@ -30,6 +34,14 @@ public class AndroidHostInterface {
|
|||
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
public InputStream openAssetStream(String path) {
|
||||
try {
|
||||
return mContext.getAssets().open(path, AssetManager.ACCESS_STREAMING);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public native boolean isEmulationThreadRunning();
|
||||
|
||||
public native boolean startEmulationThread(EmulationActivity emulationActivity, Surface surface, String filename, boolean resumeState, String state_filename);
|
||||
|
|
Loading…
Reference in New Issue