Switched from Method-base JNI class construction to Field-base JNI class construction. Was dealing with some issues with returning a Java/Kotlin class from a C/C++ class.
This commit is contained in:
+4
-4
File diff suppressed because one or more lines are too long
@@ -22,7 +22,6 @@ android {
|
|||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
arguments "-DANDROID_STL=c++_shared", "-DANDROID=true"
|
arguments "-DANDROID_STL=c++_shared", "-DANDROID=true"
|
||||||
cppFlags "-std=c++17"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,12 +21,8 @@ set(CMAKE_CXX_STANDARD 17)
|
|||||||
# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -g -O0 -std=c++17")
|
# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -g -O0 -std=c++17")
|
||||||
# set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -std=c++17 -DNDEBUG")
|
# set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -std=c++17 -DNDEBUG")
|
||||||
|
|
||||||
set (SOURCES
|
|
||||||
Demo.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set (HEADERS
|
set (HEADERS
|
||||||
Demo.h
|
Demo.hpp
|
||||||
manager/DirectoryManager.h
|
manager/DirectoryManager.h
|
||||||
manager/Tok.h
|
manager/Tok.h
|
||||||
model/APIInfo.h
|
model/APIInfo.h
|
||||||
@@ -56,7 +52,7 @@ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/3rdparty/SQLiteCpp)
|
|||||||
|
|
||||||
|
|
||||||
add_library(native-lib SHARED
|
add_library(native-lib SHARED
|
||||||
${SOURCES}
|
Demo.cpp
|
||||||
${HEADERS}
|
${HEADERS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+1
-687
@@ -1,702 +1,16 @@
|
|||||||
//
|
//
|
||||||
// Created by brahmix on 9/26/19.
|
// Created by brahmix on 9/26/19.
|
||||||
//
|
//
|
||||||
#include "Demo.h"
|
#include "Demo.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <cstring>
|
|
||||||
#include <jni.h>
|
|
||||||
#include <string>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <sstream>
|
|
||||||
#include <vector>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <android/asset_manager_jni.h>
|
|
||||||
#include <android/log.h>
|
|
||||||
#include <android/sharedmem.h>
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include <sqlite3.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include "repository/APIRepository.h"
|
|
||||||
#include "repository/CoverArtRepository.h"
|
|
||||||
#include "repository/RepeatRepository.h"
|
|
||||||
#include "repository/ShuffleRepository.h"
|
|
||||||
#include "repository/SongRepository.h"
|
|
||||||
#include "manager/Tok.h"
|
|
||||||
#include "repository/TokenRepository.h"
|
|
||||||
#include "repository/UserRepository.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<model::Song> retrieveSongs(const model::Token& token, const std::string& baseUri)
|
|
||||||
{
|
|
||||||
std::vector<model::Song> songs;
|
|
||||||
repository::SongRepository songRepo;
|
|
||||||
|
|
||||||
return songRepo.fetchSongs(token, baseUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
jobject songToObj(JNIEnv *env, const model::Song& song)
|
|
||||||
{
|
|
||||||
jclass songClass = env->FindClass( "com/example/mear/models/Song");
|
|
||||||
jmethodID jconstructor = env->GetMethodID( songClass, "<init>", "()V" );
|
|
||||||
jobject songObj = env->NewObject( songClass, jconstructor );
|
|
||||||
|
|
||||||
jmethodID songId = env->GetMethodID( songClass, "setId", "(I)V" );
|
|
||||||
jmethodID songTitle = env->GetMethodID( songClass, "setTitle", "(Ljava/lang/String;)V" );
|
|
||||||
jmethodID songAlbum = env->GetMethodID( songClass, "setAlbum", "(Ljava/lang/String;)V" );
|
|
||||||
jmethodID songAlbumArtist = env->GetMethodID(songClass, "setAlbumArtist", "(Ljava/lang/String;)V");
|
|
||||||
jmethodID songArtist = env->GetMethodID( songClass, "setArtist", "(Ljava/lang/String;)V" );
|
|
||||||
jmethodID songGenre = env->GetMethodID( songClass, "setGenre", "(Ljava/lang/String;)V" );
|
|
||||||
jmethodID songDuration = env->GetMethodID( songClass, "setDuration", "(I)V" );
|
|
||||||
jmethodID songYear = env->GetMethodID( songClass, "setYear", "(I)V" );
|
|
||||||
jmethodID songCoverArtId = env->GetMethodID(songClass, "setCoverArtId", "(I)V");
|
|
||||||
jmethodID songPathId = env->GetMethodID(songClass, "setPath", "(Ljava/lang/String;)V");
|
|
||||||
jmethodID songFilenameId = env->GetMethodID(songClass, "setFilename", "(Ljava/lang/String;)V");
|
|
||||||
jmethodID songDownloadedId = env->GetMethodID(songClass, "setDownloaded", "(B)V");
|
|
||||||
|
|
||||||
jint id = song.id;
|
|
||||||
jstring title = env->NewStringUTF(song.title.c_str());
|
|
||||||
jstring album = env->NewStringUTF(song.album.c_str());
|
|
||||||
jstring albumArtist = env->NewStringUTF(song.albumArtist.c_str());
|
|
||||||
jstring artist = env->NewStringUTF(song.artist.c_str());
|
|
||||||
jstring genre = env->NewStringUTF(song.genre.c_str());
|
|
||||||
jint duration = song.duration;
|
|
||||||
jint year = song.year;
|
|
||||||
jint coverArtId = song.coverArtId;
|
|
||||||
jstring songPath = env->NewStringUTF(song.path.c_str());
|
|
||||||
jstring songFilename = env->NewStringUTF(song.filename.c_str());
|
|
||||||
jboolean songDownloaded = song.downloaded;
|
|
||||||
|
|
||||||
|
|
||||||
env->CallVoidMethod( songObj, songId, id );
|
|
||||||
env->CallVoidMethod(songObj, songTitle, title);
|
|
||||||
env->CallVoidMethod(songObj, songAlbum, album);
|
|
||||||
env->CallVoidMethod(songObj, songAlbumArtist, albumArtist);
|
|
||||||
env->CallVoidMethod(songObj, songArtist, artist);
|
|
||||||
env->CallVoidMethod(songObj, songGenre, genre);
|
|
||||||
env->CallVoidMethod(songObj, songDuration, duration);
|
|
||||||
env->CallVoidMethod(songObj, songYear, year);
|
|
||||||
env->CallVoidMethod(songObj, songCoverArtId, coverArtId);
|
|
||||||
env->CallVoidMethod(songObj, songPathId, songPath);
|
|
||||||
env->CallVoidMethod(songObj, songFilenameId, songFilename);
|
|
||||||
env->CallVoidMethod(songObj, songDownloadedId, songDownloaded);
|
|
||||||
|
|
||||||
env->DeleteLocalRef(title);
|
|
||||||
env->DeleteLocalRef(album);
|
|
||||||
env->DeleteLocalRef(albumArtist);
|
|
||||||
env->DeleteLocalRef(artist);
|
|
||||||
env->DeleteLocalRef(genre);
|
|
||||||
env->DeleteLocalRef(songPath);
|
|
||||||
env->DeleteLocalRef(songFilename);
|
|
||||||
|
|
||||||
return songObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string jstringToString(JNIEnv *env, jstring& val)
|
|
||||||
{
|
|
||||||
return env->GetStringUTFChars(val, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
model::APIInfo retrieveAPIInfo(const std::string& path)
|
|
||||||
{
|
|
||||||
repository::local::APIRepository apiRepo;
|
|
||||||
|
|
||||||
return apiRepo.retrieveAPIInfo(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
model::Song retrieveSong(const model::Token& token, const model::Song& song,
|
|
||||||
const std::string& baseUri)
|
|
||||||
{
|
|
||||||
repository::SongRepository songRepo;
|
|
||||||
|
|
||||||
return songRepo.retrieveSong(token, song, baseUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
model::Token fetchToken(const model::User& user, const std::string& apiUri)
|
|
||||||
{
|
|
||||||
manager::Tok tokMgr;
|
|
||||||
auto token = tokMgr.fetchTokenTrans(user, apiUri);
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
model::Token retrieveSavedToken(const std::string& path)
|
|
||||||
{
|
|
||||||
repository::local::TokenRepository tokenRepo;
|
|
||||||
if (!tokenRepo.databaseExist(path)) {
|
|
||||||
tokenRepo.initializedDatabase(path);
|
|
||||||
}
|
|
||||||
auto token = tokenRepo.retrieveToken(path);
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
model::User retrieveCredentials(const std::string& dataPath)
|
|
||||||
{
|
|
||||||
repository::local::UserRepository userRepo;
|
|
||||||
if (!userRepo.databaseExist(dataPath)) {
|
|
||||||
userRepo.initializedDatabase(dataPath);
|
|
||||||
}
|
|
||||||
auto user = userRepo.retrieveUserCredentials(dataPath);
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int retrieveRepeatMode(const std::string& path)
|
|
||||||
{
|
|
||||||
repository::local::RepeatRepository repeatRepo;
|
|
||||||
if (!repeatRepo.databaseExist(path)) {
|
|
||||||
repeatRepo.initializedDatabase(path);
|
|
||||||
}
|
|
||||||
if (!repeatRepo.doesTableExist(path)) {
|
|
||||||
repeatRepo.createRepeatTable(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto repeatMode = repeatRepo.retrieveRepeatMode(path);
|
|
||||||
|
|
||||||
return static_cast<int>(repeatMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int retrieveShuffleMode(const std::string& path)
|
|
||||||
{
|
|
||||||
repository::local::ShuffleRepository shuffleRepo;
|
|
||||||
if (!shuffleRepo.databaseExist(path)) {
|
|
||||||
shuffleRepo.initializedDatabase(path);
|
|
||||||
}
|
|
||||||
if (!shuffleRepo.doesTableExist(path)) {
|
|
||||||
shuffleRepo.createShuffleTable(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto shuffleMode = shuffleRepo.retrieveShuffleMode(path);
|
|
||||||
|
|
||||||
return static_cast<int>(shuffleMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool doesDatabaseExist(const std::string& dataPath)
|
|
||||||
{
|
|
||||||
repository::local::UserRepository userRepo;
|
|
||||||
const auto result = userRepo.databaseExist(dataPath);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool apiInformationExist(const std::string& dataPath)
|
|
||||||
{
|
|
||||||
repository::local::APIRepository apiRepo;
|
|
||||||
|
|
||||||
return apiRepo.isTableEmpty(dataPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool doesTokenExist(const std::string& dataPath)
|
|
||||||
{
|
|
||||||
repository::local::TokenRepository tokenRepo;
|
|
||||||
|
|
||||||
return tokenRepo.isTableEmpty(dataPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool userCredentialExist(const std::string& dataPath)
|
|
||||||
{
|
|
||||||
repository::local::UserRepository userRepo;
|
|
||||||
|
|
||||||
return userRepo.isTableEmpty(dataPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void saveAPIInfo(const model::APIInfo& apiInfo, const std::string& path)
|
|
||||||
{
|
|
||||||
repository::local::APIRepository apiRepo;
|
|
||||||
if (!apiRepo.databaseExist(path)) {
|
|
||||||
apiRepo.initializedDatabase(path);
|
|
||||||
}
|
|
||||||
if (!apiRepo.doesTableExist(path)) {
|
|
||||||
apiRepo.createAPiInfoTable(path);
|
|
||||||
}
|
|
||||||
if (!apiRepo.isTableEmpty(path)) {
|
|
||||||
apiRepo.deleteAPIInfo(apiInfo, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
apiRepo.saveAPIInfo(apiInfo, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveCredentials(const model::User& user, const std::string& appDirectory)
|
|
||||||
{
|
|
||||||
repository::local::UserRepository userRepo;
|
|
||||||
|
|
||||||
if (!userRepo.databaseExist(appDirectory)) {
|
|
||||||
userRepo.initializedDatabase(appDirectory);
|
|
||||||
}
|
|
||||||
if (!userRepo.doesTableExist(appDirectory)) {
|
|
||||||
userRepo.createUserTable(appDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!userRepo.isTableEmpty(appDirectory)) {
|
|
||||||
userRepo.deleteUserTable(appDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
userRepo.saveUserCred(user, appDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveToken(const model::Token& token, const std::string& path)
|
|
||||||
{
|
|
||||||
repository::local::TokenRepository tokenRepo;
|
|
||||||
if (!tokenRepo.databaseExist(path)) {
|
|
||||||
tokenRepo.initializedDatabase(path);
|
|
||||||
}
|
|
||||||
if (!tokenRepo.doesTableExist(path)) {
|
|
||||||
tokenRepo.createTokenTable(path);
|
|
||||||
}
|
|
||||||
if (!tokenRepo.isTableEmpty(path)) {
|
|
||||||
tokenRepo.deleteRecord(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenRepo.saveToken(token, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateRepeatMode(const std::string& path)
|
|
||||||
{
|
|
||||||
repository::local::RepeatRepository repeatRepo;
|
|
||||||
if (!repeatRepo.databaseExist(path)) {
|
|
||||||
repeatRepo.initializedDatabase(path);
|
|
||||||
}
|
|
||||||
repeatRepo.updateRepeat(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateShuffleMode(const std::string& path)
|
|
||||||
{
|
|
||||||
repository::local::ShuffleRepository shuffleRepo;
|
|
||||||
if (!shuffleRepo.databaseExist(path)) {
|
|
||||||
shuffleRepo.initializedDatabase(path);
|
|
||||||
}
|
|
||||||
shuffleRepo.updateShuffle(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jobjectArray
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_TrackRepository_retrieveSongs(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisOnj,
|
|
||||||
jobject token,
|
|
||||||
jstring baseUri
|
|
||||||
) {
|
|
||||||
jclass tokenClass = env->FindClass("com/example/mear/models/Token");
|
|
||||||
jclass songClass = env->FindClass( "com/example/mear/models/Song");
|
|
||||||
|
|
||||||
auto tokField = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;");
|
|
||||||
auto tokObj = env->GetObjectField(token, tokField);
|
|
||||||
std::string tokStr = env->GetStringUTFChars((jstring)tokObj, nullptr);
|
|
||||||
model::Token tk(tokStr);
|
|
||||||
|
|
||||||
const std::string uri = env->GetStringUTFChars(baseUri, nullptr);
|
|
||||||
|
|
||||||
auto allSongs = retrieveSongs(tk, uri);
|
|
||||||
jobjectArray songs = env->NewObjectArray(allSongs.size(), songClass, nullptr);
|
|
||||||
for (auto i = 0; i != allSongs.size(); ++i) {
|
|
||||||
try {
|
|
||||||
auto song = songToObj(env, allSongs[i]);
|
|
||||||
env->SetObjectArrayElement(songs, i, song);
|
|
||||||
} catch (std::exception& ex) {
|
|
||||||
auto msg = ex.what();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto curPath = "/data/data/com.example.mear/";
|
|
||||||
std::string filename;
|
|
||||||
std::string currPathStr(curPath);
|
|
||||||
std::fstream tmp;
|
|
||||||
if (currPathStr.at(currPathStr.size() - 1) == '/') {
|
|
||||||
filename.assign(currPathStr);
|
|
||||||
} else {
|
|
||||||
filename.assign(currPathStr);
|
|
||||||
filename.append("/");
|
|
||||||
}
|
|
||||||
filename.append("test.txt");
|
|
||||||
tmp.open(filename.c_str(), std::ios::out);
|
|
||||||
auto content = "hello fs";
|
|
||||||
tmp.write(content, std::strlen(content));
|
|
||||||
tmp.close();
|
|
||||||
|
|
||||||
return songs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jobject
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_APIRepository_retrieveAPIInfoRecord(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jstring pathStr ) {
|
|
||||||
const auto path = env->GetStringUTFChars(pathStr, nullptr);
|
|
||||||
|
|
||||||
auto apiInfo = retrieveAPIInfo(path);
|
|
||||||
|
|
||||||
jclass apiInfoClass = env->FindClass( "com/example/mear/models/APIInfo");
|
|
||||||
jmethodID jconstructor = env->GetMethodID( apiInfoClass, "<init>", "()V" );
|
|
||||||
jobject apiInfoObj = env->NewObject( apiInfoClass, jconstructor );
|
|
||||||
|
|
||||||
jmethodID uriId = env->GetMethodID( apiInfoClass, "setUri", "(Ljava/lang/String;)V" );
|
|
||||||
jmethodID versionId = env->GetMethodID( apiInfoClass, "setVersion", "(I)V" );
|
|
||||||
|
|
||||||
jint versionVal = apiInfo.version;
|
|
||||||
jstring uriVal = env->NewStringUTF(apiInfo.uri.c_str());
|
|
||||||
|
|
||||||
env->CallVoidMethod(apiInfoObj, uriId, uriVal);
|
|
||||||
env->CallVoidMethod( apiInfoObj, versionId, versionVal);
|
|
||||||
|
|
||||||
return apiInfoObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jobject
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_TokenRepository_retrieveTokenRecord(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jstring pathStr
|
|
||||||
) {
|
|
||||||
const auto path = env->GetStringUTFChars(pathStr, nullptr);
|
|
||||||
auto token = retrieveSavedToken(path);
|
|
||||||
|
|
||||||
auto tokenClass = env->FindClass("com/example/mear/models/Token");
|
|
||||||
auto jConstructor = env->GetMethodID(tokenClass, "<init>", "()V");
|
|
||||||
auto tokenObj = env->NewObject(tokenClass, jConstructor);
|
|
||||||
|
|
||||||
auto accessTokenId = env->GetMethodID(tokenClass, "setAccessToken", "(Ljava/lang/String;)V");
|
|
||||||
|
|
||||||
auto accessTokenStr = env->NewStringUTF(token.accessToken.c_str());
|
|
||||||
|
|
||||||
env->CallVoidMethod(tokenObj, accessTokenId, accessTokenStr);
|
|
||||||
|
|
||||||
return tokenObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jobject
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_TrackRepository_retrieveSong(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jobject tokenObj,
|
|
||||||
jobject songObj,
|
|
||||||
jstring uriStr
|
|
||||||
) {
|
|
||||||
auto tokenClass = env->GetObjectClass(tokenObj);
|
|
||||||
auto songClass = env->GetObjectClass(songObj);
|
|
||||||
|
|
||||||
auto accessTokenField = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;");
|
|
||||||
auto idField = env->GetFieldID(songClass, "id", "I");
|
|
||||||
|
|
||||||
auto accessTokenStr = (jstring)env->GetObjectField(tokenObj, accessTokenField);
|
|
||||||
auto idInt = env->GetIntField(songObj, idField);
|
|
||||||
|
|
||||||
auto uri = env->GetStringUTFChars(uriStr, nullptr);
|
|
||||||
model::Token token(env->GetStringUTFChars(accessTokenStr, nullptr));
|
|
||||||
model::Song song(idInt);
|
|
||||||
|
|
||||||
song = retrieveSong(token, song, uri);
|
|
||||||
auto fetchedSongObj = songToObj(env, song);
|
|
||||||
|
|
||||||
return fetchedSongObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jobject
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_UserRepository_retrieveUserCredentials(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jstring dataPath
|
|
||||||
) {
|
|
||||||
jclass userClass = env->FindClass("com/example/mear/models/User");
|
|
||||||
jmethodID userContructor = env->GetMethodID(userClass, "<init>", "()V");
|
|
||||||
jobject userObj = env->NewObject(userClass, userContructor);
|
|
||||||
|
|
||||||
const std::string dataPathStr = env->GetStringUTFChars(dataPath, nullptr);
|
|
||||||
auto user = retrieveCredentials(dataPathStr);
|
|
||||||
|
|
||||||
jmethodID usernameId = env->GetMethodID(userClass, "setUsername", "(Ljava/lang/String;)V");
|
|
||||||
jmethodID passwordId = env->GetMethodID(userClass, "setPassword", "(Ljava/lang/String;)V");
|
|
||||||
|
|
||||||
jstring username = env->NewStringUTF(user.username.c_str());
|
|
||||||
jstring password = env->NewStringUTF(user.password.c_str());
|
|
||||||
|
|
||||||
env->CallVoidMethod(userObj, usernameId, username);
|
|
||||||
env->CallVoidMethod(userObj, passwordId, password);
|
|
||||||
|
|
||||||
return userObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jobject
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_UserRepository_logUser(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jobject user,
|
|
||||||
jstring apiUri ) {
|
|
||||||
jclass userClass = env->GetObjectClass(user);
|
|
||||||
auto passwordField = env->GetFieldID(userClass, "password", "Ljava/lang/String;");
|
|
||||||
auto usernameField = env->GetFieldID(userClass, "username", "Ljava/lang/String;");
|
|
||||||
|
|
||||||
auto password = (jstring)env->GetObjectField(user, passwordField);
|
|
||||||
auto username = (jstring)env->GetObjectField(user, usernameField);
|
|
||||||
|
|
||||||
const std::string api = env->GetStringUTFChars(apiUri, nullptr);
|
|
||||||
model::User us(env->GetStringUTFChars(username, nullptr),
|
|
||||||
env->GetStringUTFChars(password, nullptr));
|
|
||||||
|
|
||||||
auto token = fetchToken(us, api);
|
|
||||||
|
|
||||||
jclass tokenClass = env->FindClass( "com/example/mear/models/Token");
|
|
||||||
jmethodID jconstructor = env->GetMethodID( tokenClass, "<init>", "()V" );
|
|
||||||
jobject tokenObj = env->NewObject( tokenClass, jconstructor );
|
|
||||||
|
|
||||||
jmethodID tokenAccess = env->GetMethodID( tokenClass, "setAccessToken", "(Ljava/lang/String;)V" );
|
|
||||||
|
|
||||||
jstring title = env->NewStringUTF(token.accessToken.c_str());
|
|
||||||
|
|
||||||
env->CallVoidMethod(tokenObj, tokenAccess, title);
|
|
||||||
|
|
||||||
return tokenObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jbyteArray
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_CoverArtRepository_retrieveCoverArtImage(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jobject tokenObj,
|
|
||||||
jobject coverArt,
|
|
||||||
jstring apiUri
|
|
||||||
) {
|
|
||||||
jclass coverArtClass = env->GetObjectClass(coverArt);
|
|
||||||
auto idField = env->GetFieldID(coverArtClass, "id", "I");
|
|
||||||
auto titleField = env->GetFieldID(coverArtClass, "title", "Ljava/lang/String;");
|
|
||||||
auto id = env->GetIntField(coverArt, idField);
|
|
||||||
auto title = (jstring)env->GetObjectField(coverArt, titleField);
|
|
||||||
|
|
||||||
jclass tokenClass = env->GetObjectClass(tokenObj);
|
|
||||||
auto accessTokenId = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;");
|
|
||||||
auto accessTokenVal = (jstring) env->GetObjectField(tokenObj, accessTokenId);
|
|
||||||
|
|
||||||
model::Token token;
|
|
||||||
token.accessToken = env->GetStringUTFChars(accessTokenVal, nullptr);
|
|
||||||
|
|
||||||
model::CoverArt cover(id, env->GetStringUTFChars(title, nullptr));
|
|
||||||
repository::CoverArtRepository<model::CoverArt> coverArtRepo;
|
|
||||||
auto data = coverArtRepo.retrieveCoverArtData(token, cover, env->GetStringUTFChars(apiUri, nullptr));
|
|
||||||
|
|
||||||
jbyteArray image = env->NewByteArray(data.size());
|
|
||||||
env->SetByteArrayRegion(image, 0, data.size(), (jbyte*) data.data());
|
|
||||||
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_RepeatRepository_retrieveRepeatMode(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jstring pathStr
|
|
||||||
) {
|
|
||||||
const auto dataPath = jstringToString(env, pathStr);
|
|
||||||
auto repeatMode = retrieveRepeatMode(dataPath);
|
|
||||||
|
|
||||||
return repeatMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_ShuffleRepository_retrieveShuffleMode(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jstring pathStr
|
|
||||||
) {
|
|
||||||
const auto dataPath = jstringToString(env, pathStr);
|
|
||||||
auto shuffleMode = retrieveShuffleMode(dataPath);
|
|
||||||
|
|
||||||
return shuffleMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jboolean
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_APIRepository_isAPIInfoTableEmpty(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jstring pathStr
|
|
||||||
) {
|
|
||||||
const auto dataPath = env->GetStringUTFChars(pathStr, nullptr);
|
|
||||||
|
|
||||||
return apiInformationExist(dataPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jboolean
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_TokenRepository_isTokenTableEmpty(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jstring pathStr
|
|
||||||
) {
|
|
||||||
const auto dataPath = env->GetStringUTFChars(pathStr, nullptr);
|
|
||||||
|
|
||||||
return doesTokenExist(dataPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jboolean
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_UserRepository_isUserTableEmpty(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jstring dataPath
|
|
||||||
) {
|
|
||||||
const std::string dataPathStr = env->GetStringUTFChars(dataPath, nullptr);
|
|
||||||
|
|
||||||
return userCredentialExist(dataPathStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jboolean
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_BaseRepository_doesDatabaseExist(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thidObj,
|
|
||||||
jstring dataPath
|
|
||||||
) {
|
|
||||||
const std::string dataPathStr = env->GetStringUTFChars(dataPath, nullptr);
|
|
||||||
jboolean result = doesDatabaseExist(dataPathStr);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_UserRepository_saveUserCredentials(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jobject user,
|
|
||||||
jstring appDirectory
|
|
||||||
) {
|
|
||||||
jclass userClass = env->GetObjectClass(user);
|
|
||||||
auto usernameId = env->GetFieldID(userClass, "username", "Ljava/lang/String;");
|
|
||||||
auto passwordId = env->GetFieldID(userClass, "password", "Ljava/lang/String;");
|
|
||||||
|
|
||||||
auto usernameStr = (jstring) env->GetObjectField(user, usernameId);
|
|
||||||
auto passwordStr = (jstring) env->GetObjectField(user, passwordId);
|
|
||||||
|
|
||||||
const std::string username = env->GetStringUTFChars(usernameStr, nullptr);
|
|
||||||
const std::string password = env->GetStringUTFChars(passwordStr, nullptr);
|
|
||||||
const std::string appDirectoryStr = env->GetStringUTFChars(appDirectory, nullptr);
|
|
||||||
|
|
||||||
model::User usr(username, password);
|
|
||||||
|
|
||||||
saveCredentials(usr, appDirectoryStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_APIRepository_saveAPIInfoRecord(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jobject apiInfoObj,
|
|
||||||
jstring pathStr
|
|
||||||
) {
|
|
||||||
auto apiInfoClass = env->GetObjectClass(apiInfoObj);
|
|
||||||
auto uriId = env->GetFieldID(apiInfoClass, "uri", "Ljava/lang/String;");
|
|
||||||
auto versionId = env->GetFieldID(apiInfoClass, "version", "I");
|
|
||||||
|
|
||||||
auto uriStr = (jstring) env->GetObjectField(apiInfoObj, uriId);
|
|
||||||
auto versionInt = env->GetIntField(apiInfoObj, versionId);
|
|
||||||
|
|
||||||
model::APIInfo apiInfo(env->GetStringUTFChars(uriStr, nullptr), versionInt);
|
|
||||||
auto path = env->GetStringUTFChars(pathStr, nullptr);
|
|
||||||
|
|
||||||
saveAPIInfo(apiInfo, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_TokenRepository_saveTokenRecord(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jobject tokenObj,
|
|
||||||
jstring pathStr
|
|
||||||
) {
|
|
||||||
auto tokenClass = env->GetObjectClass(tokenObj);
|
|
||||||
auto accessTokenId = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;");
|
|
||||||
|
|
||||||
auto accessTokenVal = (jstring) env->GetObjectField(tokenObj, accessTokenId);
|
|
||||||
|
|
||||||
model::Token token(env->GetStringUTFChars(accessTokenVal, nullptr));
|
|
||||||
auto path = env->GetStringUTFChars(pathStr, nullptr);
|
|
||||||
|
|
||||||
saveToken(token, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_TrackRepositories_downloadSong(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jobject tokenObj,
|
|
||||||
jobject songObj,
|
|
||||||
jstring uriStr
|
|
||||||
) {
|
|
||||||
// TODO: left off here
|
|
||||||
auto song = ObjToSong<jobject, JNIEnv>(env, songObj);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_RepeatRepository_updateRepeatMode(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jstring pathStr
|
|
||||||
) {
|
|
||||||
const auto dataPath = jstringToString(env, pathStr);
|
|
||||||
updateRepeatMode(dataPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void
|
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_repositories_ShuffleRepository_updateShuffle(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject thisObj,
|
|
||||||
jstring pathStr
|
|
||||||
) {
|
|
||||||
const auto dataPath = jstringToString(env, pathStr);
|
|
||||||
updateShuffleMode(dataPath);
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by brahmix on 10/12/19.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef MEAR_DEMO_H
|
|
||||||
#define MEAR_DEMO_H
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
|
|
||||||
#include "model/APIInfo.h"
|
|
||||||
#include "model/CoverArt.h"
|
|
||||||
#include "model/Song.h"
|
|
||||||
#include "model/Token.h"
|
|
||||||
#include "model/User.h"
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<model::Song> retrieveSongs(const model::Token&, const std::string&);
|
|
||||||
|
|
||||||
jobject songToObj(JNIEnv *env, const model::Song&);
|
|
||||||
|
|
||||||
std::string jstringToString(JNIEnv*, jstring&);
|
|
||||||
|
|
||||||
model::APIInfo retrieveAPIInfo(const std::string&);
|
|
||||||
|
|
||||||
template<typename SongObj, typename JE, class Song = model::Song>
|
|
||||||
Song ObjToSong(JE *env, SongObj obj) {
|
|
||||||
jclass songClass = env->GetObjectClass(obj);
|
|
||||||
//jmethodID jconstructor = env->GetMethodID( songClass, "<init>", "()V" );
|
|
||||||
//jobject songObj = env->NewObject( songClass, jconstructor );
|
|
||||||
|
|
||||||
auto songId = env->GetFieldID( songClass, "id", "I" );
|
|
||||||
auto songTitle = env->GetFieldID( songClass, "title", "Ljava/lang/String;" );
|
|
||||||
auto songAlbum = env->GetFieldID( songClass, "album", "Ljava/lang/String;" );
|
|
||||||
auto songAlbumArtist = env->GetFieldID(songClass, "albumArtist", "Ljava/lang/String;");
|
|
||||||
auto songArtist = env->GetFieldID( songClass, "artist", "Ljava/lang/String;" );
|
|
||||||
auto songGenre = env->GetFieldID( songClass, "genre", "Ljava/lang/String;" );
|
|
||||||
auto songDuration = env->GetFieldID( songClass, "duration", "I" );
|
|
||||||
auto songYear = env->GetFieldID( songClass, "year", "I" );
|
|
||||||
auto songCoverArtId = env->GetFieldID(songClass, "coverArtId", "I");
|
|
||||||
auto songPathId = env->GetFieldID(songClass, "path", "Ljava/lang/String;");
|
|
||||||
auto songFilenameId = env->GetFieldID(songClass, "filename", "Ljava/lang/String;");
|
|
||||||
auto songDownloadedId = env->GetFieldID(songClass, "downloaded", "B");
|
|
||||||
|
|
||||||
auto titleVal = (jstring)env->GetObjectField(obj, songTitle);
|
|
||||||
|
|
||||||
Song song;
|
|
||||||
|
|
||||||
return song;
|
|
||||||
}
|
|
||||||
|
|
||||||
model::Song retrieveSong(const model::Token&, const model::Song&, const std::string&);
|
|
||||||
|
|
||||||
model::Token fetchToken(const model::User&, const std::string&);
|
|
||||||
model::Token retrieveSavedToken(const std::string&);
|
|
||||||
|
|
||||||
model::User retrieveCredentials(const std::string&);
|
|
||||||
|
|
||||||
int retrieveRepeatMode(const std::string&);
|
|
||||||
int retrieveShuffleMode(const std::string&);
|
|
||||||
|
|
||||||
bool doesDatabaseExist(const std::string&);
|
|
||||||
bool apiInformationExist(const std::string&);
|
|
||||||
bool doesTokenExist(const std::string&);
|
|
||||||
bool userCredentialExist(const std::string&);
|
|
||||||
|
|
||||||
void saveAPIInfo(const model::APIInfo&, const std::string&);
|
|
||||||
void saveCredentials(const model::User&, const std::string&);
|
|
||||||
void saveToken(const model::Token&, const std::string&);
|
|
||||||
void updateRepeatMode(const std::string&);
|
|
||||||
void updateShuffleMode(const std::string&);
|
|
||||||
template<class Song = model::Song>
|
|
||||||
void downloadSong(Song& song) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //MEAR_DEMO_H
|
|
||||||
@@ -0,0 +1,714 @@
|
|||||||
|
//
|
||||||
|
// Created by brahmix on 10/12/19.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MEAR_DEMO_H
|
||||||
|
#define MEAR_DEMO_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <android/asset_manager_jni.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <android/sharedmem.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <jni.h>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "manager/Tok.h"
|
||||||
|
#include "model/APIInfo.h"
|
||||||
|
#include "model/CoverArt.h"
|
||||||
|
#include "model/Song.h"
|
||||||
|
#include "model/Token.h"
|
||||||
|
#include "model/User.h"
|
||||||
|
#include "repository/APIRepository.h"
|
||||||
|
#include "repository/CoverArtRepository.h"
|
||||||
|
#include "repository/RepeatRepository.h"
|
||||||
|
#include "repository/ShuffleRepository.h"
|
||||||
|
#include "repository/SongRepository.h"
|
||||||
|
#include "repository/TokenRepository.h"
|
||||||
|
#include "repository/UserRepository.h"
|
||||||
|
|
||||||
|
|
||||||
|
template<class Song = model::Song>
|
||||||
|
std::vector<Song> retrieveSongs(const model::Token& token, const std::string& baseUri) {
|
||||||
|
std::vector<model::Song> songs;
|
||||||
|
repository::SongRepository songRepo;
|
||||||
|
|
||||||
|
return songRepo.fetchSongs(token, baseUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Str = std::string>
|
||||||
|
Str jstringToString(JNIEnv *env, jstring& val) {
|
||||||
|
auto myVal = env->GetStringUTFChars(val, nullptr);
|
||||||
|
return myVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class APIInfo = model::APIInfo>
|
||||||
|
APIInfo retrieveAPIInfo(const std::string& path) {
|
||||||
|
repository::local::APIRepository apiRepo;
|
||||||
|
|
||||||
|
return apiRepo.retrieveAPIInfo(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename SongObj, typename JE, class Song = model::Song>
|
||||||
|
Song ObjToSong(JE *env, SongObj obj) {
|
||||||
|
jclass songClass = env->GetObjectClass(obj);
|
||||||
|
|
||||||
|
auto songId = env->GetFieldID( songClass, "id", "I" );
|
||||||
|
auto songTitle = env->GetFieldID( songClass, "title", "Ljava/lang/String;" );
|
||||||
|
auto songAlbum = env->GetFieldID( songClass, "album", "Ljava/lang/String;" );
|
||||||
|
auto songAlbumArtist = env->GetFieldID(songClass, "albumArtist", "Ljava/lang/String;");
|
||||||
|
auto songArtist = env->GetFieldID( songClass, "artist", "Ljava/lang/String;" );
|
||||||
|
auto songGenre = env->GetFieldID( songClass, "genre", "Ljava/lang/String;" );
|
||||||
|
auto songDuration = env->GetFieldID( songClass, "duration", "I" );
|
||||||
|
auto songYear = env->GetFieldID( songClass, "year", "I" );
|
||||||
|
auto songCoverArtId = env->GetFieldID(songClass, "coverArtId", "I");
|
||||||
|
auto songPathId = env->GetFieldID(songClass, "path", "Ljava/lang/String;");
|
||||||
|
auto songFilenameId = env->GetFieldID(songClass, "filename", "Ljava/lang/String;");
|
||||||
|
auto songDownloadedId = env->GetFieldID(songClass, "downloaded", "Z");
|
||||||
|
|
||||||
|
auto titleVal = (jstring)env->GetObjectField(obj, songTitle);
|
||||||
|
auto albumVal = (jstring)env->GetObjectField(obj, songAlbum);
|
||||||
|
auto albumArtistVal = (jstring)env->GetObjectField(obj, songAlbumArtist);
|
||||||
|
auto songArtistVal = (jstring)env->GetObjectField(obj, songArtist);
|
||||||
|
auto songGenreVal = (jstring)env->GetObjectField(obj, songGenre);
|
||||||
|
auto songDurationVal = env->GetIntField(obj, songDuration);
|
||||||
|
auto songYearVal = env->GetIntField(obj, songYear);
|
||||||
|
auto songCoverArtIdVal = env->GetIntField(obj, songCoverArtId);
|
||||||
|
auto songPathVal = (jstring)env->GetObjectField(obj, songPathId);
|
||||||
|
auto songFilenameVal = (jstring)env->GetObjectField(obj, songFilenameId);
|
||||||
|
|
||||||
|
|
||||||
|
Song song;
|
||||||
|
song.title = env->GetStringUTFChars(titleVal, nullptr);
|
||||||
|
song.artist = env->GetStringUTFChars(songArtistVal, nullptr);
|
||||||
|
song.album = env->GetStringUTFChars(albumVal, nullptr);
|
||||||
|
song.albumArtist = env->GetStringUTFChars(albumArtistVal, nullptr);
|
||||||
|
song.genre = env->GetStringUTFChars(songGenreVal, nullptr);
|
||||||
|
song.duration = songDurationVal;
|
||||||
|
song.year = songYearVal;
|
||||||
|
song.coverArtId = songCoverArtIdVal;
|
||||||
|
song.path = env->GetStringUTFChars(songPathVal, nullptr);
|
||||||
|
song.filename = env->GetStringUTFChars(songFilenameVal, nullptr);
|
||||||
|
|
||||||
|
return song;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Song = model::Song>
|
||||||
|
Song retrieveSong(const model::Token& token, const Song& song,
|
||||||
|
const std::string& baseUri) {
|
||||||
|
repository::SongRepository songRepo;
|
||||||
|
|
||||||
|
return songRepo.retrieveSong(token, song, baseUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Token = model::Token>
|
||||||
|
Token fetchToken(const model::User& user, const std::string& apiUri) {
|
||||||
|
manager::Tok tokMgr;
|
||||||
|
auto token = tokMgr.fetchTokenTrans(user, apiUri);
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
template<class Token = model::Token>
|
||||||
|
Token retrieveSavedToken(const std::string& path) {
|
||||||
|
repository::local::TokenRepository tokenRepo;
|
||||||
|
if (!tokenRepo.databaseExist(path)) {
|
||||||
|
tokenRepo.initializedDatabase(path);
|
||||||
|
}
|
||||||
|
auto token = tokenRepo.retrieveToken(path);
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class User = model::User>
|
||||||
|
User retrieveCredentials(const std::string& dataPath) {
|
||||||
|
repository::local::UserRepository userRepo;
|
||||||
|
if (!userRepo.databaseExist(dataPath)) {
|
||||||
|
userRepo.initializedDatabase(dataPath);
|
||||||
|
}
|
||||||
|
auto user = userRepo.retrieveUserCredentials(dataPath);
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int retrieveRepeatMode(const std::string& path) {
|
||||||
|
repository::local::RepeatRepository repeatRepo;
|
||||||
|
if (!repeatRepo.databaseExist(path)) {
|
||||||
|
repeatRepo.initializedDatabase(path);
|
||||||
|
}
|
||||||
|
if (!repeatRepo.doesTableExist(path)) {
|
||||||
|
repeatRepo.createRepeatTable(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto repeatMode = repeatRepo.retrieveRepeatMode(path);
|
||||||
|
|
||||||
|
return static_cast<int>(repeatMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int retrieveShuffleMode(const std::string& path) {
|
||||||
|
repository::local::ShuffleRepository shuffleRepo;
|
||||||
|
if (!shuffleRepo.databaseExist(path)) {
|
||||||
|
shuffleRepo.initializedDatabase(path);
|
||||||
|
}
|
||||||
|
if (!shuffleRepo.doesTableExist(path)) {
|
||||||
|
shuffleRepo.createShuffleTable(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto shuffleMode = shuffleRepo.retrieveShuffleMode(path);
|
||||||
|
|
||||||
|
return static_cast<int>(shuffleMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool doesDatabaseExist(const std::string& dataPath) {
|
||||||
|
repository::local::UserRepository userRepo;
|
||||||
|
const auto result = userRepo.databaseExist(dataPath);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool apiInformationExist(const std::string& dataPath) {
|
||||||
|
repository::local::APIRepository apiRepo;
|
||||||
|
|
||||||
|
return apiRepo.isTableEmpty(dataPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool doesTokenExist(const std::string& dataPath) {
|
||||||
|
repository::local::TokenRepository tokenRepo;
|
||||||
|
|
||||||
|
return tokenRepo.isTableEmpty(dataPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool userCredentialExist(const std::string& dataPath) {
|
||||||
|
repository::local::UserRepository userRepo;
|
||||||
|
|
||||||
|
return userRepo.isTableEmpty(dataPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void saveAPIInfo(const model::APIInfo& apiInfo, const std::string& path) {
|
||||||
|
repository::local::APIRepository apiRepo;
|
||||||
|
if (!apiRepo.databaseExist(path)) {
|
||||||
|
apiRepo.initializedDatabase(path);
|
||||||
|
}
|
||||||
|
if (!apiRepo.doesTableExist(path)) {
|
||||||
|
apiRepo.createAPiInfoTable(path);
|
||||||
|
}
|
||||||
|
if (!apiRepo.isTableEmpty(path)) {
|
||||||
|
apiRepo.deleteAPIInfo(apiInfo, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
apiRepo.saveAPIInfo(apiInfo, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveCredentials(const model::User& user, const std::string& appDirectory) {
|
||||||
|
repository::local::UserRepository userRepo;
|
||||||
|
|
||||||
|
if (!userRepo.databaseExist(appDirectory)) {
|
||||||
|
userRepo.initializedDatabase(appDirectory);
|
||||||
|
}
|
||||||
|
if (!userRepo.doesTableExist(appDirectory)) {
|
||||||
|
userRepo.createUserTable(appDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userRepo.isTableEmpty(appDirectory)) {
|
||||||
|
userRepo.deleteUserTable(appDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
userRepo.saveUserCred(user, appDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveToken(const model::Token& token, const std::string& path) {
|
||||||
|
repository::local::TokenRepository tokenRepo;
|
||||||
|
if (!tokenRepo.databaseExist(path)) {
|
||||||
|
tokenRepo.initializedDatabase(path);
|
||||||
|
}
|
||||||
|
if (!tokenRepo.doesTableExist(path)) {
|
||||||
|
tokenRepo.createTokenTable(path);
|
||||||
|
}
|
||||||
|
if (!tokenRepo.isTableEmpty(path)) {
|
||||||
|
tokenRepo.deleteRecord(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenRepo.saveToken(token, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateRepeatMode(const std::string& path) {
|
||||||
|
repository::local::RepeatRepository repeatRepo;
|
||||||
|
if (!repeatRepo.databaseExist(path)) {
|
||||||
|
repeatRepo.initializedDatabase(path);
|
||||||
|
}
|
||||||
|
repeatRepo.updateRepeat(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateShuffleMode(const std::string& path) {
|
||||||
|
repository::local::ShuffleRepository shuffleRepo;
|
||||||
|
if (!shuffleRepo.databaseExist(path)) {
|
||||||
|
shuffleRepo.initializedDatabase(path);
|
||||||
|
}
|
||||||
|
shuffleRepo.updateShuffle(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Song = model::Song, class Token = model::Token, typename Str = std::string>
|
||||||
|
void downloadSong(Song& song, const Token& token, const Str& path) {
|
||||||
|
repository::SongRepository songRepo;
|
||||||
|
// songRepo.downloadSong();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Song = model::Song>
|
||||||
|
jobject songToObj(JNIEnv *env, const Song& song) {
|
||||||
|
jclass songClass = env->FindClass( "com/example/mear/models/Song");
|
||||||
|
jmethodID jconstructor = env->GetMethodID( songClass, "<init>", "()V" );
|
||||||
|
jobject songObj = env->NewObject( songClass, jconstructor );
|
||||||
|
|
||||||
|
auto songId = env->GetFieldID( songClass, "id", "I" );
|
||||||
|
auto songTitle = env->GetFieldID( songClass, "title", "Ljava/lang/String;" );
|
||||||
|
auto songAlbum = env->GetFieldID( songClass, "album", "Ljava/lang/String;" );
|
||||||
|
auto songAlbumArtist = env->GetFieldID(songClass, "albumArtist", "Ljava/lang/String;");
|
||||||
|
auto songArtist = env->GetFieldID( songClass, "artist", "Ljava/lang/String;" );
|
||||||
|
auto songGenre = env->GetFieldID( songClass, "genre", "Ljava/lang/String;" );
|
||||||
|
auto songYear = env->GetFieldID( songClass, "year", "I" );
|
||||||
|
auto songDuration = env->GetFieldID( songClass, "duration", "I" );
|
||||||
|
auto songCoverArtId = env->GetFieldID(songClass, "coverArtId", "I");
|
||||||
|
auto songDownloadedId = env->GetFieldID(songClass, "downloaded", "Z");
|
||||||
|
auto songPathId = env->GetFieldID(songClass, "path", "Ljava/lang/String;");
|
||||||
|
auto songFilenameId = env->GetFieldID(songClass, "filename", "Ljava/lang/String;");
|
||||||
|
|
||||||
|
auto songPath = (song.path.empty()) ? nullptr : env->NewStringUTF(song.path.c_str());
|
||||||
|
auto songFilename = (song.filename.empty()) ? nullptr : env->NewStringUTF(song.filename.c_str());
|
||||||
|
|
||||||
|
env->SetIntField(songObj, songId, song.id);
|
||||||
|
env->SetObjectField(songObj, songTitle, env->NewStringUTF(song.title.c_str()));
|
||||||
|
env->SetObjectField(songObj, songAlbum, env->NewStringUTF(song.album.c_str()));
|
||||||
|
env->SetObjectField(songObj, songAlbumArtist, env->NewStringUTF(song.albumArtist.c_str()));
|
||||||
|
env->SetObjectField(songObj, songArtist, env->NewStringUTF(song.artist.c_str()));
|
||||||
|
env->SetObjectField(songObj, songGenre, env->NewStringUTF(song.genre.c_str()));
|
||||||
|
env->SetIntField(songObj, songYear, song.year);
|
||||||
|
env->SetIntField(songObj, songDuration, song.duration);
|
||||||
|
env->SetIntField(songObj, songCoverArtId, song.coverArtId);
|
||||||
|
env->SetBooleanField(songObj, songDownloadedId, song.downloaded);
|
||||||
|
env->SetObjectField(songObj, songPathId, songPath);
|
||||||
|
env->SetObjectField(songObj, songFilenameId, songFilename);
|
||||||
|
|
||||||
|
env->DeleteLocalRef(songPath);
|
||||||
|
env->DeleteLocalRef(songFilename);
|
||||||
|
|
||||||
|
return songObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobjectArray
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_TrackRepository_retrieveSongs(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisOnj,
|
||||||
|
jobject token,
|
||||||
|
jstring baseUri
|
||||||
|
) {
|
||||||
|
jclass tokenClass = env->FindClass("com/example/mear/models/Token");
|
||||||
|
jclass songClass = env->FindClass( "com/example/mear/models/Song");
|
||||||
|
|
||||||
|
auto tokField = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;");
|
||||||
|
auto tokObj = env->GetObjectField(token, tokField);
|
||||||
|
std::string tokStr = env->GetStringUTFChars((jstring)tokObj, nullptr);
|
||||||
|
model::Token tk(tokStr);
|
||||||
|
|
||||||
|
const std::string uri = env->GetStringUTFChars(baseUri, nullptr);
|
||||||
|
env->DeleteLocalRef(baseUri);
|
||||||
|
|
||||||
|
auto allSongs = retrieveSongs(tk, uri);
|
||||||
|
jobjectArray songs = env->NewObjectArray(allSongs.size(), songClass, nullptr);
|
||||||
|
auto i = 0;
|
||||||
|
for (auto& sng: allSongs) {
|
||||||
|
try {
|
||||||
|
auto song = songToObj<model::Song>(env, sng);
|
||||||
|
env->SetObjectArrayElement(songs, i++, song);
|
||||||
|
} catch (std::exception& ex) {
|
||||||
|
auto msg = ex.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return songs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jbyteArray
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_CoverArtRepository_retrieveCoverArtImage(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jobject tokenObj,
|
||||||
|
jobject coverArt,
|
||||||
|
jstring apiUri
|
||||||
|
) {
|
||||||
|
jclass coverArtClass = env->GetObjectClass(coverArt);
|
||||||
|
auto idField = env->GetFieldID(coverArtClass, "id", "I");
|
||||||
|
auto titleField = env->GetFieldID(coverArtClass, "title", "Ljava/lang/String;");
|
||||||
|
auto id = env->GetIntField(coverArt, idField);
|
||||||
|
auto title = (jstring)env->GetObjectField(coverArt, titleField);
|
||||||
|
|
||||||
|
jclass tokenClass = env->GetObjectClass(tokenObj);
|
||||||
|
auto accessTokenId = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;");
|
||||||
|
auto accessTokenVal = (jstring) env->GetObjectField(tokenObj, accessTokenId);
|
||||||
|
|
||||||
|
model::Token token;
|
||||||
|
token.accessToken = env->GetStringUTFChars(accessTokenVal, nullptr);
|
||||||
|
|
||||||
|
model::CoverArt cover(id, env->GetStringUTFChars(title, nullptr));
|
||||||
|
repository::CoverArtRepository<model::CoverArt> coverArtRepo;
|
||||||
|
auto data = coverArtRepo.retrieveCoverArtData(token, cover, env->GetStringUTFChars(apiUri, nullptr));
|
||||||
|
|
||||||
|
jbyteArray image = env->NewByteArray(data.size());
|
||||||
|
env->SetByteArrayRegion(image, 0, data.size(), (jbyte*) data.data());
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobject
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_APIRepository_retrieveAPIInfoRecord(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jstring pathStr ) {
|
||||||
|
const auto path = env->GetStringUTFChars(pathStr, nullptr);
|
||||||
|
|
||||||
|
auto apiInfo = retrieveAPIInfo(path);
|
||||||
|
|
||||||
|
jclass apiInfoClass = env->FindClass( "com/example/mear/models/APIInfo");
|
||||||
|
jmethodID jconstructor = env->GetMethodID( apiInfoClass, "<init>", "()V" );
|
||||||
|
jobject apiInfoObj = env->NewObject( apiInfoClass, jconstructor );
|
||||||
|
|
||||||
|
jmethodID uriId = env->GetMethodID( apiInfoClass, "setUri", "(Ljava/lang/String;)V" );
|
||||||
|
jmethodID versionId = env->GetMethodID( apiInfoClass, "setVersion", "(I)V" );
|
||||||
|
|
||||||
|
jint versionVal = apiInfo.version;
|
||||||
|
jstring uriVal = env->NewStringUTF(apiInfo.uri.c_str());
|
||||||
|
|
||||||
|
env->CallVoidMethod(apiInfoObj, uriId, uriVal);
|
||||||
|
env->CallVoidMethod( apiInfoObj, versionId, versionVal);
|
||||||
|
|
||||||
|
return apiInfoObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobject
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_TokenRepository_retrieveTokenRecord(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jstring pathStr
|
||||||
|
) {
|
||||||
|
const auto path = env->GetStringUTFChars(pathStr, nullptr);
|
||||||
|
auto token = retrieveSavedToken(path);
|
||||||
|
|
||||||
|
auto tokenClass = env->FindClass("com/example/mear/models/Token");
|
||||||
|
auto jConstructor = env->GetMethodID(tokenClass, "<init>", "()V");
|
||||||
|
auto tokenObj = env->NewObject(tokenClass, jConstructor);
|
||||||
|
|
||||||
|
auto accessTokenId = env->GetMethodID(tokenClass, "setAccessToken", "(Ljava/lang/String;)V");
|
||||||
|
|
||||||
|
auto accessTokenStr = env->NewStringUTF(token.accessToken.c_str());
|
||||||
|
|
||||||
|
env->CallVoidMethod(tokenObj, accessTokenId, accessTokenStr);
|
||||||
|
|
||||||
|
return tokenObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobject
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_TrackRepository_retrieveSong(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jobject tokenObj,
|
||||||
|
jobject songObj,
|
||||||
|
jstring uriStr
|
||||||
|
) {
|
||||||
|
auto tokenClass = env->GetObjectClass(tokenObj);
|
||||||
|
auto songClass = env->GetObjectClass(songObj);
|
||||||
|
|
||||||
|
auto accessTokenField = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;");
|
||||||
|
auto idField = env->GetFieldID(songClass, "id", "I");
|
||||||
|
|
||||||
|
auto accessTokenStr = (jstring)env->GetObjectField(tokenObj, accessTokenField);
|
||||||
|
auto idInt = env->GetIntField(songObj, idField);
|
||||||
|
|
||||||
|
auto uri = env->GetStringUTFChars(uriStr, nullptr);
|
||||||
|
model::Token token(env->GetStringUTFChars(accessTokenStr, nullptr));
|
||||||
|
model::Song song(idInt);
|
||||||
|
|
||||||
|
song = retrieveSong(token, song, uri);
|
||||||
|
auto fetchedSongObj = songToObj(env, song);
|
||||||
|
|
||||||
|
return fetchedSongObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobject
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_UserRepository_retrieveUserCredentials(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jstring dataPath
|
||||||
|
) {
|
||||||
|
jclass userClass = env->FindClass("com/example/mear/models/User");
|
||||||
|
jmethodID userContructor = env->GetMethodID(userClass, "<init>", "()V");
|
||||||
|
jobject userObj = env->NewObject(userClass, userContructor);
|
||||||
|
|
||||||
|
const std::string dataPathStr = env->GetStringUTFChars(dataPath, nullptr);
|
||||||
|
auto user = retrieveCredentials(dataPathStr);
|
||||||
|
|
||||||
|
jmethodID usernameId = env->GetMethodID(userClass, "setUsername", "(Ljava/lang/String;)V");
|
||||||
|
jmethodID passwordId = env->GetMethodID(userClass, "setPassword", "(Ljava/lang/String;)V");
|
||||||
|
|
||||||
|
jstring username = env->NewStringUTF(user.username.c_str());
|
||||||
|
jstring password = env->NewStringUTF(user.password.c_str());
|
||||||
|
|
||||||
|
env->CallVoidMethod(userObj, usernameId, username);
|
||||||
|
env->CallVoidMethod(userObj, passwordId, password);
|
||||||
|
|
||||||
|
return userObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobject
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_UserRepository_logUser(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jobject user,
|
||||||
|
jstring apiUri ) {
|
||||||
|
jclass userClass = env->GetObjectClass(user);
|
||||||
|
auto passwordField = env->GetFieldID(userClass, "password", "Ljava/lang/String;");
|
||||||
|
auto usernameField = env->GetFieldID(userClass, "username", "Ljava/lang/String;");
|
||||||
|
|
||||||
|
auto password = (jstring)env->GetObjectField(user, passwordField);
|
||||||
|
auto username = (jstring)env->GetObjectField(user, usernameField);
|
||||||
|
|
||||||
|
const std::string api = env->GetStringUTFChars(apiUri, nullptr);
|
||||||
|
model::User us(env->GetStringUTFChars(username, nullptr),
|
||||||
|
env->GetStringUTFChars(password, nullptr));
|
||||||
|
|
||||||
|
auto token = fetchToken(us, api);
|
||||||
|
|
||||||
|
jclass tokenClass = env->FindClass( "com/example/mear/models/Token");
|
||||||
|
jmethodID jconstructor = env->GetMethodID( tokenClass, "<init>", "()V" );
|
||||||
|
jobject tokenObj = env->NewObject( tokenClass, jconstructor );
|
||||||
|
|
||||||
|
jmethodID tokenAccess = env->GetMethodID( tokenClass, "setAccessToken", "(Ljava/lang/String;)V" );
|
||||||
|
|
||||||
|
jstring title = env->NewStringUTF(token.accessToken.c_str());
|
||||||
|
|
||||||
|
env->CallVoidMethod(tokenObj, tokenAccess, title);
|
||||||
|
|
||||||
|
return tokenObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jint
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_RepeatRepository_retrieveRepeatMode(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jstring pathStr
|
||||||
|
) {
|
||||||
|
const auto dataPath = jstringToString(env, pathStr);
|
||||||
|
auto repeatMode = retrieveRepeatMode(dataPath);
|
||||||
|
|
||||||
|
return repeatMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jint
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_ShuffleRepository_retrieveShuffleMode(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jstring pathStr
|
||||||
|
) {
|
||||||
|
const auto dataPath = jstringToString(env, pathStr);
|
||||||
|
auto shuffleMode = retrieveShuffleMode(dataPath);
|
||||||
|
|
||||||
|
return shuffleMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jboolean
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_APIRepository_isAPIInfoTableEmpty(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jstring pathStr
|
||||||
|
) {
|
||||||
|
const auto dataPath = env->GetStringUTFChars(pathStr, nullptr);
|
||||||
|
|
||||||
|
return apiInformationExist(dataPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jboolean
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_BaseRepository_doesDatabaseExist(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thidObj,
|
||||||
|
jstring dataPath
|
||||||
|
) {
|
||||||
|
const std::string dataPathStr = env->GetStringUTFChars(dataPath, nullptr);
|
||||||
|
jboolean result = doesDatabaseExist(dataPathStr);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jboolean
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_TokenRepository_isTokenTableEmpty(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jstring pathStr
|
||||||
|
) {
|
||||||
|
const auto dataPath = env->GetStringUTFChars(pathStr, nullptr);
|
||||||
|
|
||||||
|
return doesTokenExist(dataPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jboolean
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_UserRepository_isUserTableEmpty(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jstring dataPath
|
||||||
|
) {
|
||||||
|
const std::string dataPathStr = env->GetStringUTFChars(dataPath, nullptr);
|
||||||
|
|
||||||
|
return userCredentialExist(dataPathStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_APIRepository_saveAPIInfoRecord(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jobject apiInfoObj,
|
||||||
|
jstring pathStr
|
||||||
|
) {
|
||||||
|
auto apiInfoClass = env->GetObjectClass(apiInfoObj);
|
||||||
|
auto uriId = env->GetFieldID(apiInfoClass, "uri", "Ljava/lang/String;");
|
||||||
|
auto versionId = env->GetFieldID(apiInfoClass, "version", "I");
|
||||||
|
|
||||||
|
auto uriStr = (jstring) env->GetObjectField(apiInfoObj, uriId);
|
||||||
|
auto versionInt = env->GetIntField(apiInfoObj, versionId);
|
||||||
|
|
||||||
|
model::APIInfo apiInfo(env->GetStringUTFChars(uriStr, nullptr), versionInt);
|
||||||
|
auto path = env->GetStringUTFChars(pathStr, nullptr);
|
||||||
|
|
||||||
|
saveAPIInfo(apiInfo, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_RepeatRepository_updateRepeatMode(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jstring pathStr
|
||||||
|
) {
|
||||||
|
const auto dataPath = jstringToString(env, pathStr);
|
||||||
|
updateRepeatMode(dataPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_ShuffleRepository_updateShuffle(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jstring pathStr
|
||||||
|
) {
|
||||||
|
const auto dataPath = jstringToString(env, pathStr);
|
||||||
|
updateShuffleMode(dataPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_TokenRepository_saveTokenRecord(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jobject tokenObj,
|
||||||
|
jstring pathStr
|
||||||
|
) {
|
||||||
|
auto tokenClass = env->GetObjectClass(tokenObj);
|
||||||
|
auto accessTokenId = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;");
|
||||||
|
|
||||||
|
auto accessTokenVal = (jstring) env->GetObjectField(tokenObj, accessTokenId);
|
||||||
|
|
||||||
|
model::Token token(env->GetStringUTFChars(accessTokenVal, nullptr));
|
||||||
|
auto path = env->GetStringUTFChars(pathStr, nullptr);
|
||||||
|
|
||||||
|
saveToken(token, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_TrackRepositories_downloadSong(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jobject tokenObj,
|
||||||
|
jobject songObj,
|
||||||
|
jstring pathStr
|
||||||
|
) {
|
||||||
|
// TODO: left off here
|
||||||
|
auto tokenClass = env->GetObjectClass(tokenObj);
|
||||||
|
auto accessTokenId = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;");
|
||||||
|
auto accessTokenVal = (jstring) env->GetObjectField(tokenObj, accessTokenId);
|
||||||
|
model::Token token(env->GetStringUTFChars(accessTokenVal, nullptr));
|
||||||
|
|
||||||
|
auto song = ObjToSong<jobject, JNIEnv>(env, songObj);
|
||||||
|
auto path = env->GetStringUTFChars(pathStr, nullptr);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void
|
||||||
|
JNICALL
|
||||||
|
Java_com_example_mear_repositories_UserRepository_saveUserCredentials(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject thisObj,
|
||||||
|
jobject user,
|
||||||
|
jstring appDirectory
|
||||||
|
) {
|
||||||
|
jclass userClass = env->GetObjectClass(user);
|
||||||
|
auto usernameId = env->GetFieldID(userClass, "username", "Ljava/lang/String;");
|
||||||
|
auto passwordId = env->GetFieldID(userClass, "password", "Ljava/lang/String;");
|
||||||
|
|
||||||
|
auto usernameStr = (jstring) env->GetObjectField(user, usernameId);
|
||||||
|
auto passwordStr = (jstring) env->GetObjectField(user, passwordId);
|
||||||
|
|
||||||
|
const std::string username = env->GetStringUTFChars(usernameStr, nullptr);
|
||||||
|
const std::string password = env->GetStringUTFChars(passwordStr, nullptr);
|
||||||
|
const std::string appDirectoryStr = env->GetStringUTFChars(appDirectory, nullptr);
|
||||||
|
|
||||||
|
model::User usr(username, password);
|
||||||
|
|
||||||
|
saveCredentials(usr, appDirectoryStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MEAR_DEMO_H
|
||||||
@@ -61,6 +61,9 @@ namespace repository {
|
|||||||
songJson["album_artist"].get<std::string>(),
|
songJson["album_artist"].get<std::string>(),
|
||||||
songJson["genre"].get<std::string>(), songJson["duration"].get<int>(),
|
songJson["genre"].get<std::string>(), songJson["duration"].get<int>(),
|
||||||
songJson["year"].get<int>(), songJson["coverart_id"].get<int>());
|
songJson["year"].get<int>(), songJson["coverart_id"].get<int>());
|
||||||
|
song.filename = "";
|
||||||
|
song.path = "";
|
||||||
|
song.downloaded = false;
|
||||||
|
|
||||||
songs.push_back(song);
|
songs.push_back(song);
|
||||||
}
|
}
|
||||||
@@ -109,6 +112,9 @@ namespace repository {
|
|||||||
s["album_artist"].get<std::string>(), s["genre"].get<std::string>(),
|
s["album_artist"].get<std::string>(), s["genre"].get<std::string>(),
|
||||||
s["duration"].get<int>(), s["year"].get<int>(),
|
s["duration"].get<int>(), s["year"].get<int>(),
|
||||||
s["coverart_id"].get<int>());
|
s["coverart_id"].get<int>());
|
||||||
|
song.filename = "";
|
||||||
|
song.path = "";
|
||||||
|
song.downloaded = false;
|
||||||
|
|
||||||
return song;
|
return song;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ buildscript {
|
|||||||
|
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.5.2'
|
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|||||||
Reference in New Issue
Block a user