Merge commit '05cc660641' into traffic

# Conflicts:
#	CMakeLists.txt
#	android/app/src/main/java/app/organicmaps/settings/SettingsPrefsFragment.java
#	android/sdk/src/main/cpp/app/organicmaps/sdk/Framework.hpp
#	android/sdk/src/main/cpp/app/organicmaps/sdk/OrganicMaps.cpp
#	android/sdk/src/main/cpp/app/organicmaps/sdk/util/Config.cpp
#	libs/indexer/data_source.hpp
#	libs/indexer/feature.hpp
#	libs/indexer/ftypes_matcher.hpp
#	libs/map/framework.cpp
#	libs/map/traffic_manager.cpp
#	libs/routing/absent_regions_finder.cpp
#	libs/routing/edge_estimator.hpp
#	libs/routing/index_router.cpp
#	libs/routing/index_router.hpp
#	libs/routing/routing_session.hpp
#	libs/routing_common/num_mwm_id.hpp
#	libs/traffic/traffic_info.cpp
#	qt/mainwindow.hpp
#	qt/preferences_dialog.cpp
#	tools/openlr/helpers.hpp
#	tools/openlr/openlr_decoder.cpp
#	tools/openlr/openlr_decoder.hpp
#	tools/openlr/openlr_stat/openlr_stat.cpp
#	tools/openlr/router.hpp
#	tools/openlr/score_candidate_paths_getter.cpp
#	tools/openlr/score_candidate_paths_getter.hpp
#	xcode/CoMaps.xcworkspace/contents.xcworkspacedata
This commit is contained in:
mvglasow
2025-09-10 21:22:40 +03:00
4644 changed files with 82377 additions and 85029 deletions

View File

@@ -8,8 +8,11 @@ android {
ndkVersion = '28.2.13676358'
defaultConfig {
buildFeatures {
buildConfig = true
}
defaultConfig {
minSdk = propMinSdkVersion.toInteger()
targetSdk = propTargetSdkVersion.toInteger()
@@ -73,12 +76,12 @@ android {
jniDebuggable true // Enable jni debug build
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// minifyEnabled true
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
beta {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// minifyEnabled true
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
matchingFallbacks = ['release']
}
}
@@ -92,13 +95,37 @@ android {
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
lint {
disable 'MissingTranslation'
// https://github.com/organicmaps/organicmaps/issues/3551
disable 'MissingQuantity', 'UnusedQuantity'
// https://github.com/organicmaps/organicmaps/issues/3550
disable 'ByteOrderMark'
// https://github.com/organicmaps/organicmaps/issues/1077
disable 'CustomSplashScreen'
// https://github.com/organicmaps/organicmaps/issues/3610
disable 'InsecureBaseConfiguration'
abortOnError = true
}
}
dependencies {
coreLibraryDesugaring libs.android.tools.desugar
implementation libs.androidx.core
implementation libs.androidx.annotation
implementation libs.androidx.fragment
implementation libs.androidx.lifecycle.process
implementation libs.androidx.recyclerview
implementation libs.android.material
testImplementation libs.junit
}
// TODO: Running lint task triggers native build. Find a better solution.
@@ -114,6 +141,20 @@ project.afterEvaluate {
nativeTask.onlyIf { false }
}
}
final taskName = gradle.startParameter.taskNames
if (['assemble', 'bundle', 'compile', 'install'].any{taskName.any{task->task.startsWith(it)}}) {
exec {
workingDir '../..'
if (!taskName.toString().contains('Google')) {
environment 'SKIP_MAP_DOWNLOAD', '1'
}
commandLine './configure.sh'
}
}
}
tasks.withType(JavaCompile).configureEach {

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="auto">
<!-- Requiring "android.hardware.touchscreen" here breaks DeX mode -->
<uses-feature
android:glEsVersion="0x00030000"
android:required="true" />
<uses-feature
android:name="android.hardware.wifi"
android:required="false" />
<uses-feature
android:name="android.hardware.location"
android:required="false" />
<uses-feature
android:name="android.hardware.location.network"
android:required="false" />
<uses-feature
android:name="android.hardware.location.gps"
android:required="false" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="22" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

View File

@@ -44,6 +44,10 @@ set(SRC
app/organicmaps/sdk/core/jni_java_methods.cpp
app/organicmaps/sdk/core/logging.cpp
app/organicmaps/sdk/bookmarks/data/BookmarkManager.cpp
app/organicmaps/sdk/bookmarks/data/Icon.cpp
app/organicmaps/sdk/bookmarks/data/Icon.hpp
app/organicmaps/sdk/bookmarks/data/PredefinedColors.cpp
app/organicmaps/sdk/bookmarks/data/PredefinedColors.hpp
app/organicmaps/sdk/DownloadResourcesLegacyActivity.cpp
app/organicmaps/sdk/editor/Editor.cpp
app/organicmaps/sdk/editor/OpeningHours.cpp

View File

@@ -31,13 +31,13 @@ using namespace std::placeholders;
/// Special error codes to notify GUI about free space
//@{
#define ERR_DOWNLOAD_SUCCESS 0
#define ERR_DISK_ERROR -1
#define ERR_NOT_ENOUGH_FREE_SPACE -2
#define ERR_STORAGE_DISCONNECTED -3
#define ERR_DOWNLOAD_ERROR -4
#define ERR_NO_MORE_FILES -5
#define ERR_FILE_IN_PROGRESS -6
#define ERR_DOWNLOAD_SUCCESS 0
#define ERR_DISK_ERROR -1
#define ERR_NOT_ENOUGH_FREE_SPACE -2
#define ERR_STORAGE_DISCONNECTED -3
#define ERR_DOWNLOAD_ERROR -4
#define ERR_NO_MORE_FILES -5
#define ERR_FILE_IN_PROGRESS -6
//@}
namespace
@@ -52,135 +52,129 @@ static std::shared_ptr<HttpRequest> g_currentRequest;
extern "C"
{
using Callback = HttpRequest::Callback;
using Callback = HttpRequest::Callback;
static int HasSpaceForFiles(Platform & pl, std::string const & sdcardPath, size_t fileSize)
static int HasSpaceForFiles(Platform & pl, std::string const & sdcardPath, size_t fileSize)
{
switch (pl.GetWritableStorageStatus(fileSize))
{
switch (pl.GetWritableStorageStatus(fileSize))
{
case Platform::STORAGE_DISCONNECTED:
return ERR_STORAGE_DISCONNECTED;
case Platform::STORAGE_DISCONNECTED: return ERR_STORAGE_DISCONNECTED;
case Platform::NOT_ENOUGH_SPACE:
return ERR_NOT_ENOUGH_FREE_SPACE;
case Platform::NOT_ENOUGH_SPACE: return ERR_NOT_ENOUGH_FREE_SPACE;
default:
return static_cast<int>(fileSize);
}
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeGetBytesToDownload(JNIEnv * env, jclass clazz)
{
// clear all
g_filesToDownload.clear();
g_totalBytesToDownload = 0;
g_totalDownloadedBytes = 0;
using namespace storage;
Storage const & storage = g_framework->GetStorage();
auto const status = storage.GetForceDownloadWorlds(g_filesToDownload);
for (auto const & cf : g_filesToDownload)
g_totalBytesToDownload += cf.GetRemoteSize();
int res;
if (status == Storage::WorldStatus::ERROR_CREATE_FOLDER ||
status == Storage::WorldStatus::ERROR_MOVE_FILE)
{
res = ERR_DISK_ERROR;
}
else
{
Platform & pl = GetPlatform();
res = HasSpaceForFiles(pl, pl.WritableDir(), g_totalBytesToDownload);
}
if (res == ERR_STORAGE_DISCONNECTED)
LOG(LWARNING, ("External file system is not available"));
else if (res == ERR_NOT_ENOUGH_FREE_SPACE)
LOG(LWARNING, ("Not enough space to extract files"));
g_currentRequest.reset();
if (status == Storage::WorldStatus::WAS_MOVED)
{
g_framework->ReloadWorldMaps();
res = ERR_DOWNLOAD_SUCCESS; // reset possible storage error if we moved files
}
return res;
}
static void DownloadFileFinished(std::shared_ptr<jobject> obj, HttpRequest const & req)
{
auto const status = req.GetStatus();
ASSERT_NOT_EQUAL(status, DownloadStatus::InProgress, ());
int errorCode = ERR_DOWNLOAD_ERROR;
if (status == DownloadStatus::Completed)
errorCode = ERR_DOWNLOAD_SUCCESS;
g_currentRequest.reset();
if (errorCode == ERR_DOWNLOAD_SUCCESS)
{
auto const & curFile = g_filesToDownload.back();
size_t const sz = curFile.GetRemoteSize();
LOG(LDEBUG, ("finished downloading", curFile.GetName(), "size", sz, "bytes"));
g_totalDownloadedBytes += sz;
LOG(LDEBUG, ("totalDownloadedBytes:", g_totalDownloadedBytes));
g_filesToDownload.pop_back();
}
JNIEnv * env = jni::GetEnv();
jmethodID methodID = jni::GetMethodID(env, *obj, "onFinish", "(I)V");
env->CallVoidMethod(*obj, methodID, errorCode);
}
static void DownloadFileProgress(std::shared_ptr<jobject> listener, HttpRequest const & req)
{
JNIEnv * env = jni::GetEnv();
static jmethodID methodID = jni::GetMethodID(env, *listener, "onProgress", "(I)V");
env->CallVoidMethod(*listener, methodID, static_cast<jint>(g_totalDownloadedBytes + req.GetProgress().m_bytesDownloaded));
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeStartNextFileDownload(JNIEnv * env, jclass clazz, jobject listener)
{
if (g_filesToDownload.empty())
return ERR_NO_MORE_FILES;
/// @todo One downloader instance with cached servers. All this routine will be refactored some time.
static auto downloader = storage::GetDownloader();
storage::Storage const & storage = g_framework->GetStorage();
downloader->SetDataVersion(storage.GetCurrentDataVersion());
downloader->EnsureMetaConfigReady([&storage, ptr = jni::make_global_ref(listener)]()
{
auto const & curFile = g_filesToDownload.back();
auto const fileName = curFile.GetFileName(MapFileType::Map);
LOG(LINFO, ("Downloading file", fileName));
g_currentRequest.reset(HttpRequest::GetFile(
downloader->MakeUrlListLegacy(fileName),
storage.GetFilePath(curFile.GetName(), MapFileType::Map),
curFile.GetRemoteSize(),
std::bind(&DownloadFileFinished, ptr, _1),
std::bind(&DownloadFileProgress, ptr, _1),
0, false));
});
return ERR_FILE_IN_PROGRESS;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeCancelCurrentFile(JNIEnv * env, jclass clazz)
{
LOG(LDEBUG, ("cancelCurrentFile, currentRequest=", g_currentRequest));
g_currentRequest.reset();
default: return static_cast<int>(fileSize);
}
}
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeGetBytesToDownload(JNIEnv * env,
jclass clazz)
{
// clear all
g_filesToDownload.clear();
g_totalBytesToDownload = 0;
g_totalDownloadedBytes = 0;
using namespace storage;
Storage const & storage = g_framework->GetStorage();
auto const status = storage.GetForceDownloadWorlds(g_filesToDownload);
for (auto const & cf : g_filesToDownload)
g_totalBytesToDownload += cf.GetRemoteSize();
int res;
if (status == Storage::WorldStatus::ERROR_CREATE_FOLDER || status == Storage::WorldStatus::ERROR_MOVE_FILE)
{
res = ERR_DISK_ERROR;
}
else
{
Platform & pl = GetPlatform();
res = HasSpaceForFiles(pl, pl.WritableDir(), g_totalBytesToDownload);
}
if (res == ERR_STORAGE_DISCONNECTED)
LOG(LWARNING, ("External file system is not available"));
else if (res == ERR_NOT_ENOUGH_FREE_SPACE)
LOG(LWARNING, ("Not enough space to extract files"));
g_currentRequest.reset();
if (status == Storage::WorldStatus::WAS_MOVED)
{
g_framework->ReloadWorldMaps();
res = ERR_DOWNLOAD_SUCCESS; // reset possible storage error if we moved files
}
return res;
}
static void DownloadFileFinished(std::shared_ptr<jobject> obj, HttpRequest const & req)
{
auto const status = req.GetStatus();
ASSERT_NOT_EQUAL(status, DownloadStatus::InProgress, ());
int errorCode = ERR_DOWNLOAD_ERROR;
if (status == DownloadStatus::Completed)
errorCode = ERR_DOWNLOAD_SUCCESS;
g_currentRequest.reset();
if (errorCode == ERR_DOWNLOAD_SUCCESS)
{
auto const & curFile = g_filesToDownload.back();
size_t const sz = curFile.GetRemoteSize();
LOG(LDEBUG, ("finished downloading", curFile.GetName(), "size", sz, "bytes"));
g_totalDownloadedBytes += sz;
LOG(LDEBUG, ("totalDownloadedBytes:", g_totalDownloadedBytes));
g_filesToDownload.pop_back();
}
JNIEnv * env = jni::GetEnv();
jmethodID methodID = jni::GetMethodID(env, *obj, "onFinish", "(I)V");
env->CallVoidMethod(*obj, methodID, errorCode);
}
static void DownloadFileProgress(std::shared_ptr<jobject> listener, HttpRequest const & req)
{
JNIEnv * env = jni::GetEnv();
static jmethodID methodID = jni::GetMethodID(env, *listener, "onProgress", "(I)V");
env->CallVoidMethod(*listener, methodID,
static_cast<jint>(g_totalDownloadedBytes + req.GetProgress().m_bytesDownloaded));
}
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeStartNextFileDownload(
JNIEnv * env, jclass clazz, jobject listener)
{
if (g_filesToDownload.empty())
return ERR_NO_MORE_FILES;
/// @todo One downloader instance with cached servers. All this routine will be refactored some time.
static auto downloader = storage::GetDownloader();
storage::Storage const & storage = g_framework->GetStorage();
downloader->SetDataVersion(storage.GetCurrentDataVersion());
downloader->EnsureMetaConfigReady([&storage, ptr = jni::make_global_ref(listener)]()
{
auto const & curFile = g_filesToDownload.back();
auto const fileName = curFile.GetFileName(MapFileType::Map);
LOG(LINFO, ("Downloading file", fileName));
g_currentRequest.reset(HttpRequest::GetFile(downloader->MakeUrlListLegacy(fileName),
storage.GetFilePath(curFile.GetName(), MapFileType::Map),
curFile.GetRemoteSize(), std::bind(&DownloadFileFinished, ptr, _1),
std::bind(&DownloadFileProgress, ptr, _1), 0, false));
});
return ERR_FILE_IN_PROGRESS;
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeCancelCurrentFile(JNIEnv * env,
jclass clazz)
{
LOG(LDEBUG, ("cancelCurrentFile, currentRequest=", g_currentRequest));
g_currentRequest.reset();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,9 +10,8 @@
#include "drape_frontend/gui/skin.hpp"
#include "drape/pointers.hpp"
#include "drape/graphics_context_factory.hpp"
#include "drape/pointers.hpp"
#include "indexer/feature_decl.hpp"
#include "indexer/map_style.hpp"
@@ -39,186 +38,178 @@ struct EverywhereSearchParams;
namespace android
{
enum CoordinatesFormat // See Java enum app.organicmaps.widget.placepage.CoordinatesFormat for all possible values.
enum CoordinatesFormat // See Java enum app.organicmaps.widget.placepage.CoordinatesFormat for all possible values.
{
LatLonDMS = 0, // Latitude, Longitude in degrees minutes seconds format, comma separated
LatLonDecimal = 1, // Latitude, Longitude in decimal format, comma separated
OLCFull = 2, // Open location code, full format
OSMLink = 3, // Link to the OSM. E.g. https://osm.org/go/xcXjyqQlq-?m=
UTM = 4, // Universal Transverse Mercator
MGRS = 5 // Military Grid Reference System
};
// Keep in sync `public @interface ChoosePositionMode`in Framework.java.
enum class ChoosePositionMode
{
None = 0,
Editor = 1,
Api = 2,
};
class Framework : private power_management::PowerManager::Subscriber
{
private:
drape_ptr<dp::ThreadSafeFactory> m_oglContextFactory;
drape_ptr<dp::GraphicsContextFactory> m_vulkanContextFactory;
::Framework m_work;
math::LowPassVector<float, 3> m_sensors[2];
double m_lastCompass = 0;
std::string m_searchQuery;
std::map<gui::EWidget, gui::Position> m_guiPositions;
void TrafficStateChanged(TrafficManager::TrafficState state);
void TransitSchemeStateChanged(TransitReadManager::TransitSchemeState state);
void IsolinesSchemeStateChanged(IsolinesManager::IsolinesState state);
void MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive);
location::TMyPositionModeChanged m_myPositionModeSignal;
TrafficManager::TrafficStateChangedFn m_onTrafficStateChangedFn;
TransitReadManager::TransitStateChangedFn m_onTransitStateChangedFn;
IsolinesManager::IsolinesStateChangedFn m_onIsolinesStateChangedFn;
ChoosePositionMode m_isChoosePositionMode = ChoosePositionMode::None;
bool m_isSurfaceDestroyed = false;
public:
Framework(std::function<void()> && afterMapsLoaded);
storage::Storage & GetStorage();
DataSource const & GetDataSource();
void ShowNode(storage::CountryId const & countryId, bool zoomToDownloadButton);
void OnLocationError(int /* == location::TLocationStatus*/ newStatus);
void OnLocationUpdated(location::GpsInfo const & info);
void OnCompassUpdated(location::CompassInfo const & info, bool forceRedraw);
bool CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi, bool firstLaunch, bool launchByDeepLink,
uint32_t appVersionCode, bool isCustomROM);
bool IsDrapeEngineCreated() const;
void UpdateDpi(int dpi);
bool DestroySurfaceOnDetach();
void DetachSurface(bool destroySurface);
bool AttachSurface(JNIEnv * env, jobject jSurface);
void PauseSurfaceRendering();
void ResumeSurfaceRendering();
void SetMapStyle(MapStyle mapStyle);
void MarkMapStyle(MapStyle mapStyle);
MapStyle GetMapStyle() const;
void SetupMeasurementSystem();
RoutingManager & GetRoutingManager() { return m_work.GetRoutingManager(); }
void SetRouter(routing::RouterType type) { m_work.GetRoutingManager().SetRouter(type); }
routing::RouterType GetRouter() const { return m_work.GetRoutingManager().GetRouter(); }
routing::RouterType GetLastUsedRouter() const { return m_work.GetRoutingManager().GetLastUsedRouter(); }
void Resize(JNIEnv * env, jobject jSurface, int w, int h);
struct Finger
{
LatLonDMS = 0, // Latitude, Longitude in degrees minutes seconds format, comma separated
LatLonDecimal = 1, // Latitude, Longitude in decimal format, comma separated
OLCFull = 2, // Open location code, full format
OSMLink = 3, // Link to the OSM. E.g. https://osm.org/go/xcXjyqQlq-?m=
UTM = 4, // Universal Transverse Mercator
MGRS = 5 // Military Grid Reference System
Finger(int64_t id, float x, float y) : m_id(id), m_x(x), m_y(y) {}
int64_t m_id;
float m_x, m_y;
};
// Keep in sync `public @interface ChoosePositionMode`in Framework.java.
enum class ChoosePositionMode
{
None = 0,
Editor = 1,
Api = 2,
};
void Scale(double factor, m2::PointD const & pxPoint, bool isAnim);
class Framework : private power_management::PowerManager::Subscriber
{
private:
drape_ptr<dp::ThreadSafeFactory> m_oglContextFactory;
drape_ptr<dp::GraphicsContextFactory> m_vulkanContextFactory;
::Framework m_work;
void Scroll(double distanceX, double distanceY);
math::LowPassVector<float, 3> m_sensors[2];
double m_lastCompass = 0;
void Touch(int action, Finger const & f1, Finger const & f2, uint8_t maskedPointer);
std::string m_searchQuery;
bool Search(search::EverywhereSearchParams const & params);
std::string GetLastSearchQuery() { return m_searchQuery; }
void ClearLastSearchQuery() { m_searchQuery.clear(); }
std::map<gui::EWidget, gui::Position> m_guiPositions;
void AddLocalMaps();
void RemoveLocalMaps();
void ReloadWorldMaps();
void TrafficStateChanged(TrafficManager::TrafficState state);
void TransitSchemeStateChanged(TransitReadManager::TransitSchemeState state);
void IsolinesSchemeStateChanged(IsolinesManager::IsolinesState state);
m2::PointD GetViewportCenter() const;
void MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive);
void AddString(std::string const & name, std::string const & value);
location::TMyPositionModeChanged m_myPositionModeSignal;
void Scale(::Framework::EScaleMode mode);
void Scale(m2::PointD const & centerPt, int targetZoom, bool animate);
TrafficManager::TrafficStateChangedFn m_onTrafficStateChangedFn;
TransitReadManager::TransitStateChangedFn m_onTransitStateChangedFn;
IsolinesManager::IsolinesStateChangedFn m_onIsolinesStateChangedFn;
void ChangeTrackColor(kml::TrackId trackId, dp::Color color);
void ReplaceBookmark(kml::MarkId markId, kml::BookmarkData & bm);
void ReplaceTrack(kml::TrackId trackId, kml::TrackData & trackData);
void MoveBookmark(kml::MarkId markId, kml::MarkGroupId curCat, kml::MarkGroupId newCat);
void MoveTrack(kml::TrackId trackId, kml::MarkGroupId curCat, kml::MarkGroupId newCat);
ChoosePositionMode m_isChoosePositionMode = ChoosePositionMode::None;
bool m_isSurfaceDestroyed = false;
::Framework * NativeFramework();
public:
Framework(std::function<void()> && afterMapsLoaded);
bool IsDownloadingActive();
storage::Storage & GetStorage();
DataSource const & GetDataSource();
void ExecuteMapApiRequest();
void ShowNode(storage::CountryId const & countryId, bool zoomToDownloadButton);
void DeactivatePopup();
void DeactivateMapSelectionCircle(bool restoreViewport);
void OnLocationError(int/* == location::TLocationStatus*/ newStatus);
void OnLocationUpdated(location::GpsInfo const & info);
void OnCompassUpdated(location::CompassInfo const & info, bool forceRedraw);
// std::string GetOutdatedCountriesString();
bool CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi, bool firstLaunch,
bool launchByDeepLink, uint32_t appVersionCode, bool isCustomROM);
bool IsDrapeEngineCreated() const;
void UpdateDpi(int dpi);
bool DestroySurfaceOnDetach();
void DetachSurface(bool destroySurface);
bool AttachSurface(JNIEnv * env, jobject jSurface);
void PauseSurfaceRendering();
void ResumeSurfaceRendering();
void SetMyPositionModeListener(location::TMyPositionModeChanged const & fn);
location::EMyPositionMode GetMyPositionMode() const;
void SwitchMyPositionNextMode();
void SetMapStyle(MapStyle mapStyle);
void MarkMapStyle(MapStyle mapStyle);
MapStyle GetMapStyle() const;
void SetTrafficStateListener(TrafficManager::TrafficStateChangedFn const & fn);
void SetTransitSchemeListener(TransitReadManager::TransitStateChangedFn const & fn);
void SetIsolinesListener(IsolinesManager::IsolinesStateChangedFn const & fn);
void SetupMeasurementSystem();
bool IsTrafficEnabled();
void EnableTraffic();
void DisableTraffic();
RoutingManager & GetRoutingManager() { return m_work.GetRoutingManager(); }
void SetRouter(routing::RouterType type) { m_work.GetRoutingManager().SetRouter(type); }
routing::RouterType GetRouter() const { return m_work.GetRoutingManager().GetRouter(); }
routing::RouterType GetLastUsedRouter() const
{
return m_work.GetRoutingManager().GetLastUsedRouter();
}
void Save3dMode(bool allow3d, bool allow3dBuildings);
void Set3dMode(bool allow3d, bool allow3dBuildings);
void Get3dMode(bool & allow3d, bool & allow3dBuildings);
TrafficManager & GetTrafficManager() { return m_work.GetTrafficManager(); }
TrafficManager & GetTrafficManager() { return m_work.GetTrafficManager(); }
void Resize(JNIEnv * env, jobject jSurface, int w, int h);
void SetMapLanguageCode(std::string const & languageCode);
std::string GetMapLanguageCode();
struct Finger
{
Finger(int64_t id, float x, float y)
: m_id(id)
, m_x(x)
, m_y(y)
{
}
void SetChoosePositionMode(ChoosePositionMode mode, bool isBusiness, m2::PointD const * optionalPosition);
ChoosePositionMode GetChoosePositionMode();
int64_t m_id;
float m_x, m_y;
};
void UpdateMyPositionRoutingOffset(int offsetY);
void SetupWidget(gui::EWidget widget, float x, float y, dp::Anchor anchor);
void ApplyWidgets();
void CleanWidgets();
void Scale(double factor, m2::PointD const & pxPoint, bool isAnim);
place_page::Info & GetPlacePageInfo();
void Scroll(double distanceX, double distanceY);
bool IsAutoRetryDownloadFailed();
bool IsDownloadOn3gEnabled();
void EnableDownloadOn3g();
void Touch(int action, Finger const & f1, Finger const & f2, uint8_t maskedPointer);
// int ToDoAfterUpdate() const;
bool Search(search::EverywhereSearchParams const & params);
std::string GetLastSearchQuery() { return m_searchQuery; }
void ClearLastSearchQuery() { m_searchQuery.clear(); }
// PowerManager::Subscriber overrides:
void OnPowerFacilityChanged(power_management::Facility const facility, bool enabled) override;
void OnPowerSchemeChanged(power_management::Scheme const actualScheme) override;
void AddLocalMaps();
void RemoveLocalMaps();
void ReloadWorldMaps();
m2::PointD GetViewportCenter() const;
void AddString(std::string const & name, std::string const & value);
void Scale(::Framework::EScaleMode mode);
void Scale(m2::PointD const & centerPt, int targetZoom, bool animate);
void ChangeTrackColor(kml::TrackId trackId, dp::Color color);
void ReplaceBookmark(kml::MarkId markId, kml::BookmarkData & bm);
void ReplaceTrack(kml::TrackId trackId, kml::TrackData & trackData);
void MoveBookmark(kml::MarkId markId, kml::MarkGroupId curCat, kml::MarkGroupId newCat);
void MoveTrack(kml::TrackId trackId, kml::MarkGroupId curCat, kml::MarkGroupId newCat);
::Framework * NativeFramework();
bool IsDownloadingActive();
void ExecuteMapApiRequest();
void DeactivatePopup();
void DeactivateMapSelectionCircle(bool restoreViewport);
// std::string GetOutdatedCountriesString();
void SetMyPositionModeListener(location::TMyPositionModeChanged const & fn);
location::EMyPositionMode GetMyPositionMode() const;
void SwitchMyPositionNextMode();
void SetTrafficStateListener(TrafficManager::TrafficStateChangedFn const & fn);
void SetTransitSchemeListener(TransitReadManager::TransitStateChangedFn const & fn);
void SetIsolinesListener(IsolinesManager::IsolinesStateChangedFn const & fn);
bool IsTrafficEnabled();
void EnableTraffic();
void DisableTraffic();
void Save3dMode(bool allow3d, bool allow3dBuildings);
void Set3dMode(bool allow3d, bool allow3dBuildings);
void Get3dMode(bool & allow3d, bool & allow3dBuildings);
void SetMapLanguageCode(std::string const & languageCode);
std::string GetMapLanguageCode();
void SetChoosePositionMode(ChoosePositionMode mode, bool isBusiness, m2::PointD const * optionalPosition);
ChoosePositionMode GetChoosePositionMode();
void UpdateMyPositionRoutingOffset(int offsetY);
void SetupWidget(gui::EWidget widget, float x, float y, dp::Anchor anchor);
void ApplyWidgets();
void CleanWidgets();
place_page::Info & GetPlacePageInfo();
bool IsAutoRetryDownloadFailed();
bool IsDownloadOn3gEnabled();
void EnableDownloadOn3g();
// int ToDoAfterUpdate() const;
// PowerManager::Subscriber overrides:
void OnPowerFacilityChanged(power_management::Facility const facility, bool enabled) override;
void OnPowerSchemeChanged(power_management::Scheme const actualScheme) override;
FeatureID BuildFeatureId(JNIEnv * env, jobject featureId);
};
}
FeatureID BuildFeatureId(JNIEnv * env, jobject featureId);
};
} // namespace android
extern std::unique_ptr<android::Framework> g_framework;
::Framework * frm();

View File

@@ -7,26 +7,23 @@
extern "C"
{
static void LocationStateModeChanged(location::EMyPositionMode mode,
std::shared_ptr<jobject> const & listener)
static void LocationStateModeChanged(location::EMyPositionMode mode, std::shared_ptr<jobject> const & listener)
{
JNIEnv * env = jni::GetEnv();
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener.get(),
"onMyPositionModeChanged", "(I)V"), static_cast<jint>(mode));
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener.get(), "onMyPositionModeChanged", "(I)V"),
static_cast<jint>(mode));
}
// public static void nativeSwitchToNextMode();
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeSwitchToNextMode(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeSwitchToNextMode(JNIEnv * env,
jclass clazz)
{
ASSERT(g_framework, ());
g_framework->SwitchMyPositionNextMode();
}
// private static int nativeGetMode();
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeGetMode(JNIEnv * env, jclass clazz)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeGetMode(JNIEnv * env, jclass clazz)
{
// GetMyPositionMode() is initialized only after drape creation.
// https://github.com/organicmaps/organicmaps/issues/1128#issuecomment-1784435190
@@ -35,34 +32,31 @@ Java_app_organicmaps_sdk_location_LocationState_nativeGetMode(JNIEnv * env, jcla
}
// public static void nativeSetListener(ModeChangeListener listener);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeSetListener(JNIEnv * env, jclass clazz,
jobject listener)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeSetListener(JNIEnv * env, jclass clazz,
jobject listener)
{
ASSERT(g_framework, ());
g_framework->SetMyPositionModeListener(std::bind(&LocationStateModeChanged, std::placeholders::_1,
jni::make_global_ref(listener)));
g_framework->SetMyPositionModeListener(
std::bind(&LocationStateModeChanged, std::placeholders::_1, jni::make_global_ref(listener)));
}
// public static void nativeRemoveListener();
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeRemoveListener(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeRemoveListener(JNIEnv * env, jclass clazz)
{
ASSERT(g_framework, ());
g_framework->SetMyPositionModeListener(location::TMyPositionModeChanged());
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeOnLocationError(JNIEnv * env, jclass clazz, int errorCode)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeOnLocationError(JNIEnv * env, jclass clazz,
int errorCode)
{
ASSERT(g_framework, ());
g_framework->OnLocationError(errorCode);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeLocationUpdated(JNIEnv * env, jclass clazz, jlong time,
jdouble lat, jdouble lon, jfloat accuracy,
jdouble altitude, jfloat speed, jfloat bearing)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeLocationUpdated(
JNIEnv * env, jclass clazz, jlong time, jdouble lat, jdouble lon, jfloat accuracy, jdouble altitude, jfloat speed,
jfloat bearing)
{
ASSERT(g_framework, ());
location::GpsInfo info;
@@ -90,4 +84,4 @@ Java_app_organicmaps_sdk_location_LocationState_nativeLocationUpdated(JNIEnv * e
g_framework->OnLocationUpdated(info);
GpsTracker::Instance().OnLocationUpdated(info);
}
} // extern "C"
} // extern "C"

View File

@@ -15,51 +15,43 @@ namespace
void OnRenderingInitializationFinished(std::shared_ptr<jobject> const & listener)
{
JNIEnv * env = jni::GetEnv();
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener.get(),
"onRenderingInitializationFinished", "()V"));
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener.get(), "onRenderingInitializationFinished", "()V"));
}
} // namespace
extern "C"
{
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_Map_nativeCreateEngine(JNIEnv * env, jclass,
jobject surface, jint density,
jboolean firstLaunch,
jboolean isLaunchByDeepLink,
jint appVersionCode,
jboolean isCustomROM)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_Map_nativeCreateEngine(JNIEnv * env, jclass, jobject surface,
jint density, jboolean firstLaunch,
jboolean isLaunchByDeepLink,
jint appVersionCode, jboolean isCustomROM)
{
return g_framework->CreateDrapeEngine(env, surface, density, firstLaunch, isLaunchByDeepLink,
base::asserted_cast<uint32_t>(appVersionCode), isCustomROM);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_Map_nativeIsEngineCreated(JNIEnv *, jclass)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_Map_nativeIsEngineCreated(JNIEnv *, jclass)
{
return g_framework->IsDrapeEngineCreated();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeUpdateEngineDpi(JNIEnv *, jclass, jint dpi)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeUpdateEngineDpi(JNIEnv *, jclass, jint dpi)
{
return g_framework->UpdateDpi(dpi);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeExecuteMapApiRequest(JNIEnv * env, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeExecuteMapApiRequest(JNIEnv * env, jclass)
{
return g_framework->ExecuteMapApiRequest();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeSetRenderingInitializationFinishedListener(
JNIEnv *, jclass, jobject listener)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeSetRenderingInitializationFinishedListener(JNIEnv *, jclass,
jobject listener)
{
if (listener)
{
g_framework->NativeFramework()->SetGraphicsContextInitializationHandler(
std::bind(&OnRenderingInitializationFinished, jni::make_global_ref(listener)));
std::bind(&OnRenderingInitializationFinished, jni::make_global_ref(listener)));
}
else
{
@@ -67,69 +59,61 @@ Java_app_organicmaps_sdk_Map_nativeSetRenderingInitializationFinishedListener(
}
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_Map_nativeAttachSurface(JNIEnv * env, jclass, jobject surface)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_Map_nativeAttachSurface(JNIEnv * env, jclass, jobject surface)
{
return g_framework->AttachSurface(env, surface);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeDetachSurface(JNIEnv *, jclass, jboolean destroySurface)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeDetachSurface(JNIEnv *, jclass, jboolean destroySurface)
{
g_framework->DetachSurface(destroySurface);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeSurfaceChanged(JNIEnv * env, jclass, jobject surface, jint w, jint h)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeSurfaceChanged(JNIEnv * env, jclass, jobject surface, jint w,
jint h)
{
g_framework->Resize(env, surface, w, h);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_Map_nativeDestroySurfaceOnDetach(JNIEnv *, jclass)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_Map_nativeDestroySurfaceOnDetach(JNIEnv *, jclass)
{
return g_framework->DestroySurfaceOnDetach();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativePauseSurfaceRendering(JNIEnv *, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativePauseSurfaceRendering(JNIEnv *, jclass)
{
g_framework->PauseSurfaceRendering();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeResumeSurfaceRendering(JNIEnv *, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeResumeSurfaceRendering(JNIEnv *, jclass)
{
g_framework->ResumeSurfaceRendering();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeUpdateMyPositionRoutingOffset(JNIEnv * env, jclass clazz, int offsetY)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeUpdateMyPositionRoutingOffset(JNIEnv * env, jclass clazz,
int offsetY)
{
g_framework->UpdateMyPositionRoutingOffset(offsetY);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeApplyWidgets(JNIEnv *, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeApplyWidgets(JNIEnv *, jclass)
{
g_framework->ApplyWidgets();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeCleanWidgets(JNIEnv *, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeCleanWidgets(JNIEnv *, jclass)
{
g_framework->CleanWidgets();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeSetupWidget(
JNIEnv *, jclass, jint widget, jfloat x, jfloat y, jint anchor)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeSetupWidget(JNIEnv *, jclass, jint widget, jfloat x, jfloat y,
jint anchor)
{
g_framework->SetupWidget(static_cast<gui::EWidget>(widget), x, y, static_cast<dp::Anchor>(anchor));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeCompassUpdated(JNIEnv *, jclass, jdouble north, jboolean forceRedraw)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeCompassUpdated(JNIEnv *, jclass, jdouble north,
jboolean forceRedraw)
{
location::CompassInfo info;
info.m_bearing = north;
@@ -137,54 +121,45 @@ Java_app_organicmaps_sdk_Map_nativeCompassUpdated(JNIEnv *, jclass, jdouble nort
g_framework->OnCompassUpdated(info, forceRedraw);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeScalePlus(JNIEnv *, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeScalePlus(JNIEnv *, jclass)
{
g_framework->Scale(::Framework::SCALE_MAG);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeScaleMinus(JNIEnv *, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeScaleMinus(JNIEnv *, jclass)
{
g_framework->Scale(::Framework::SCALE_MIN);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeOnScroll(
JNIEnv *, jclass, jdouble distanceX, jdouble distanceY)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeOnScroll(JNIEnv *, jclass, jdouble distanceX,
jdouble distanceY)
{
g_framework->Scroll(distanceX, distanceY);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeOnScale(
JNIEnv *, jclass, jdouble factor, jdouble focusX, jdouble focusY, jboolean isAnim)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeOnScale(JNIEnv *, jclass, jdouble factor, jdouble focusX,
jdouble focusY, jboolean isAnim)
{
g_framework->Scale(factor, {focusX, focusY}, isAnim);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeOnTouch(JNIEnv *, jclass, jint action,
jint id1, jfloat x1, jfloat y1,
jint id2, jfloat x2, jfloat y2,
jint maskedPointer)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeOnTouch(JNIEnv *, jclass, jint action, jint id1, jfloat x1,
jfloat y1, jint id2, jfloat x2, jfloat y2,
jint maskedPointer)
{
g_framework->Touch(action,
android::Framework::Finger(id1, x1, y1),
android::Framework::Finger(id2, x2, y2), maskedPointer);
g_framework->Touch(action, android::Framework::Finger(id1, x1, y1), android::Framework::Finger(id2, x2, y2),
maskedPointer);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeStorageConnected(JNIEnv *, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeStorageConnected(JNIEnv *, jclass)
{
android::Platform::Instance().OnExternalStorageStatusChanged(true);
g_framework->AddLocalMaps();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeStorageDisconnected(JNIEnv *, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Map_nativeStorageDisconnected(JNIEnv *, jclass)
{
android::Platform::Instance().OnExternalStorageStatusChanged(false);
g_framework->RemoveLocalMaps();
}
} // extern "C"
} // extern "C"

View File

@@ -21,7 +21,6 @@
#include <unordered_map>
#include <vector>
namespace
{
// The last 5% are left for applying diffs.
@@ -44,7 +43,10 @@ struct TBatchedData
TBatchedData(storage::CountryId const & countryId, storage::NodeStatus const newStatus,
storage::NodeErrorCode const errorCode, bool isLeaf)
: m_countryId(countryId), m_newStatus(newStatus), m_errorCode(errorCode), m_isLeaf(isLeaf)
: m_countryId(countryId)
, m_newStatus(newStatus)
, m_errorCode(errorCode)
, m_isLeaf(isLeaf)
{}
};
@@ -64,11 +66,11 @@ struct CountryItemBuilder
{
jclass m_class;
jmethodID m_ctor;
jfieldID m_Id, m_Name, m_DirectParentId, m_TopmostParentId, m_DirectParentName, m_TopmostParentName,
m_Description, m_Size, m_EnqueuedSize, m_TotalSize, m_ChildCount, m_TotalChildCount,
m_Present, m_Progress, m_DownloadedBytes, m_BytesToDownload, m_Category, m_Status, m_ErrorCode;
jfieldID m_Id, m_Name, m_DirectParentId, m_TopmostParentId, m_DirectParentName, m_TopmostParentName, m_Description,
m_Size, m_EnqueuedSize, m_TotalSize, m_ChildCount, m_TotalChildCount, m_Present, m_Progress, m_DownloadedBytes,
m_BytesToDownload, m_Category, m_Status, m_ErrorCode;
CountryItemBuilder(JNIEnv *env)
CountryItemBuilder(JNIEnv * env)
{
m_class = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/downloader/CountryItem");
m_ctor = jni::GetConstructorID(env, m_class, "(Ljava/lang/String;)V");
@@ -95,10 +97,7 @@ struct CountryItemBuilder
}
DECLARE_BUILDER_INSTANCE(CountryItemBuilder);
jobject Create(JNIEnv * env, jobject id) const
{
return env->NewObject(m_class, m_ctor, id);
}
jobject Create(JNIEnv * env, jobject id) const { return env->NewObject(m_class, m_ctor, id); }
};
static storage::CountryId const GetRootId(JNIEnv * env, jstring root)
@@ -109,52 +108,54 @@ static storage::CountryId const GetRootId(JNIEnv * env, jstring root)
extern "C"
{
// static String nativeGetRoot();
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetRoot(JNIEnv * env, jclass clazz)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetRoot(JNIEnv * env, jclass clazz)
{
return jni::ToJavaString(env, GetStorage().GetRootId());
}
// static boolean nativeMoveFile(String oldFile, String newFile);
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeMoveFile(JNIEnv * env, jclass clazz, jstring oldFile, jstring newFile)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeMoveFile(JNIEnv * env, jclass clazz,
jstring oldFile,
jstring newFile)
{
return base::MoveFileX(jni::ToNativeString(env, oldFile), jni::ToNativeString(env, newFile));
}
// static boolean nativeHasSpaceToDownloadAmount(long bytes);
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToDownloadAmount(JNIEnv * env, jclass clazz, jlong bytes)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToDownloadAmount(JNIEnv * env,
jclass clazz,
jlong bytes)
{
return storage::IsEnoughSpaceForDownload(bytes);
}
// static boolean nativeHasSpaceToDownloadCountry(String root);
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToDownloadCountry(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToDownloadCountry(JNIEnv * env,
jclass clazz,
jstring root)
{
return storage::IsEnoughSpaceForDownload(jni::ToNativeString(env, root), GetStorage());
}
// static boolean nativeHasSpaceToUpdate(String root);
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToUpdate(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToUpdate(JNIEnv * env,
jclass clazz,
jstring root)
{
return IsEnoughSpaceForUpdate(jni::ToNativeString(env, root), GetStorage());
}
// static int nativeGetDownloadedCount();
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetDownloadedCount(JNIEnv * env, jclass clazz)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetDownloadedCount(JNIEnv * env,
jclass clazz)
{
return static_cast<jint>(GetStorage().GetDownloadedFilesCount());
}
// static @Nullable UpdateInfo nativeGetUpdateInfo(@Nullable String root);
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetUpdateInfo(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetUpdateInfo(JNIEnv * env, jclass clazz,
jstring root)
{
storage::Storage::UpdateInfo info;
if (!GetStorage().GetUpdateInfo(GetRootId(env, root), info))
@@ -168,7 +169,8 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeGetUpdateInfo(JNIEnv * env,
return env->NewObject(infoClass, ctor, info.m_numberOfMwmFilesToUpdate, info.m_totalDownloadSizeInBytes);
}
static void UpdateItemShort(JNIEnv * env, jobject item, storage::NodeStatus const status, storage::NodeErrorCode const error)
static void UpdateItemShort(JNIEnv * env, jobject item, storage::NodeStatus const status,
storage::NodeErrorCode const error)
{
auto const & ciBuilder = CountryItemBuilder::Instance(env);
@@ -211,7 +213,8 @@ static void UpdateItem(JNIEnv * env, jobject item, storage::NodeAttrs const & at
}
// Description
env->SetObjectField(item, ciBuilder.m_Description, SLR(env, jni::ToJavaString(env, attrs.m_nodeLocalDescription)).get());
env->SetObjectField(item, ciBuilder.m_Description,
SLR(env, jni::ToJavaString(env, attrs.m_nodeLocalDescription)).get());
// Sizes
env->SetLongField(item, ciBuilder.m_Size, attrs.m_localMwmSize);
@@ -267,18 +270,21 @@ static void PutItemsToList(
}
}
// static void nativeListItems(@Nullable String root, double lat, double lon, boolean hasLocation, boolean myMapsMode, List<CountryItem> result);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeListItems(JNIEnv * env, jclass clazz, jstring parent, jdouble lat, jdouble lon, jboolean hasLocation, jboolean myMapsMode, jobject result)
// static void nativeListItems(@Nullable String root, double lat, double lon, boolean hasLocation, boolean myMapsMode,
// List<CountryItem> result);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeListItems(JNIEnv * env, jclass clazz,
jstring parent, jdouble lat,
jdouble lon, jboolean hasLocation,
jboolean myMapsMode,
jobject result)
{
if (hasLocation && !myMapsMode)
{
storage::CountriesVec near;
g_framework->NativeFramework()->GetCountryInfoGetter().GetRegionsCountryId(mercator::FromLatLon(lat, lon), near);
PutItemsToList(env, result, near, ItemCategory::NEAR_ME,
[](storage::CountryId const & countryId, storage::NodeAttrs const & attrs) -> bool {
return !attrs.m_present;
});
[](storage::CountryId const & countryId, storage::NodeAttrs const & attrs) -> bool
{ return !attrs.m_present; });
}
storage::CountriesVec downloaded, available;
@@ -291,8 +297,8 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeListItems(JNIEnv * env, jcl
}
// static void nativeUpdateItem(CountryItem item);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetAttributes(JNIEnv * env, jclass, jobject item)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetAttributes(JNIEnv * env, jclass,
jobject item)
{
auto const & ciBuilder = CountryItemBuilder::Instance(env);
jstring id = static_cast<jstring>(env->GetObjectField(item, ciBuilder.m_Id));
@@ -304,8 +310,8 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeGetAttributes(JNIEnv * env,
}
// static void nativeGetStatus(String root);
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetStatus(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetStatus(JNIEnv * env, jclass clazz,
jstring root)
{
storage::NodeStatuses ns;
GetStorage().GetNodeStatuses(jni::ToNativeString(env, root), ns);
@@ -313,8 +319,8 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeGetStatus(JNIEnv * env, jcl
}
// static void nativeGetError(String root);
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetError(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetError(JNIEnv * env, jclass clazz,
jstring root)
{
storage::NodeStatuses ns;
GetStorage().GetNodeStatuses(jni::ToNativeString(env, root), ns);
@@ -322,22 +328,23 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeGetError(JNIEnv * env, jcla
}
// static String nativeGetName(String root);
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetName(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetName(JNIEnv * env, jclass clazz,
jstring root)
{
return jni::ToJavaString(env, GetStorage().GetNodeLocalName(jni::ToNativeString(env, root)));
}
// static @Nullable String nativeFindCountry(double lat, double lon);
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeFindCountry(JNIEnv * env, jclass clazz, jdouble lat, jdouble lon)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeFindCountry(JNIEnv * env, jclass clazz,
jdouble lat, jdouble lon)
{
return jni::ToJavaString(env, g_framework->NativeFramework()->GetCountryInfoGetter().GetRegionCountryId(mercator::FromLatLon(lat, lon)));
return jni::ToJavaString(
env, g_framework->NativeFramework()->GetCountryInfoGetter().GetRegionCountryId(mercator::FromLatLon(lat, lon)));
}
// static boolean nativeIsDownloading();
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeIsDownloading(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsDownloading(JNIEnv * env,
jclass clazz)
{
return static_cast<jboolean>(GetStorage().IsDownloadInProgress());
}
@@ -365,14 +372,14 @@ static void EndBatchingCallbacks(JNIEnv * env)
for (TBatchedData const & dataItem : key.second)
{
// Create StorageCallbackData instance…
static jclass batchDataClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/downloader/MapManager$StorageCallbackData");
static jclass batchDataClass =
jni::GetGlobalClassRef(env, "app/organicmaps/sdk/downloader/MapManager$StorageCallbackData");
static jmethodID batchDataCtor = jni::GetConstructorID(env, batchDataClass, "(Ljava/lang/String;IIZ)V");
jni::TScopedLocalRef const id(env, jni::ToJavaString(env, dataItem.m_countryId));
jni::TScopedLocalRef const item(env, env->NewObject(batchDataClass, batchDataCtor, id.get(),
static_cast<jint>(dataItem.m_newStatus),
static_cast<jint>(dataItem.m_errorCode),
dataItem.m_isLeaf));
jni::TScopedLocalRef const item(
env, env->NewObject(batchDataClass, batchDataCtor, id.get(), static_cast<jint>(dataItem.m_newStatus),
static_cast<jint>(dataItem.m_errorCode), dataItem.m_isLeaf));
// …and put it into the resulting list
env->CallBooleanMethod(list.get(), listBuilder.m_add, item.get());
}
@@ -387,8 +394,8 @@ static void EndBatchingCallbacks(JNIEnv * env)
}
// static void nativeDownload(String root);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeDownload(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeDownload(JNIEnv * env, jclass clazz,
jstring root)
{
StartBatchingCallbacks();
GetStorage().DownloadNode(jni::ToNativeString(env, root));
@@ -396,8 +403,8 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeDownload(JNIEnv * env, jcla
}
// static boolean nativeRetry(String root);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeRetry(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeRetry(JNIEnv * env, jclass clazz,
jstring root)
{
StartBatchingCallbacks();
GetStorage().RetryDownloadNode(jni::ToNativeString(env, root));
@@ -405,8 +412,8 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeRetry(JNIEnv * env, jclass
}
// static void nativeUpdate(String root);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeUpdate(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeUpdate(JNIEnv * env, jclass clazz,
jstring root)
{
StartBatchingCallbacks();
GetStorage().UpdateNode(GetRootId(env, root));
@@ -414,8 +421,8 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeUpdate(JNIEnv * env, jclass
}
// static void nativeCancel(String root);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeCancel(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeCancel(JNIEnv * env, jclass clazz,
jstring root)
{
StartBatchingCallbacks();
GetStorage().CancelDownloadNode(GetRootId(env, root));
@@ -423,8 +430,8 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeCancel(JNIEnv * env, jclass
}
// static void nativeDelete(String root);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeDelete(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeDelete(JNIEnv * env, jclass clazz,
jstring root)
{
StartBatchingCallbacks();
auto const countryId = jni::ToNativeString(env, root);
@@ -432,8 +439,7 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeDelete(JNIEnv * env, jclass
EndBatchingCallbacks(env);
}
static void StatusChangedCallback(std::shared_ptr<jobject> const & listenerRef,
storage::CountryId const & countryId)
static void StatusChangedCallback(std::shared_ptr<jobject> const & listenerRef, storage::CountryId const & countryId)
{
storage::NodeStatuses ns;
GetStorage().GetNodeStatuses(countryId, ns);
@@ -445,42 +451,48 @@ static void StatusChangedCallback(std::shared_ptr<jobject> const & listenerRef,
EndBatchingCallbacks(jni::GetEnv());
}
static void ProgressChangedCallback(std::shared_ptr<jobject> const & listenerRef,
storage::CountryId const & countryId, downloader::Progress const & progress)
static void ProgressChangedCallback(std::shared_ptr<jobject> const & listenerRef, storage::CountryId const & countryId,
downloader::Progress const & progress)
{
JNIEnv * env = jni::GetEnv();
jmethodID const methodID = jni::GetMethodID(env, *listenerRef, "onProgress", "(Ljava/lang/String;JJ)V");
env->CallVoidMethod(*listenerRef, methodID, jni::ToJavaString(env, countryId),
progress.m_bytesDownloaded, progress.m_bytesTotal);
env->CallVoidMethod(*listenerRef, methodID, jni::ToJavaString(env, countryId), progress.m_bytesDownloaded,
progress.m_bytesTotal);
}
// static int nativeSubscribe(StorageCallback listener);
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeSubscribe(JNIEnv * env, jclass clazz, jobject listener)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeSubscribe(JNIEnv * env, jclass clazz,
jobject listener)
{
return GetStorage().Subscribe(std::bind(&StatusChangedCallback, jni::make_global_ref(listener), std::placeholders::_1),
std::bind(&ProgressChangedCallback, jni::make_global_ref(listener), std::placeholders::_1, std::placeholders::_2));
return GetStorage().Subscribe(
std::bind(&StatusChangedCallback, jni::make_global_ref(listener), std::placeholders::_1),
std::bind(&ProgressChangedCallback, jni::make_global_ref(listener), std::placeholders::_1,
std::placeholders::_2));
}
// static void nativeUnsubscribe(int slot);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeUnsubscribe(JNIEnv * env, jclass clazz, jint slot)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeUnsubscribe(JNIEnv * env, jclass clazz,
jint slot)
{
GetStorage().Unsubscribe(slot);
}
// static void nativeSubscribeOnCountryChanged(CurrentCountryChangedListener listener);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeSubscribeOnCountryChanged(JNIEnv * env, jclass clazz, jobject listener)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeSubscribeOnCountryChanged(JNIEnv * env,
jclass clazz,
jobject listener)
{
ASSERT(!g_countryChangedListener, ());
g_countryChangedListener = env->NewGlobalRef(listener);
auto const callback = [](storage::CountryId const & countryId) {
auto const callback = [](storage::CountryId const & countryId)
{
JNIEnv * env = jni::GetEnv();
jmethodID methodID = jni::GetMethodID(env, g_countryChangedListener, "onCurrentCountryChanged", "(Ljava/lang/String;)V");
env->CallVoidMethod(g_countryChangedListener, methodID, jni::TScopedLocalRef(env, jni::ToJavaString(env, countryId)).get());
jmethodID methodID =
jni::GetMethodID(env, g_countryChangedListener, "onCurrentCountryChanged", "(Ljava/lang/String;)V");
env->CallVoidMethod(g_countryChangedListener, methodID,
jni::TScopedLocalRef(env, jni::ToJavaString(env, countryId)).get());
};
storage::CountryId const & prev = g_framework->NativeFramework()->GetLastReportedCountry();
@@ -491,8 +503,8 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeSubscribeOnCountryChanged(J
}
// static void nativeUnsubscribeOnCountryChanged();
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeUnsubscribeOnCountryChanged(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeUnsubscribeOnCountryChanged(JNIEnv * env,
jclass clazz)
{
g_framework->NativeFramework()->SetCurrentCountryChangedListener(nullptr);
@@ -501,15 +513,16 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeUnsubscribeOnCountryChanged
}
// static boolean nativeHasUnsavedEditorChanges(String root);
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeHasUnsavedEditorChanges(JNIEnv * env, jclass clazz, jstring root)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeHasUnsavedEditorChanges(JNIEnv * env,
jclass clazz,
jstring root)
{
return g_framework->NativeFramework()->HasUnsavedEdits(jni::ToNativeString(env, root));
}
// static void nativeGetPathTo(String root, List<String> result);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetPathTo(JNIEnv * env, jclass clazz, jstring root, jobject result)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetPathTo(JNIEnv * env, jclass clazz,
jstring root, jobject result)
{
auto const listAddMethod = jni::ListBuilder::Instance(env).m_add;
@@ -520,8 +533,9 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeGetPathTo(JNIEnv * env, jcl
}
// static int nativeGetOverallProgress(String[] countries);
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetOverallProgress(JNIEnv * env, jclass clazz, jobjectArray jcountries)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetOverallProgress(JNIEnv * env,
jclass clazz,
jobjectArray jcountries)
{
int const size = env->GetArrayLength(jcountries);
storage::CountriesVec countries;
@@ -543,29 +557,29 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeGetOverallProgress(JNIEnv *
}
// static boolean nativeIsAutoretryFailed();
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeIsAutoretryFailed(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsAutoretryFailed(JNIEnv * env,
jclass clazz)
{
return g_framework->IsAutoRetryDownloadFailed();
}
// static boolean nativeIsDownloadOn3gEnabled();
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeIsDownloadOn3gEnabled(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsDownloadOn3gEnabled(JNIEnv * env,
jclass clazz)
{
return g_framework->IsDownloadOn3gEnabled();
}
// static void nativeEnableDownloadOn3g();
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeEnableDownloadOn3g(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeEnableDownloadOn3g(JNIEnv * env,
jclass clazz)
{
g_framework->EnableDownloadOn3g();
}
// static @Nullable String nativeGetSelectedCountry();
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetSelectedCountry(JNIEnv * env, jclass clazz)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetSelectedCountry(JNIEnv * env,
jclass clazz)
{
if (!g_framework->NativeFramework()->HasPlacePageInfo())
return nullptr;
@@ -573,4 +587,4 @@ Java_app_organicmaps_sdk_downloader_MapManager_nativeGetSelectedCountry(JNIEnv *
storage::CountryId const & res = g_framework->GetPlacePageInfo().GetCountryId();
return (res == storage::kInvalidCountryId ? nullptr : jni::ToJavaString(env, res));
}
} // extern "C"
} // extern "C"

View File

@@ -17,8 +17,8 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeSetSettingsDir
// static void nativeInitPlatform(Context context, String apkPath, String storagePath, String privatePath, String
// tmpPath, String flavorName, String buildType, boolean isTablet);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeInitPlatform(
JNIEnv * env, jclass clazz, jobject context, jstring apkPath, jstring writablePath, jstring privatePath,
jstring tmpPath, jstring flavorName, jstring buildType, jboolean isTablet)
JNIEnv * env, jclass clazz, jobject context, jstring apkPath, jstring writablePath, jstring privatePath,
jstring tmpPath, jstring flavorName, jstring buildType, jboolean isTablet)
{
android::Platform::Instance().Initialize(env, context, apkPath, writablePath, privatePath, tmpPath, flavorName,
buildType, isTablet);
@@ -30,33 +30,32 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeInitFramework(
{
if (!g_framework)
{
g_framework = std::make_unique<android::Framework>(
[onComplete = jni::make_global_ref(onComplete)]()
{
JNIEnv * env = jni::GetEnv();
jmethodID const runId = jni::GetMethodID(env, *onComplete, "run", "()V");
env->CallVoidMethod(*onComplete, runId);
g_framework = std::make_unique<android::Framework>([onComplete = jni::make_global_ref_safe(onComplete)]()
{
JNIEnv * env = jni::GetEnv();
jmethodID const methodId = jni::GetMethodID(env, *onComplete, "run", "()V");
env->CallVoidMethod(*onComplete, methodId);
ASSERT(g_framework, ("g_framework must be non-null"));
ASSERT(g_framework, ("g_framework must be non-null"));
/*
* Add traffic sources for Android.
*/
jclass configClass = env->FindClass("app/organicmaps/sdk/util/Config");
jmethodID const getTrafficLegacyEnabledId = jni::GetStaticMethodID(env, configClass,
"getTrafficLegacyEnabled", "()Z");
jmethodID const applyTrafficLegacyEnabledId = jni::GetStaticMethodID(env, configClass,
"applyTrafficLegacyEnabled", "(Z)V");
jmethodID const getTrafficAppsId = jni::GetStaticMethodID(env, configClass,
"getTrafficApps", "()[Ljava/lang/String;");
jmethodID const applyTrafficAppsId = jni::GetStaticMethodID(env, configClass,
"applyTrafficApps", "([Ljava/lang/String;)V");
/*
* Add traffic sources for Android.
*/
jclass configClass = env->FindClass("app/organicmaps/sdk/util/Config");
jmethodID const getTrafficLegacyEnabledId = jni::GetStaticMethodID(env, configClass,
"getTrafficLegacyEnabled", "()Z");
jmethodID const applyTrafficLegacyEnabledId = jni::GetStaticMethodID(env, configClass,
"applyTrafficLegacyEnabled", "(Z)V");
jmethodID const getTrafficAppsId = jni::GetStaticMethodID(env, configClass,
"getTrafficApps", "()[Ljava/lang/String;");
jmethodID const applyTrafficAppsId = jni::GetStaticMethodID(env, configClass,
"applyTrafficApps", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(configClass, applyTrafficLegacyEnabledId,
env->CallStaticBooleanMethod(configClass, getTrafficLegacyEnabledId));
env->CallStaticVoidMethod(configClass, applyTrafficAppsId,
(jobjectArray)env->CallStaticObjectMethod(configClass, getTrafficAppsId));
});
env->CallStaticVoidMethod(configClass, applyTrafficLegacyEnabledId,
env->CallStaticBooleanMethod(configClass, getTrafficLegacyEnabledId));
env->CallStaticVoidMethod(configClass, applyTrafficAppsId,
(jobjectArray)env->CallStaticObjectMethod(configClass, getTrafficAppsId));
});
}
}

View File

@@ -8,52 +8,52 @@
extern "C"
{
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_TrackRecorder_nativeSetEnabled(JNIEnv * env, jclass clazz, jboolean enable)
{
GpsTracker::Instance().SetEnabled(enable);
Framework * const f = frm();
if (f == nullptr)
return;
if (enable)
f->ConnectToGpsTracker();
else
f->DisconnectFromGpsTracker();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_location_TrackRecorder_nativeIsEnabled(JNIEnv * env, jclass clazz)
{
return GpsTracker::Instance().IsEnabled();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_TrackRecorder_nativeStartTrackRecording(JNIEnv * env, jclass clazz)
{
frm()->StartTrackRecording();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_TrackRecorder_nativeStopTrackRecording(JNIEnv * env, jclass clazz)
{
frm()->StopTrackRecording();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_TrackRecorder_nativeSaveTrackRecordingWithName(JNIEnv * env, jclass clazz, jstring name)
{
frm()->SaveTrackRecordingWithName(jni::ToNativeString(env, name));
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_location_TrackRecorder_nativeIsTrackRecordingEmpty(JNIEnv * env, jclass clazz)
{
return frm()->IsTrackRecordingEmpty();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_location_TrackRecorder_nativeIsTrackRecordingEnabled(JNIEnv * env, jclass clazz)
{
return frm()->IsTrackRecordingEnabled();
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_TrackRecorder_nativeSetEnabled(JNIEnv * env, jclass clazz,
jboolean enable)
{
GpsTracker::Instance().SetEnabled(enable);
Framework * const f = frm();
if (f == nullptr)
return;
if (enable)
f->ConnectToGpsTracker();
else
f->DisconnectFromGpsTracker();
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_location_TrackRecorder_nativeIsEnabled(JNIEnv * env, jclass clazz)
{
return GpsTracker::Instance().IsEnabled();
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_TrackRecorder_nativeStartTrackRecording(JNIEnv * env,
jclass clazz)
{
frm()->StartTrackRecording();
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_TrackRecorder_nativeStopTrackRecording(JNIEnv * env,
jclass clazz)
{
frm()->StopTrackRecording();
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_TrackRecorder_nativeSaveTrackRecordingWithName(JNIEnv * env,
jclass clazz,
jstring name)
{
frm()->SaveTrackRecordingWithName(jni::ToNativeString(env, name));
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_location_TrackRecorder_nativeIsTrackRecordingEmpty(JNIEnv * env,
jclass clazz)
{
return frm()->IsTrackRecordingEmpty();
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_location_TrackRecorder_nativeIsTrackRecordingEnabled(JNIEnv * env,
jclass clazz)
{
return frm()->IsTrackRecordingEnabled();
}
}

View File

@@ -9,41 +9,42 @@ extern "C"
static void TrafficStateChanged(TrafficManager::TrafficState state, std::shared_ptr<jobject> const & listener)
{
JNIEnv * env = jni::GetEnv();
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener, "onTrafficStateChanged", "(I)V"), static_cast<jint>(state));
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener, "onTrafficStateChanged", "(I)V"),
static_cast<jint>(state));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_maplayer_traffic_TrafficState_nativeSetListener(JNIEnv * env, jclass clazz, jobject listener)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_maplayer_traffic_TrafficState_nativeSetListener(JNIEnv * env,
jclass clazz,
jobject listener)
{
CHECK(g_framework, ("Framework isn't created yet!"));
g_framework->SetTrafficStateListener(std::bind(&TrafficStateChanged, std::placeholders::_1, jni::make_global_ref(listener)));
g_framework->SetTrafficStateListener(
std::bind(&TrafficStateChanged, std::placeholders::_1, jni::make_global_ref(listener)));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_maplayer_traffic_TrafficState_nativeRemoveListener(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_maplayer_traffic_TrafficState_nativeRemoveListener(JNIEnv * env,
jclass clazz)
{
CHECK(g_framework, ("Framework isn't created yet!"));
g_framework->SetTrafficStateListener(TrafficManager::TrafficStateChangedFn());
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_maplayer_traffic_TrafficState_nativeEnable(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_maplayer_traffic_TrafficState_nativeEnable(JNIEnv * env, jclass clazz)
{
CHECK(g_framework, ("Framework isn't created yet!"));
g_framework->EnableTraffic();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_maplayer_traffic_TrafficState_nativeIsEnabled(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_maplayer_traffic_TrafficState_nativeIsEnabled(JNIEnv * env,
jclass clazz)
{
CHECK(g_framework, ("Framework isn't created yet!"));
return static_cast<jboolean>(g_framework->IsTrafficEnabled());
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_maplayer_traffic_TrafficState_nativeDisable(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_maplayer_traffic_TrafficState_nativeDisable(JNIEnv * env, jclass clazz)
{
CHECK(g_framework, ("Framework isn't created yet!"));
g_framework->DisableTraffic();
}
} // extern "C"
} // extern "C"

View File

@@ -1,6 +1,7 @@
#include "UserMarkHelper.hpp"
#include "app/organicmaps/sdk/routing/RoutePointInfo.hpp"
#include "app/organicmaps/sdk/util/Distance.hpp"
#include "map/elevation_info.hpp"
#include "map/place_page_info.hpp"
@@ -27,107 +28,135 @@ void InjectMetadata(JNIEnv * env, jclass const clazz, jobject const mapObject, o
});
}
//jobject CreatePopularity(JNIEnv * env, place_page::Info const & info)
// jobject CreatePopularity(JNIEnv * env, place_page::Info const & info)
//{
// static jclass const popularityClass =
// jni::GetGlobalClassRef(env, "app/organicmaps/sdk/search/Popularity");
// static jmethodID const popularityConstructor =
// jni::GetConstructorID(env, popularityClass, "(I)V");
// auto const popularityValue = info.GetPopularity();
// return env->NewObject(popularityClass, popularityConstructor, static_cast<jint>(popularityValue));
//}
// static jclass const popularityClass =
// jni::GetGlobalClassRef(env, "app/organicmaps/sdk/search/Popularity");
// static jmethodID const popularityConstructor =
// jni::GetConstructorID(env, popularityClass, "(I)V");
// auto const popularityValue = info.GetPopularity();
// return env->NewObject(popularityClass, popularityConstructor, static_cast<jint>(popularityValue));
// }
jobject CreateMapObject(JNIEnv * env, place_page::Info const & info, int mapObjectType,
double lat, double lon, bool parseMeta, bool parseApi,
jobject const & routingPointInfo, jobject const & popularity, jobjectArray jrawTypes)
jobject CreateMapObject(JNIEnv * env, place_page::Info const & info, int mapObjectType, double lat, double lon,
bool parseMeta, bool parseApi, jobject const & routingPointInfo, jobject const & popularity,
jobjectArray jrawTypes)
{
// public MapObject(@NonNull FeatureId featureId, @MapObjectType int mapObjectType, String title,
// @Nullable String secondaryTitle, String subtitle, String address,
// double lat, double lon, String apiId, @Nullable RoutePointInfo routePointInfo,
// @OpeningMode int openingMode, @NonNull Popularity popularity, @NonNull String description,
// int roadWarningType, @Nullable String[] rawTypes)
static jmethodID const ctorId = jni::GetConstructorID(
env, g_mapObjectClazz,
"("
"Lapp/organicmaps/sdk/bookmarks/data/FeatureId;" // featureId
"I" // mapObjectType
"Ljava/lang/String;" // title
"Ljava/lang/String;" // secondaryTitle
"Ljava/lang/String;" // subtitle
"Ljava/lang/String;" // address
"DD" // lat, lon
"Ljava/lang/String;" // appId
"Lapp/organicmaps/sdk/routing/RoutePointInfo;" // routePointInfo
"I" // openingMode
"Lapp/organicmaps/sdk/search/Popularity;" // popularity
"Ljava/lang/String;" // description
"I" // roadWarnType
"[Ljava/lang/String;" // rawTypes
")V");
static jmethodID const ctorId =
jni::GetConstructorID(env, g_mapObjectClazz,
"("
"Lapp/organicmaps/sdk/bookmarks/data/FeatureId;" // featureId
"I" // mapObjectType
"Ljava/lang/String;" // title
"Ljava/lang/String;" // secondaryTitle
"Ljava/lang/String;" // subtitle
"Ljava/lang/String;" // address
"DD" // lat, lon
"Ljava/lang/String;" // appId
"Lapp/organicmaps/sdk/routing/RoutePointInfo;" // routePointInfo
"I" // openingMode
"Lapp/organicmaps/sdk/search/Popularity;" // popularity
"Ljava/lang/String;" // description
"I" // roadWarnType
"[Ljava/lang/String;" // rawTypes
")V");
//public FeatureId(@NonNull String mwmName, long mwmVersion, int featureIndex)
static jmethodID const featureCtorId =
jni::GetConstructorID(env, g_featureIdClazz, "(Ljava/lang/String;JI)V");
// public FeatureId(@NonNull String mwmName, long mwmVersion, int featureIndex)
static jmethodID const featureCtorId = jni::GetConstructorID(env, g_featureIdClazz, "(Ljava/lang/String;JI)V");
auto const fID = info.GetID();
jni::TScopedLocalRef jMwmName(env, jni::ToJavaString(env, fID.GetMwmName()));
jni::TScopedLocalRef jFeatureId(
env, env->NewObject(g_featureIdClazz, featureCtorId, jMwmName.get(), (jlong)fID.GetMwmVersion(),
(jint)fID.m_index));
jni::TScopedLocalRef jFeatureId(env, env->NewObject(g_featureIdClazz, featureCtorId, jMwmName.get(),
(jlong)fID.GetMwmVersion(), (jint)fID.m_index));
jni::TScopedLocalRef jTitle(env, jni::ToJavaString(env, info.GetTitle()));
jni::TScopedLocalRef jSecondaryTitle(env, jni::ToJavaString(env, info.GetSecondaryTitle()));
jni::TScopedLocalRef jSubtitle(env, jni::ToJavaStringWithSupplementalCharsFix(env, info.GetSubtitle()));
jni::TScopedLocalRef jAddress(env, jni::ToJavaString(env, info.GetSecondarySubtitle()));
jni::TScopedLocalRef jApiId(env, jni::ToJavaString(env, parseApi ? info.GetApiUrl() : ""));
jni::TScopedLocalRef jWikiDescription(env, jni::ToJavaString(env, info.GetWikiDescription()));
jobject mapObject =
env->NewObject(g_mapObjectClazz, ctorId, jFeatureId.get(), mapObjectType, jTitle.get(),
jSecondaryTitle.get(), jSubtitle.get(), jAddress.get(), lat, lon, jApiId.get(),
routingPointInfo,
static_cast<jint>(info.GetOpeningMode()), popularity, jWikiDescription.get(),
static_cast<jint>(info.GetRoadType()), jrawTypes);
jobject mapObject = env->NewObject(g_mapObjectClazz, ctorId, jFeatureId.get(), mapObjectType, jTitle.get(),
jSecondaryTitle.get(), jSubtitle.get(), jAddress.get(), lat, lon, jApiId.get(),
routingPointInfo, static_cast<jint>(info.GetOpeningMode()), popularity,
jWikiDescription.get(), static_cast<jint>(info.GetRoadType()), jrawTypes);
if (parseMeta)
InjectMetadata(env, g_mapObjectClazz, mapObject, info);
return mapObject;
}
jobject CreateBookmark(JNIEnv *env, const place_page::Info &info,
const jni::TScopedLocalObjectArrayRef &jrawTypes,
const jni::TScopedLocalRef &routingPointInfo,
jobject const & popularity)
jobject CreateTrack(JNIEnv * env, place_page::Info const & info, jni::TScopedLocalObjectArrayRef const & jrawTypes,
jni::TScopedLocalRef const & routingPointInfo, jobject const & popularity)
{
//public Bookmark(@NonNull FeatureId featureId, @IntRange(from = 0) long categoryId,
// @IntRange(from = 0) long bookmarkId, String title, @Nullable String secondaryTitle,
// @Nullable String subtitle, @Nullable String address, @Nullable RoutePointInfo routePointInfo,
// @OpeningMode int openingMode, @NonNull Popularity popularity, @NonNull String description,
// @Nullable String[] rawTypes)
static jmethodID const ctorId =
jni::GetConstructorID(env, g_bookmarkClazz,
"(Lapp/organicmaps/sdk/bookmarks/data/FeatureId;JJLjava/lang/String;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;"
"Lapp/organicmaps/sdk/routing/RoutePointInfo;"
"ILapp/organicmaps/sdk/search/Popularity;Ljava/lang/String;"
"[Ljava/lang/String;)V");
static jmethodID const featureCtorId =
jni::GetConstructorID(env, g_featureIdClazz, "(Ljava/lang/String;JI)V");
jni::GetConstructorID(env, g_trackClazz,
"(Lapp/organicmaps/sdk/bookmarks/data/FeatureId;JJLjava/lang/String;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;"
"Lapp/organicmaps/sdk/routing/RoutePointInfo;"
"ILapp/organicmaps/sdk/search/Popularity;Ljava/lang/String;"
"[Ljava/lang/String;ILapp/organicmaps/sdk/util/Distance;DD)V");
static jmethodID const featureCtorId = jni::GetConstructorID(env, g_featureIdClazz, "(Ljava/lang/String;JI)V");
auto const trackId = info.GetTrackId();
auto const track = frm()->GetBookmarkManager().GetTrack(trackId);
jint androidColor = track->GetColor(0).GetARGB();
auto const categoryId = track->GetGroupId();
ms::LatLon const ll = info.GetLatLon();
jni::TScopedLocalRef jMwmName(env, jni::ToJavaString(env, info.GetID().GetMwmName()));
jni::TScopedLocalRef jFeatureId(env, env->NewObject(g_featureIdClazz, featureCtorId, jMwmName.get(),
(jlong)info.GetID().GetMwmVersion(), (jint)info.GetID().m_index));
jni::TScopedLocalRef jTitle(env, jni::ToJavaString(env, info.GetTitle()));
jni::TScopedLocalRef jSecondaryTitle(env, jni::ToJavaString(env, info.GetSecondaryTitle()));
jni::TScopedLocalRef jSubtitle(env, jni::ToJavaString(env, info.GetSubtitle()));
jni::TScopedLocalRef jAddress(env, jni::ToJavaString(env, info.GetSecondarySubtitle()));
jni::TScopedLocalRef jWikiDescription(env, jni::ToJavaString(env, info.GetWikiDescription()));
jobject mapObject =
env->NewObject(g_trackClazz, ctorId, jFeatureId.get(), static_cast<jlong>(categoryId),
static_cast<jlong>(trackId), jTitle.get(), jSecondaryTitle.get(), jSubtitle.get(), jAddress.get(),
routingPointInfo.get(), info.GetOpeningMode(), popularity, jWikiDescription.get(), jrawTypes.get(),
androidColor, ToJavaDistance(env, platform::Distance::CreateFormatted(track->GetLengthMeters())),
static_cast<jdouble>(ll.m_lat), static_cast<jdouble>(ll.m_lon));
if (info.HasMetadata())
InjectMetadata(env, g_mapObjectClazz, mapObject, info);
return mapObject;
}
jobject CreateBookmark(JNIEnv * env, place_page::Info const & info, jni::TScopedLocalObjectArrayRef const & jrawTypes,
jni::TScopedLocalRef const & routingPointInfo, jobject const & popularity)
{
// public Bookmark(@NonNull FeatureId featureId, @IntRange(from = 0) long categoryId,
// @IntRange(from = 0) long bookmarkId, String title, @Nullable String secondaryTitle,
// @Nullable String subtitle, @Nullable String address, @Nullable RoutePointInfo routePointInfo,
// @OpeningMode int openingMode, @NonNull Popularity popularity, @NonNull String description,
// @Nullable String[] rawTypes)
static jmethodID const ctorId =
jni::GetConstructorID(env, g_bookmarkClazz,
"(Lapp/organicmaps/sdk/bookmarks/data/FeatureId;JJLjava/lang/String;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;"
"Lapp/organicmaps/sdk/routing/RoutePointInfo;"
"ILapp/organicmaps/sdk/search/Popularity;Ljava/lang/String;"
"[Ljava/lang/String;)V");
static jmethodID const featureCtorId = jni::GetConstructorID(env, g_featureIdClazz, "(Ljava/lang/String;JI)V");
auto const bookmarkId = info.GetBookmarkId();
auto const categoryId = info.GetBookmarkCategoryId();
jni::TScopedLocalRef jMwmName(env, jni::ToJavaString(env, info.GetID().GetMwmName()));
jni::TScopedLocalRef jFeatureId(
env, env->NewObject(g_featureIdClazz, featureCtorId, jMwmName.get(),
(jlong)info.GetID().GetMwmVersion(), (jint)info.GetID().m_index));
jni::TScopedLocalRef jFeatureId(env, env->NewObject(g_featureIdClazz, featureCtorId, jMwmName.get(),
(jlong)info.GetID().GetMwmVersion(), (jint)info.GetID().m_index));
jni::TScopedLocalRef jTitle(env, jni::ToJavaString(env, info.GetTitle()));
jni::TScopedLocalRef jSecondaryTitle(env, jni::ToJavaString(env, info.GetSecondaryTitle()));
jni::TScopedLocalRef jSubtitle(env, jni::ToJavaStringWithSupplementalCharsFix(env, info.GetSubtitle()));
jni::TScopedLocalRef jAddress(env, jni::ToJavaString(env, info.GetSecondarySubtitle()));
jni::TScopedLocalRef jWikiDescription(env, jni::ToJavaString(env, info.GetWikiDescription()));
jobject mapObject = env->NewObject(
g_bookmarkClazz, ctorId, jFeatureId.get(), static_cast<jlong>(categoryId),
static_cast<jlong>(bookmarkId), jTitle.get(), jSecondaryTitle.get(), jSubtitle.get(),
jAddress.get(), routingPointInfo.get(), info.GetOpeningMode(), popularity,
jWikiDescription.get(), jrawTypes.get());
jobject mapObject = env->NewObject(g_bookmarkClazz, ctorId, jFeatureId.get(), static_cast<jlong>(categoryId),
static_cast<jlong>(bookmarkId), jTitle.get(), jSecondaryTitle.get(),
jSubtitle.get(), jAddress.get(), routingPointInfo.get(), info.GetOpeningMode(),
popularity, jWikiDescription.get(), jrawTypes.get());
if (info.HasMetadata())
InjectMetadata(env, g_mapObjectClazz, mapObject, info);
@@ -138,11 +167,11 @@ jobject CreateElevationPoint(JNIEnv * env, ElevationInfo::Point const & point)
{
static jclass const pointClass =
jni::GetGlobalClassRef(env, "app/organicmaps/sdk/bookmarks/data/ElevationInfo$Point");
// public Point(double distance, int altitude)
static jmethodID const pointCtorId =
jni::GetConstructorID(env, pointClass, "(DI)V");
return env->NewObject(pointClass, pointCtorId, static_cast<jdouble >(point.m_distance),
static_cast<jint>(point.m_point.GetAltitude()));
// public Point(double distance, int altitude, double latitude, double longitude)
static jmethodID const pointCtorId = jni::GetConstructorID(env, pointClass, "(DIDD)V");
return env->NewObject(
pointClass, pointCtorId, static_cast<jdouble>(point.m_distance), static_cast<jint>(point.m_point.GetAltitude()),
static_cast<jdouble>(point.m_point.GetPoint().x), static_cast<jdouble>(point.m_point.GetPoint().y));
}
jobjectArray ToElevationPointArray(JNIEnv * env, ElevationInfo::Points const & points)
@@ -150,31 +179,18 @@ jobjectArray ToElevationPointArray(JNIEnv * env, ElevationInfo::Points const & p
CHECK(!points.empty(), ("Elevation points must be non empty!"));
static jclass const pointClass =
jni::GetGlobalClassRef(env, "app/organicmaps/sdk/bookmarks/data/ElevationInfo$Point");
return jni::ToJavaArray(env, pointClass, points,
[](JNIEnv * env, ElevationInfo::Point const & item)
{
return CreateElevationPoint(env, item);
});
return jni::ToJavaArray(env, pointClass, points, [](JNIEnv * env, ElevationInfo::Point const & item)
{ return CreateElevationPoint(env, item); });
}
jobject CreateElevationInfo(JNIEnv * env, ElevationInfo const & info)
{
// public ElevationInfo(long trackId, @NonNull String name, @NonNull Point[] points,
// int ascent, int descent, int minAltitude, int maxAltitude, int difficulty,
// long m_duration)
// public ElevationInfo(@NonNull Point[] points, int difficulty);
static jmethodID const ctorId =
jni::GetConstructorID(env, g_elevationInfoClazz, "(JLjava/lang/String;Ljava/lang/String;"
"[Lapp/organicmaps/sdk/bookmarks/data/ElevationInfo$Point;"
"IIIIIJ)V");
jni::GetConstructorID(env, g_elevationInfoClazz, "([Lapp/organicmaps/sdk/bookmarks/data/ElevationInfo$Point;I)V");
jni::TScopedLocalObjectArrayRef jPoints(env, ToElevationPointArray(env, info.GetPoints()));
// TODO (KK): elevation info should have only the elevation data - see the https://github.com/organicmaps/organicmaps/pull/10063
return env->NewObject(g_elevationInfoClazz, ctorId,
jPoints.get(),
// static_cast<jint>(info.GetAscent()),
// static_cast<jint>(info.GetDescent()),
// static_cast<jint>(info.GetMinAltitude()),
// static_cast<jint>(info.GetMaxAltitude()),
static_cast<jint>(info.GetDifficulty()));
return env->NewObject(g_elevationInfoClazz, ctorId, jPoints.get(), static_cast<jint>(info.GetDifficulty()));
}
jobject CreateMapObject(JNIEnv * env, place_page::Info const & info)
@@ -185,46 +201,42 @@ jobject CreateMapObject(JNIEnv * env, place_page::Info const & info)
if (info.IsRoutePoint())
routingPointInfo.reset(CreateRoutePointInfo(env, info));
//jni::TScopedLocalRef popularity(env, CreatePopularity(env, info));
// jni::TScopedLocalRef popularity(env, CreatePopularity(env, info));
jobject popularity = nullptr;
if (info.IsBookmark())
{
return CreateBookmark(env, info, jrawTypes, routingPointInfo, popularity);
}
ms::LatLon const ll = info.GetLatLon();
// TODO(yunikkk): object can be POI + API + search result + bookmark simultaneously.
// TODO(yunikkk): Should we pass localized strings here and in other methods as byte arrays?
if (info.IsMyPosition())
{
return CreateMapObject(env, info, kMyPosition, ll.m_lat, ll.m_lon,
false /* parseMeta */, false /* parseApi */,
return CreateMapObject(env, info, kMyPosition, ll.m_lat, ll.m_lon, false /* parseMeta */, false /* parseApi */,
routingPointInfo.get(), popularity, jrawTypes.get());
}
if (info.HasApiUrl())
{
return CreateMapObject(env, info, kApiPoint, ll.m_lat, ll.m_lon,
true /* parseMeta */, true /* parseApi */,
return CreateMapObject(env, info, kApiPoint, ll.m_lat, ll.m_lon, true /* parseMeta */, true /* parseApi */,
routingPointInfo.get(), popularity, jrawTypes.get());
}
return CreateMapObject(env, info, kPoi, ll.m_lat, ll.m_lon,
true /* parseMeta */, false /* parseApi */,
if (info.IsTrack())
return CreateTrack(env, info, jrawTypes, routingPointInfo, popularity);
return CreateMapObject(env, info, kPoi, ll.m_lat, ll.m_lon, true /* parseMeta */, false /* parseApi */,
routingPointInfo.get(), popularity, jrawTypes.get());
}
jobject CreateFeatureId(JNIEnv * env, FeatureID const & fid)
{
static jmethodID const featureCtorId =
jni::GetConstructorID(env, g_featureIdClazz, "(Ljava/lang/String;JI)V");
static jmethodID const featureCtorId = jni::GetConstructorID(env, g_featureIdClazz, "(Ljava/lang/String;JI)V");
auto const & info = fid.m_mwmId.GetInfo();
jni::TScopedLocalRef jMwmName(env, jni::ToJavaString(env, info ? info->GetCountryName() : ""));
return env->NewObject(g_featureIdClazz, featureCtorId, jMwmName.get(),
info ? static_cast<jlong>(info->GetVersion()) : 0,
static_cast<jint>(fid.m_index));
info ? static_cast<jlong>(info->GetVersion()) : 0, static_cast<jint>(fid.m_index));
}
jobjectArray ToFeatureIdArray(JNIEnv * env, std::vector<FeatureID> const & ids)
@@ -233,8 +245,6 @@ jobjectArray ToFeatureIdArray(JNIEnv * env, std::vector<FeatureID> const & ids)
return nullptr;
return jni::ToJavaArray(env, g_featureIdClazz, ids,
[](JNIEnv * env, FeatureID const & fid) {
return CreateFeatureId(env, fid);
});
[](JNIEnv * env, FeatureID const & fid) { return CreateFeatureId(env, fid); });
}
} // namespace usermark_helper

View File

@@ -2,8 +2,8 @@
#include <jni.h>
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "app/organicmaps/sdk/Framework.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include <vector>
@@ -26,6 +26,7 @@ static constexpr int kApiPoint = 1;
static constexpr int kBookmark = 2;
static constexpr int kMyPosition = 3;
static constexpr int kSearch = 4;
static constexpr int kTrack = 5;
static constexpr int kPriceRateUndefined = -1;
@@ -34,6 +35,9 @@ void InjectMetadata(JNIEnv * env, jclass clazz, jobject const mapObject, feature
jobject CreateMapObject(JNIEnv * env, place_page::Info const & info);
jobject CreateTrack(JNIEnv * env, place_page::Info const & info, jni::TScopedLocalObjectArrayRef const & jrawTypes,
jni::TScopedLocalRef const & routingPointInfo, jobject const & popularity);
jobject CreateElevationInfo(JNIEnv * env, ElevationInfo const & info);
jobjectArray ToRatingArray(JNIEnv * env, std::vector<std::string> const & ratingCategories);

View File

@@ -0,0 +1,37 @@
#include <jni.h>
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "kml/types.hpp"
extern "C"
{
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_bookmarks_data_Icon_nativeGetBookmarkIconNames(JNIEnv * env,
jclass)
{
std::vector<std::string> icons;
for (uint16_t i = 0; i < static_cast<uint16_t>(kml::BookmarkIcon::Count); ++i)
icons.emplace_back(kml::DebugPrint(static_cast<kml::BookmarkIcon>(i)));
return jni::ToJavaStringArray(env, icons);
}
}
namespace
{
JNINativeMethod const iconMethods[] = {
{"nativeGetBookmarkIconNames", "()[Ljava/lang/String;",
reinterpret_cast<void *>(&Java_app_organicmaps_sdk_bookmarks_data_Icon_nativeGetBookmarkIconNames)},
};
}
namespace icon
{
jint registerNativeMethods(JNIEnv * env)
{
jclass clazz = env->FindClass("app/organicmaps/sdk/bookmarks/data/Icon");
if (clazz == nullptr)
return JNI_ERR;
return env->RegisterNatives(clazz, iconMethods, std::size(iconMethods));
}
} // namespace icon

View File

@@ -0,0 +1,8 @@
#pragma once
#include <jni.h>
namespace icon
{
jint registerNativeMethods(JNIEnv * env);
} // namespace icon

View File

@@ -0,0 +1,41 @@
#include "PredefinedColors.hpp"
#include "kml/types.hpp"
#include <array>
extern "C"
{
JNIEXPORT jintArray JNICALL
Java_app_organicmaps_sdk_bookmarks_data_PredefinedColors_nativeGetPredefinedColors(JNIEnv * env, jclass)
{
using kml::kOrderedPredefinedColors;
std::array<jint, kOrderedPredefinedColors.size()> colors;
for (size_t i = 0; i < kOrderedPredefinedColors.size(); ++i)
colors[i] = static_cast<jint>(kml::ColorFromPredefinedColor(kOrderedPredefinedColors[i]).GetARGB());
jintArray jColors = env->NewIntArray(colors.size());
env->SetIntArrayRegion(jColors, 0, static_cast<jsize>(colors.size()), colors.data());
return jColors;
}
}
namespace
{
JNINativeMethod const predefinedColorsMethods[] = {
{"nativeGetPredefinedColors", "()[I",
reinterpret_cast<void *>(&Java_app_organicmaps_sdk_bookmarks_data_PredefinedColors_nativeGetPredefinedColors)},
};
}
namespace predefined_colors
{
jint registerNativeMethods(JNIEnv * env)
{
jclass clazz = env->FindClass("app/organicmaps/sdk/bookmarks/data/PredefinedColors");
if (clazz == nullptr)
return JNI_ERR;
return env->RegisterNatives(clazz, predefinedColorsMethods, std::size(predefinedColorsMethods));
}
} // namespace predefined_colors

View File

@@ -0,0 +1,8 @@
#pragma once
#include <jni.h>
namespace predefined_colors
{
jint registerNativeMethods(JNIEnv * env);
} // namespace predefined_colors

View File

@@ -6,7 +6,8 @@ namespace jni
{
// A smart pointer that deletes a JNI local reference when it goes out of scope.
template <typename T>
class ScopedLocalRef {
class ScopedLocalRef
{
public:
ScopedLocalRef(JNIEnv * env, T localRef) : m_env(env), m_localRef(localRef) {}

View File

@@ -1,11 +1,14 @@
#include "jni_helper.hpp"
#include "logging.hpp"
#include "ScopedLocalRef.hpp"
#include "logging.hpp"
#include "base/assert.hpp"
#include "base/exception.hpp"
#include "base/string_utils.hpp"
#include "app/organicmaps/sdk/bookmarks/data/Icon.hpp"
#include "app/organicmaps/sdk/bookmarks/data/PredefinedColors.hpp"
#include <vector>
static JavaVM * g_jvm = 0;
@@ -18,6 +21,8 @@ extern JavaVM * GetJVM()
jclass g_mapObjectClazz;
jclass g_featureIdClazz;
jclass g_bookmarkClazz;
jclass g_trackClazz;
jclass g_trackStatisticsClazz;
jclass g_httpClientClazz;
jclass g_httpParamsClazz;
jclass g_platformSocketClazz;
@@ -31,21 +36,21 @@ extern "C"
{
int __system_property_get(char const * name, char * value);
static bool IsAndroidLowerThan7()
static bool IsAndroidApiLowerThan(int apiLevel)
{
char value[92] = { 0 };
char value[92] = {0};
if (__system_property_get("ro.build.version.sdk", value) < 1)
return false;
const int apiLevel = atoi(value);
if (apiLevel > 0 && apiLevel < 24)
int const deviceApiLevel = atoi(value);
if (deviceApiLevel > 0 && deviceApiLevel < apiLevel)
return true;
return false;
}
static bool const g_isAndroidLowerThan7 = IsAndroidLowerThan7();
static bool const g_isAndroidLowerThan12 = IsAndroidApiLowerThan(30);
static bool const g_isAndroidLowerThan7 = g_isAndroidLowerThan12 && IsAndroidApiLowerThan(24);
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM * jvm, void *)
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM * jvm, void *)
{
g_jvm = jvm;
jni::InitSystemLog();
@@ -54,6 +59,8 @@ JNI_OnLoad(JavaVM * jvm, void *)
JNIEnv * env = jni::GetEnv();
g_mapObjectClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/bookmarks/data/MapObject");
g_featureIdClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/bookmarks/data/FeatureId");
g_trackClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/bookmarks/data/Track");
g_trackStatisticsClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/bookmarks/data/TrackStatistics");
g_bookmarkClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/bookmarks/data/Bookmark");
g_httpClientClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/util/HttpClient");
g_httpParamsClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/util/HttpClient$Params");
@@ -64,17 +71,26 @@ JNI_OnLoad(JavaVM * jvm, void *)
g_networkPolicyClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/util/NetworkPolicy");
g_elevationInfoClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/bookmarks/data/ElevationInfo");
if (g_isAndroidLowerThan12)
{
if (predefined_colors::registerNativeMethods(env) != JNI_OK)
return JNI_ERR;
if (icon::registerNativeMethods(env) != JNI_OK)
return JNI_ERR;
}
return JNI_VERSION_1_6;
}
JNIEXPORT void JNICALL
JNI_OnUnload(JavaVM *, void *)
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *, void *)
{
g_jvm = 0;
JNIEnv * env = jni::GetEnv();
env->DeleteGlobalRef(g_mapObjectClazz);
env->DeleteGlobalRef(g_featureIdClazz);
env->DeleteGlobalRef(g_bookmarkClazz);
env->DeleteGlobalRef(g_trackClazz);
env->DeleteGlobalRef(g_trackStatisticsClazz);
env->DeleteGlobalRef(g_httpClientClazz);
env->DeleteGlobalRef(g_httpParamsClazz);
env->DeleteGlobalRef(g_platformSocketClazz);
@@ -84,22 +100,30 @@ JNI_OnUnload(JavaVM *, void *)
env->DeleteGlobalRef(g_networkPolicyClazz);
env->DeleteGlobalRef(g_elevationInfoClazz);
}
} // extern "C"
} // extern "C"
namespace jni
{
JNIEnv * GetEnv()
JNIEnv * GetEnvSafe()
{
JNIEnv * env;
auto const res = g_jvm->GetEnv((void **)&env, JNI_VERSION_1_6);
if (res != JNI_OK)
{
LOG(LERROR, ("Can't get JNIEnv. Is the thread attached to JVM?", res));
MYTHROW(RootException, ("Can't get JNIEnv. Is the thread attached to JVM?", res));
env = nullptr;
}
return env;
}
JNIEnv * GetEnv()
{
JNIEnv * env = GetEnvSafe();
if (env == nullptr)
MYTHROW(RootException, ("Can't get JNIEnv. Is the thread attached to JVM?"));
return env;
}
JavaVM * GetJVM()
{
ASSERT(g_jvm, ("JVM is not initialized"));
@@ -176,11 +200,11 @@ jstring ToJavaStringWithSupplementalCharsFix(JNIEnv * env, std::string const & s
if (g_isAndroidLowerThan7)
{
// Detect 4-byte sequence start marker to avoid unnecessary allocation + copy.
for (const auto c : s)
for (auto const c : s)
{
if (0b11110000 == (c & 0b11111000))
{
const auto utf16 = strings::ToUtf16(s);
auto const utf16 = strings::ToUtf16(s);
return env->NewString(reinterpret_cast<jchar const *>(utf16.data()), utf16.size());
}
}
@@ -208,39 +232,50 @@ std::shared_ptr<jobject> make_global_ref(jobject obj)
});
}
std::string ToNativeString(JNIEnv * env, const jthrowable & e)
// https://github.com/organicmaps/organicmaps/issues/9397
/// @todo There are no other ideas, let's try a safe version with a forever global ref ..
std::shared_ptr<jobject> make_global_ref_safe(jobject obj)
{
jobject * ref = new jobject(GetEnv()->NewGlobalRef(obj));
return std::shared_ptr<jobject>(ref, [](jobject * ref)
{
JNIEnv * env = GetEnvSafe();
if (env)
env->DeleteGlobalRef(*ref);
delete ref;
});
}
std::string ToNativeString(JNIEnv * env, jthrowable const & e)
{
jni::TScopedLocalClassRef logClassRef(env, env->FindClass("android/util/Log"));
ASSERT(logClassRef.get(), ());
static jmethodID const getStacktraceMethod =
jni::GetStaticMethodID(env, logClassRef.get(), "getStackTraceString",
"(Ljava/lang/Throwable;)Ljava/lang/String;");
static jmethodID const getStacktraceMethod = jni::GetStaticMethodID(env, logClassRef.get(), "getStackTraceString",
"(Ljava/lang/Throwable;)Ljava/lang/String;");
ASSERT(getStacktraceMethod, ());
TScopedLocalRef resultRef(env, env->CallStaticObjectMethod(logClassRef.get(), getStacktraceMethod, e));
return ToNativeString(env, (jstring) resultRef.get());
return ToNativeString(env, (jstring)resultRef.get());
}
bool HandleJavaException(JNIEnv * env)
{
if (env->ExceptionCheck())
{
jni::ScopedLocalRef<jthrowable> const e(env, env->ExceptionOccurred());
env->ExceptionDescribe();
env->ExceptionClear();
base::LogLevel level = GetLogLevelForException(env, e.get());
LOG(level, (ToNativeString(env, e.get())));
return true;
}
return false;
{
jni::ScopedLocalRef<jthrowable> const e(env, env->ExceptionOccurred());
env->ExceptionDescribe();
env->ExceptionClear();
base::LogLevel level = GetLogLevelForException(env, e.get());
LOG(level, (ToNativeString(env, e.get())));
return true;
}
return false;
}
base::LogLevel GetLogLevelForException(JNIEnv * env, const jthrowable & e)
base::LogLevel GetLogLevelForException(JNIEnv * env, jthrowable const & e)
{
static jclass const errorClass = jni::GetGlobalClassRef(env, "java/lang/Error");
ASSERT(errorClass, (jni::DescribeException()));
static jclass const runtimeExceptionClass =
jni::GetGlobalClassRef(env, "java/lang/RuntimeException");
static jclass const runtimeExceptionClass = jni::GetGlobalClassRef(env, "java/lang/RuntimeException");
ASSERT(runtimeExceptionClass, (jni::DescribeException()));
// If Unchecked Exception or Error is occurred during Java call the app should fail immediately.
// In other cases, just a warning message about exception (Checked Exception)
@@ -270,12 +305,10 @@ std::string DescribeException()
jobject GetNewParcelablePointD(JNIEnv * env, m2::PointD const & point)
{
jclass klass = env->FindClass("app/organicmaps/sdk/bookmarks/data/ParcelablePointD");
ASSERT ( klass, () );
ASSERT(klass, ());
jmethodID methodID = GetConstructorID(env, klass, "(DD)V");
return env->NewObject(klass, methodID,
static_cast<jdouble>(point.x),
static_cast<jdouble>(point.y));
return env->NewObject(klass, methodID, static_cast<jdouble>(point.x), static_cast<jdouble>(point.y));
}
jobject GetNewPoint(JNIEnv * env, m2::PointD const & point)
@@ -286,12 +319,10 @@ jobject GetNewPoint(JNIEnv * env, m2::PointD const & point)
jobject GetNewPoint(JNIEnv * env, m2::PointI const & point)
{
jclass klass = env->FindClass("android/graphics/Point");
ASSERT ( klass, () );
ASSERT(klass, ());
jmethodID methodID = GetConstructorID(env, klass, "(II)V");
return env->NewObject(klass, methodID,
static_cast<jint>(point.x),
static_cast<jint>(point.y));
return env->NewObject(klass, methodID, static_cast<jint>(point.x), static_cast<jint>(point.y));
}
// This util method dumps content of local and global reference jni tables to logcat for debug and testing purposes
@@ -306,8 +337,8 @@ void DumpDalvikReferenceTables()
jobject ToKeyValue(JNIEnv * env, std::pair<std::string, std::string> src)
{
static jmethodID const keyValueInit = jni::GetConstructorID(
env, g_keyValueClazz, "(Ljava/lang/String;Ljava/lang/String;)V");
static jmethodID const keyValueInit =
jni::GetConstructorID(env, g_keyValueClazz, "(Ljava/lang/String;Ljava/lang/String;)V");
jni::TScopedLocalRef key(env, jni::ToJavaString(env, src.first));
jni::TScopedLocalRef value(env, jni::ToJavaString(env, src.second));
@@ -317,16 +348,12 @@ jobject ToKeyValue(JNIEnv * env, std::pair<std::string, std::string> src)
std::pair<std::string, std::string> ToNativeKeyValue(JNIEnv * env, jobject pairOfStrings)
{
static jfieldID const keyId = env->GetFieldID(g_keyValueClazz, "mKey",
"Ljava/lang/String;");
static jfieldID const valueId = env->GetFieldID(g_keyValueClazz, "mValue",
"Ljava/lang/String;");
static jfieldID const keyId = env->GetFieldID(g_keyValueClazz, "mKey", "Ljava/lang/String;");
static jfieldID const valueId = env->GetFieldID(g_keyValueClazz, "mValue", "Ljava/lang/String;");
jni::ScopedLocalRef<jstring> const key(
env, static_cast<jstring>(env->GetObjectField(pairOfStrings, keyId)));
jni::ScopedLocalRef<jstring> const value(
env, static_cast<jstring>(env->GetObjectField(pairOfStrings, valueId)));
jni::ScopedLocalRef<jstring> const key(env, static_cast<jstring>(env->GetObjectField(pairOfStrings, keyId)));
jni::ScopedLocalRef<jstring> const value(env, static_cast<jstring>(env->GetObjectField(pairOfStrings, valueId)));
return { jni::ToNativeString(env, key.get()), jni::ToNativeString(env, value.get()) };
return {jni::ToNativeString(env, key.get()), jni::ToNativeString(env, value.get())};
}
} // namespace jni

View File

@@ -18,6 +18,8 @@
extern jclass g_mapObjectClazz;
extern jclass g_featureIdClazz;
extern jclass g_bookmarkClazz;
extern jclass g_trackClazz;
extern jclass g_trackStatisticsClazz;
extern jclass g_httpClientClazz;
extern jclass g_httpParamsClazz;
extern jclass g_platformSocketClazz;
@@ -41,8 +43,8 @@ jfieldID GetStaticFieldID(JNIEnv * env, jclass clazz, char const * name, char co
jclass GetGlobalClassRef(JNIEnv * env, char const * s);
std::string ToNativeString(JNIEnv * env, jstring str);
// Converts UTF-8 array to native UTF-8 string. Result differs from simple GetStringUTFChars call for characters greater than U+10000,
// since jni uses modified UTF (MUTF-8) for strings.
// Converts UTF-8 array to native UTF-8 string. Result differs from simple GetStringUTFChars call for characters greater
// than U+10000, since jni uses modified UTF (MUTF-8) for strings.
std::string ToNativeString(JNIEnv * env, jbyteArray const & utfBytes);
jstring ToJavaString(JNIEnv * env, char const * s);
inline jstring ToJavaString(JNIEnv * env, std::string const & s)
@@ -63,9 +65,11 @@ char const * GetStringClassName();
std::string DescribeException();
bool HandleJavaException(JNIEnv * env);
base::LogLevel GetLogLevelForException(JNIEnv * env, const jthrowable & e);
base::LogLevel GetLogLevelForException(JNIEnv * env, jthrowable const & e);
std::shared_ptr<jobject> make_global_ref(jobject obj);
std::shared_ptr<jobject> make_global_ref_safe(jobject obj);
using TScopedLocalRef = ScopedLocalRef<jobject>;
using TScopedLocalClassRef = ScopedLocalRef<jclass>;
using TScopedLocalObjectArrayRef = ScopedLocalRef<jobjectArray>;
@@ -77,10 +81,10 @@ jobject GetNewParcelablePointD(JNIEnv * env, m2::PointD const & point);
jobject GetNewPoint(JNIEnv * env, m2::PointD const & point);
jobject GetNewPoint(JNIEnv * env, m2::PointI const & point);
template<typename TIt, typename TToJavaFn>
template <typename TIt, typename TToJavaFn>
jobjectArray ToJavaArray(JNIEnv * env, jclass clazz, TIt begin, TIt end, size_t const size, TToJavaFn && toJavaFn)
{
jobjectArray jArray = env->NewObjectArray((jint) size, clazz, 0);
jobjectArray jArray = env->NewObjectArray((jint)size, clazz, 0);
jint i = 0;
for (auto it = begin; it != end; ++it)
{
@@ -92,21 +96,17 @@ jobjectArray ToJavaArray(JNIEnv * env, jclass clazz, TIt begin, TIt end, size_t
return jArray;
}
template<typename TContainer, typename TToJavaFn>
template <typename TContainer, typename TToJavaFn>
jobjectArray ToJavaArray(JNIEnv * env, jclass clazz, TContainer const & src, TToJavaFn && toJavaFn)
{
return ToJavaArray(env, clazz, std::begin(src), std::end(src), src.size(),
std::forward<TToJavaFn>(toJavaFn));
return ToJavaArray(env, clazz, std::begin(src), std::end(src), src.size(), std::forward<TToJavaFn>(toJavaFn));
}
template <typename Cont>
jobjectArray ToJavaStringArray(JNIEnv * env, Cont const & src)
{
return ToJavaArray(env, GetStringClass(env), src,
[](JNIEnv * env, std::string const & item)
{
return ToJavaString(env, item.c_str());
});
[](JNIEnv * env, std::string const & item) { return ToJavaString(env, item.c_str()); });
}
void DumpDalvikReferenceTables();

View File

@@ -29,4 +29,4 @@ jobject ListBuilder::CreateArray(JNIEnv * env, size_t sz) const
{
return env->NewObject(m_arrayClass, m_arrayCtor, sz);
}
} // namespace jni
} // namespace jni

View File

@@ -2,8 +2,12 @@
#include <jni.h>
#define DECLARE_BUILDER_INSTANCE(BuilderType) static BuilderType const & Instance(JNIEnv * env) { \
static BuilderType const inst(env); return inst; }
#define DECLARE_BUILDER_INSTANCE(BuilderType) \
static BuilderType const & Instance(JNIEnv * env) \
{ \
static BuilderType const inst(env); \
return inst; \
}
namespace jni
{
@@ -34,4 +38,4 @@ public:
jobject CreateArray(JNIEnv * env, size_t sz) const;
};
} // namespace jni
} // namespace jni

View File

@@ -3,9 +3,9 @@
#include "base/exception.hpp"
#include "base/logging.hpp"
#include "app/organicmaps/sdk/core/ScopedEnv.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "app/organicmaps/sdk/core/logging.hpp"
#include "app/organicmaps/sdk/core/ScopedEnv.hpp"
#include <android/log.h>
#include <cassert>
@@ -22,17 +22,17 @@ void AndroidMessage(LogLevel level, SrcPoint const & src, std::string const & s)
switch (level)
{
case LINFO: pr = ANDROID_LOG_INFO; break;
case LDEBUG: pr = ANDROID_LOG_DEBUG; break;
case LWARNING: pr = ANDROID_LOG_WARN; break;
case LERROR: pr = ANDROID_LOG_ERROR; break;
case LCRITICAL: pr = ANDROID_LOG_ERROR; break;
case NUM_LOG_LEVELS: break;
case LINFO: pr = ANDROID_LOG_INFO; break;
case LDEBUG: pr = ANDROID_LOG_DEBUG; break;
case LWARNING: pr = ANDROID_LOG_WARN; break;
case LERROR: pr = ANDROID_LOG_ERROR; break;
case LCRITICAL: pr = ANDROID_LOG_ERROR; break;
case NUM_LOG_LEVELS: break;
}
ScopedEnv env(jni::GetJVM());
static jmethodID const logMethod = jni::GetStaticMethodID(env.get(), g_loggerClazz,
"log", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V");
static jmethodID const logMethod = jni::GetStaticMethodID(
env.get(), g_loggerClazz, "log", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V");
std::string const out = DebugPrint(src) + s;
jni::TScopedLocalRef msg(env.get(), jni::ToJavaString(env.get(), out));
@@ -68,4 +68,4 @@ void ToggleDebugLogs(bool enabled)
else
g_LogLevel = LINFO;
}
}
} // namespace jni

View File

@@ -2,7 +2,7 @@
namespace jni
{
void InitSystemLog();
void InitAssertLog();
void ToggleDebugLogs(bool enabled);
}
void InitSystemLog();
void InitAssertLog();
void ToggleDebugLogs(bool enabled);
} // namespace jni

View File

@@ -2,16 +2,12 @@
namespace android
{
void RenderContext::makeCurrent()
{
}
void RenderContext::makeCurrent() {}
graphics::RenderContext * RenderContext::createShared()
{
RenderContext * rc = new RenderContext();
rc->setResourceManager(resourceManager());
return rc;
}
graphics::RenderContext * RenderContext::createShared()
{
RenderContext * rc = new RenderContext();
rc->setResourceManager(resourceManager());
return rc;
}
} // namespace android

View File

@@ -6,12 +6,11 @@
namespace android
{
class RenderContext : public graphics::gl::RenderContext
{
public:
class RenderContext : public graphics::gl::RenderContext
{
public:
void makeCurrent();
void makeCurrent();
graphics::RenderContext * createShared();
};
}
graphics::RenderContext * createShared();
};
} // namespace android

View File

@@ -1,7 +1,7 @@
#include <jni.h>
#include <jni.h>
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "app/organicmaps/sdk/Framework.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "editor/osm_editor.hpp"
@@ -43,8 +43,7 @@ jobject ToJavaName(JNIEnv * env, osm::LocalizedName const & name)
jni::TScopedLocalRef jName(env, jni::ToJavaString(env, name.m_name));
jni::TScopedLocalRef jLang(env, jni::ToJavaString(env, name.m_lang));
jni::TScopedLocalRef jLangName(env, jni::ToJavaString(env, name.m_langName));
return env->NewObject(g_localNameClazz, g_localNameCtor, name.m_code,
jName.get(), jLang.get(), jLangName.get());
return env->NewObject(g_localNameClazz, g_localNameCtor, name.m_code, jName.get(), jLang.get(), jLangName.get());
}
jobject ToJavaStreet(JNIEnv * env, osm::LocalizedStreet const & street)
@@ -65,12 +64,12 @@ extern "C"
{
using osm::Editor;
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeInit(JNIEnv * env, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeInit(JNIEnv * env, jclass)
{
g_localNameClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/data/LocalizedName");
// LocalizedName(int code, @NonNull String name, @NonNull String lang, @NonNull String langName)
g_localNameCtor = jni::GetConstructorID(env, g_localNameClazz, "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
g_localNameCtor =
jni::GetConstructorID(env, g_localNameClazz, "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
g_localNameFieldCode = env->GetFieldID(g_localNameClazz, "code", "I");
g_localNameFieldName = env->GetFieldID(g_localNameClazz, "name", "Ljava/lang/String;");
@@ -81,30 +80,28 @@ Java_app_organicmaps_sdk_editor_Editor_nativeInit(JNIEnv * env, jclass)
g_localStreetFieldLoc = env->GetFieldID(g_localStreetClazz, "localizedName", "Ljava/lang/String;");
g_namesDataSourceClassID = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/data/NamesDataSource");
g_namesDataSourceConstructorID = jni::GetConstructorID(env, g_namesDataSourceClassID, "([Lapp/organicmaps/sdk/editor/data/LocalizedName;I)V");
g_namesDataSourceConstructorID =
jni::GetConstructorID(env, g_namesDataSourceClassID, "([Lapp/organicmaps/sdk/editor/data/LocalizedName;I)V");
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetOpeningHours(JNIEnv * env, jclass)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetOpeningHours(JNIEnv * env, jclass)
{
return jni::ToJavaString(env, g_editableMapObject.GetOpeningHours());
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeSetOpeningHours(JNIEnv * env, jclass, jstring value)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeSetOpeningHours(JNIEnv * env, jclass, jstring value)
{
g_editableMapObject.SetOpeningHours(jni::ToNativeString(env, value));
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetMetadata(JNIEnv * env, jclass, jint id)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetMetadata(JNIEnv * env, jclass, jint id)
{
auto const metaID = static_cast<osm::MapObject::MetadataID>(id);
ASSERT_LESS(metaID, osm::MapObject::MetadataID::FMD_COUNT, ());
if (osm::isSocialContactTag(metaID))
{
auto const value = g_editableMapObject.GetMetadata(metaID);
if (value.find('/') == std::string::npos) // `value` contains pagename.
if (value.find('/') == std::string::npos) // `value` contains pagename.
return jni::ToJavaString(env, value);
// `value` contains URL.
return jni::ToJavaString(env, osm::socialContactToURL(metaID, value));
@@ -112,64 +109,56 @@ Java_app_organicmaps_sdk_editor_Editor_nativeGetMetadata(JNIEnv * env, jclass, j
return jni::ToJavaString(env, g_editableMapObject.GetMetadata(metaID));
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeIsMetadataValid(JNIEnv * env, jclass, jint id, jstring value)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsMetadataValid(JNIEnv * env, jclass, jint id,
jstring value)
{
auto const metaID = static_cast<osm::MapObject::MetadataID>(id);
ASSERT_LESS(metaID, osm::MapObject::MetadataID::FMD_COUNT, ());
return osm::EditableMapObject::IsValidMetadata(metaID, jni::ToNativeString(env, value));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeSetMetadata(JNIEnv * env, jclass, jint id, jstring value)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeSetMetadata(JNIEnv * env, jclass, jint id,
jstring value)
{
auto const metaID = static_cast<osm::MapObject::MetadataID>(id);
ASSERT_LESS(metaID, osm::MapObject::MetadataID::FMD_COUNT, ());
g_editableMapObject.SetMetadata(metaID, jni::ToNativeString(env, value));
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetStars(JNIEnv * env, jclass)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetStars(JNIEnv * env, jclass)
{
return g_editableMapObject.GetStars();
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetMaxEditableBuildingLevels(JNIEnv *, jclass)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetMaxEditableBuildingLevels(JNIEnv *, jclass)
{
return osm::EditableMapObject::kMaximumLevelsEditableByUsers;
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeHasWifi(JNIEnv *, jclass)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeHasWifi(JNIEnv *, jclass)
{
return g_editableMapObject.GetInternet() == feature::Internet::Wlan;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeSetHasWifi(JNIEnv *, jclass, jboolean hasWifi)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeSetHasWifi(JNIEnv *, jclass, jboolean hasWifi)
{
if (hasWifi != (g_editableMapObject.GetInternet() == feature::Internet::Wlan))
g_editableMapObject.SetInternet(hasWifi ? feature::Internet::Wlan : feature::Internet::Unknown);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeSaveEditedFeature(JNIEnv *, jclass)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeSaveEditedFeature(JNIEnv *, jclass)
{
switch (g_framework->NativeFramework()->SaveEditedMapObject(g_editableMapObject))
{
case osm::Editor::SaveResult::NothingWasChanged:
case osm::Editor::SaveResult::SavedSuccessfully:
return true;
case osm::Editor::SaveResult::SavedSuccessfully: return true;
case osm::Editor::SaveResult::NoFreeSpaceError:
case osm::Editor::SaveResult::NoUnderlyingMapError:
case osm::Editor::SaveResult::SavingError:
return false;
case osm::Editor::SaveResult::SavingError: return false;
}
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeShouldShowEditPlace(JNIEnv *, jclass)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeShouldShowEditPlace(JNIEnv *, jclass)
{
::Framework * frm = g_framework->NativeFramework();
if (!frm->HasPlacePageInfo())
@@ -178,8 +167,7 @@ Java_app_organicmaps_sdk_editor_Editor_nativeShouldShowEditPlace(JNIEnv *, jclas
return g_framework->GetPlacePageInfo().ShouldShowEditPlace();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeShouldShowAddBusiness(JNIEnv *, jclass)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeShouldShowAddBusiness(JNIEnv *, jclass)
{
::Framework * frm = g_framework->NativeFramework();
if (!frm->HasPlacePageInfo())
@@ -188,8 +176,7 @@ Java_app_organicmaps_sdk_editor_Editor_nativeShouldShowAddBusiness(JNIEnv *, jcl
return g_framework->GetPlacePageInfo().ShouldShowAddBusiness();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeShouldShowAddPlace(JNIEnv *, jclass)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeShouldShowAddPlace(JNIEnv *, jclass)
{
::Framework * frm = g_framework->NativeFramework();
if (!frm->HasPlacePageInfo())
@@ -198,8 +185,7 @@ Java_app_organicmaps_sdk_editor_Editor_nativeShouldShowAddPlace(JNIEnv *, jclass
return g_framework->GetPlacePageInfo().ShouldShowAddPlace();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeShouldEnableEditPlace(JNIEnv *, jclass)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeShouldEnableEditPlace(JNIEnv *, jclass)
{
::Framework * frm = g_framework->NativeFramework();
if (!frm->HasPlacePageInfo())
@@ -208,8 +194,7 @@ Java_app_organicmaps_sdk_editor_Editor_nativeShouldEnableEditPlace(JNIEnv *, jcl
return g_framework->GetPlacePageInfo().ShouldEnableEditPlace();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeShouldEnableAddPlace(JNIEnv *, jclass)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeShouldEnableAddPlace(JNIEnv *, jclass)
{
::Framework * frm = g_framework->NativeFramework();
if (!frm->HasPlacePageInfo())
@@ -218,8 +203,8 @@ Java_app_organicmaps_sdk_editor_Editor_nativeShouldEnableAddPlace(JNIEnv *, jcla
return g_framework->GetPlacePageInfo().ShouldEnableAddPlace();
}
JNIEXPORT jintArray JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetEditableProperties(JNIEnv * env, jclass clazz)
JNIEXPORT jintArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetEditableProperties(JNIEnv * env,
jclass clazz)
{
auto const & editable = g_editableMapObject.GetEditableProperties();
size_t const size = editable.size();
@@ -232,32 +217,27 @@ Java_app_organicmaps_sdk_editor_Editor_nativeGetEditableProperties(JNIEnv * env,
return jEditableFields;
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeIsAddressEditable(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsAddressEditable(JNIEnv * env, jclass clazz)
{
return g_editableMapObject.IsAddressEditable();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeIsNameEditable(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsNameEditable(JNIEnv * env, jclass clazz)
{
return g_editableMapObject.IsNameEditable();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeIsPointType(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsPointType(JNIEnv * env, jclass clazz)
{
return g_editableMapObject.IsPointType();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeIsBuilding(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsBuilding(JNIEnv * env, jclass clazz)
{
return g_editableMapObject.IsBuilding();
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetNamesDataSource(JNIEnv * env, jclass)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetNamesDataSource(JNIEnv * env, jclass)
{
auto const namesDataSource = g_editableMapObject.GetNamesDataSource();
@@ -267,82 +247,79 @@ Java_app_organicmaps_sdk_editor_Editor_nativeGetNamesDataSource(JNIEnv * env, jc
return env->NewObject(g_namesDataSourceClassID, g_namesDataSourceConstructorID, names, mandatoryNamesCount);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeSetNames(JNIEnv * env, jclass, jobjectArray names)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeSetNames(JNIEnv * env, jclass, jobjectArray names)
{
int const length = env->GetArrayLength(names);
for (int i = 0; i < length; i++)
{
auto jName = env->GetObjectArrayElement(names, i);
g_editableMapObject.SetName(jni::ToNativeString(env, static_cast<jstring>(env->GetObjectField(jName, g_localNameFieldName))),
env->GetIntField(jName, g_localNameFieldCode));
g_editableMapObject.SetName(
jni::ToNativeString(env, static_cast<jstring>(env->GetObjectField(jName, g_localNameFieldName))),
env->GetIntField(jName, g_localNameFieldCode));
}
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetStreet(JNIEnv * env, jclass)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetStreet(JNIEnv * env, jclass)
{
return ToJavaStreet(env, g_editableMapObject.GetStreet());
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeSetStreet(JNIEnv * env, jclass, jobject street)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeSetStreet(JNIEnv * env, jclass, jobject street)
{
g_editableMapObject.SetStreet({jni::ToNativeString(env, (jstring) env->GetObjectField(street, g_localStreetFieldDef)),
jni::ToNativeString(env, (jstring) env->GetObjectField(street, g_localStreetFieldLoc))});
g_editableMapObject.SetStreet(
{jni::ToNativeString(env, (jstring)env->GetObjectField(street, g_localStreetFieldDef)),
jni::ToNativeString(env, (jstring)env->GetObjectField(street, g_localStreetFieldLoc))});
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetNearbyStreets(JNIEnv * env, jclass clazz)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetNearbyStreets(JNIEnv * env, jclass clazz)
{
return jni::ToJavaArray(env, g_localStreetClazz, g_editableMapObject.GetNearbyStreets(), ToJavaStreet);
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetSupportedLanguages(JNIEnv * env, jclass clazz, jboolean includeServiceLangs)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetSupportedLanguages(
JNIEnv * env, jclass clazz, jboolean includeServiceLangs)
{
using TLang = StringUtf8Multilang::Lang;
//public Language(@NonNull String code, @NonNull String name)
// public Language(@NonNull String code, @NonNull String name)
static jclass const langClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/data/Language");
static jmethodID const langCtor = jni::GetConstructorID(env, langClass, "(Ljava/lang/String;Ljava/lang/String;)V");
return jni::ToJavaArray(env, langClass, StringUtf8Multilang::GetSupportedLanguages(includeServiceLangs),
[](JNIEnv * env, TLang const & lang)
{
jni::TScopedLocalRef const code(env, jni::ToJavaString(env, lang.m_code));
jni::TScopedLocalRef const name(env, jni::ToJavaString(env, lang.m_name));
return env->NewObject(langClass, langCtor, code.get(), name.get());
});
{
jni::TScopedLocalRef const code(env, jni::ToJavaString(env, lang.m_code));
jni::TScopedLocalRef const name(env, jni::ToJavaString(env, lang.m_name));
return env->NewObject(langClass, langCtor, code.get(), name.get());
});
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetHouseNumber(JNIEnv * env, jclass)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetHouseNumber(JNIEnv * env, jclass)
{
return jni::ToJavaString(env, g_editableMapObject.GetHouseNumber());
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeSetHouseNumber(JNIEnv * env, jclass, jstring houseNumber)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeSetHouseNumber(JNIEnv * env, jclass,
jstring houseNumber)
{
g_editableMapObject.SetHouseNumber(jni::ToNativeString(env, houseNumber));
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeHasSomethingToUpload(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeHasSomethingToUpload(JNIEnv * env, jclass clazz)
{
return Editor::Instance().HaveMapEditsOrNotesToUpload();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeUploadChanges(JNIEnv * env, jclass clazz, jstring token, jstring appVersion, jstring appId)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeUploadChanges(JNIEnv * env, jclass clazz,
jstring token, jstring appVersion,
jstring appId)
{
// TODO: Handle upload status in callback
Editor::Instance().UploadChanges(jni::ToNativeString(env, token),
{{"created_by", "CoMaps " OMIM_OS_NAME " " + jni::ToNativeString(env, appVersion)},
{"bundle_id", jni::ToNativeString(env, appId)}}, nullptr);
{{"created_by", "CoMaps " OMIM_OS_NAME " " + jni::ToNativeString(env, appVersion)},
{"bundle_id", jni::ToNativeString(env, appId)}},
nullptr);
}
JNIEXPORT jlongArray JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetStats(JNIEnv * env, jclass clazz)
JNIEXPORT jlongArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetStats(JNIEnv * env, jclass clazz)
{
auto const stats = Editor::Instance().GetStats();
jlongArray result = env->NewLongArray(3);
@@ -352,14 +329,12 @@ Java_app_organicmaps_sdk_editor_Editor_nativeGetStats(JNIEnv * env, jclass clazz
return result;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeClearLocalEdits(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeClearLocalEdits(JNIEnv * env, jclass clazz)
{
Editor::Instance().ClearAllLocalEdits();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeStartEdit(JNIEnv *, jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeStartEdit(JNIEnv *, jclass)
{
::Framework * frm = g_framework->NativeFramework();
if (!frm->HasPlacePageInfo())
@@ -373,9 +348,8 @@ Java_app_organicmaps_sdk_editor_Editor_nativeStartEdit(JNIEnv *, jclass)
CHECK(frm->GetEditableMapObject(info.GetID(), g_editableMapObject), ("Invalid feature in the place page."));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeCreateMapObject(JNIEnv * env, jclass,
jstring featureType)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeCreateMapObject(JNIEnv * env, jclass,
jstring featureType)
{
::Framework * frm = g_framework->NativeFramework();
auto const type = classif().GetTypeByReadableObjectName(jni::ToNativeString(env, featureType));
@@ -384,31 +358,35 @@ Java_app_organicmaps_sdk_editor_Editor_nativeCreateMapObject(JNIEnv * env, jclas
}
// static void nativeCreateNote(String text);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeCreateNote(JNIEnv * env, jclass clazz, jstring text)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeCreateNote(JNIEnv * env, jclass clazz, jstring text)
{
g_framework->NativeFramework()->CreateNote(
g_editableMapObject, osm::Editor::NoteProblemType::General, jni::ToNativeString(env, text));
g_framework->NativeFramework()->CreateNote(g_editableMapObject, osm::Editor::NoteProblemType::General,
jni::ToNativeString(env, text));
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeCreateStandaloneNote(JNIEnv * env, jclass clazz,
jdouble lat, jdouble lon,
jstring text)
{
osm::Editor::Instance().CreateStandaloneNote(ms::LatLon(lat, lon), jni::ToNativeString(env, text));
}
// static void nativePlaceDoesNotExist(String comment);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativePlaceDoesNotExist(JNIEnv * env, jclass clazz, jstring comment)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativePlaceDoesNotExist(JNIEnv * env, jclass clazz,
jstring comment)
{
g_framework->NativeFramework()->CreateNote(g_editableMapObject,
osm::Editor::NoteProblemType::PlaceDoesNotExist,
g_framework->NativeFramework()->CreateNote(g_editableMapObject, osm::Editor::NoteProblemType::PlaceDoesNotExist,
jni::ToNativeString(env, comment));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeRollbackMapObject(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeRollbackMapObject(JNIEnv * env, jclass clazz)
{
g_framework->NativeFramework()->RollBackChanges(g_editableMapObject.GetID());
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetAllCreatableFeatureTypes(JNIEnv * env, jclass clazz,
jstring jLang)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetAllCreatableFeatureTypes(JNIEnv * env,
jclass clazz,
jstring jLang)
{
std::string const & lang = jni::ToNativeString(env, jLang);
auto & categories = GetFeatureCategories();
@@ -417,10 +395,10 @@ Java_app_organicmaps_sdk_editor_Editor_nativeGetAllCreatableFeatureTypes(JNIEnv
return jni::ToJavaStringArray(env, categories.GetAllCreatableTypeNames());
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeSearchCreatableFeatureTypes(JNIEnv * env, jclass clazz,
jstring query,
jstring jLang)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeSearchCreatableFeatureTypes(JNIEnv * env,
jclass clazz,
jstring query,
jstring jLang)
{
std::string const & lang = jni::ToNativeString(env, jLang);
auto & categories = GetFeatureCategories();
@@ -429,8 +407,7 @@ Java_app_organicmaps_sdk_editor_Editor_nativeSearchCreatableFeatureTypes(JNIEnv
return jni::ToJavaStringArray(env, categories.Search(jni::ToNativeString(env, query)));
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetCuisines(JNIEnv * env, jclass clazz)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetCuisines(JNIEnv * env, jclass clazz)
{
osm::AllCuisines const & cuisines = osm::Cuisines::Instance().AllSupportedCuisines();
std::vector<std::string> keys;
@@ -440,14 +417,15 @@ Java_app_organicmaps_sdk_editor_Editor_nativeGetCuisines(JNIEnv * env, jclass cl
return jni::ToJavaStringArray(env, keys);
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetSelectedCuisines(JNIEnv * env, jclass clazz)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetSelectedCuisines(JNIEnv * env,
jclass clazz)
{
return jni::ToJavaStringArray(env, g_editableMapObject.GetCuisines());
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeFilterCuisinesKeys(JNIEnv * env, jclass thiz, jstring jSubstr)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeFilterCuisinesKeys(JNIEnv * env,
jclass thiz,
jstring jSubstr)
{
std::string const substr = jni::ToNativeString(env, jSubstr);
bool const noFilter = substr.length() == 0;
@@ -466,8 +444,9 @@ Java_app_organicmaps_sdk_editor_Editor_nativeFilterCuisinesKeys(JNIEnv * env, jc
return jni::ToJavaStringArray(env, keys);
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeTranslateCuisines(JNIEnv * env, jclass clazz, jobjectArray jKeys)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeTranslateCuisines(JNIEnv * env,
jclass clazz,
jobjectArray jKeys)
{
int const length = env->GetArrayLength(jKeys);
auto const & cuisines = osm::Cuisines::Instance();
@@ -481,8 +460,8 @@ Java_app_organicmaps_sdk_editor_Editor_nativeTranslateCuisines(JNIEnv * env, jcl
return jni::ToJavaStringArray(env, translations);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeSetSelectedCuisines(JNIEnv * env, jclass clazz, jobjectArray jKeys)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeSetSelectedCuisines(JNIEnv * env, jclass clazz,
jobjectArray jKeys)
{
int const length = env->GetArrayLength(jKeys);
std::vector<std::string> cuisines;
@@ -492,39 +471,41 @@ Java_app_organicmaps_sdk_editor_Editor_nativeSetSelectedCuisines(JNIEnv * env, j
g_editableMapObject.SetCuisines(cuisines);
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetFormattedCuisine(JNIEnv * env, jclass clazz)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetFormattedCuisine(JNIEnv * env, jclass clazz)
{
return jni::ToJavaString(env, g_editableMapObject.FormatCuisines());
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetMwmName(JNIEnv * env, jclass clazz)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetMwmName(JNIEnv * env, jclass clazz)
{
return jni::ToJavaString(env, g_editableMapObject.GetID().GetMwmName());
}
JNIEXPORT jlong JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetMwmVersion(JNIEnv * env, jclass clazz)
JNIEXPORT jlong JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetMwmVersion(JNIEnv * env, jclass clazz)
{
return g_editableMapObject.GetID().GetMwmVersion();
}
// static boolean nativeIsHouseValid(String houseNumber);
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeIsHouseValid(JNIEnv * env, jclass clazz, jstring houseNumber)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsHouseValid(JNIEnv * env, jclass clazz,
jstring houseNumber)
{
return osm::EditableMapObject::ValidateHouseNumber(jni::ToNativeString(env, houseNumber));
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeIsNameValid(JNIEnv * env, jclass clazz, jstring name)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeCheckHouseNumberWhenIsAddress(JNIEnv * env,
jclass clazz)
{
return g_editableMapObject.CheckHouseNumberWhenIsAddress();
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsNameValid(JNIEnv * env, jclass clazz,
jstring name)
{
return osm::EditableMapObject::ValidateName(jni::ToNativeString(env, name));
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetCategory(JNIEnv * env, jclass clazz)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetCategory(JNIEnv * env, jclass clazz)
{
auto types = g_editableMapObject.GetTypes();
types.SortBySpec();
@@ -533,23 +514,22 @@ Java_app_organicmaps_sdk_editor_Editor_nativeGetCategory(JNIEnv * env, jclass cl
// @FeatureStatus
// static native int nativeGetMapObjectStatus();
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeGetMapObjectStatus(JNIEnv * env, jclass clazz)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetMapObjectStatus(JNIEnv * env, jclass clazz)
{
return static_cast<jint>(osm::Editor::Instance().GetFeatureStatus(g_editableMapObject.GetID()));
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeIsMapObjectUploaded(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsMapObjectUploaded(JNIEnv * env, jclass clazz)
{
return osm::Editor::Instance().IsFeatureUploaded(g_editableMapObject.GetID().m_mwmId, g_editableMapObject.GetID().m_index);
return osm::Editor::Instance().IsFeatureUploaded(g_editableMapObject.GetID().m_mwmId,
g_editableMapObject.GetID().m_index);
}
// static nativeMakeLocalizedName(String langCode, String name);
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_editor_Editor_nativeMakeLocalizedName(JNIEnv * env, jclass clazz, jstring code, jstring name)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeMakeLocalizedName(JNIEnv * env, jclass clazz,
jstring code, jstring name)
{
osm::LocalizedName localizedName(jni::ToNativeString(env, code), jni::ToNativeString(env, name));
return ToJavaName(env, localizedName);
}
} // extern "C"
} // extern "C"

View File

@@ -14,7 +14,6 @@
#include <set>
#include <vector>
namespace
{
using namespace editor;
@@ -43,22 +42,12 @@ jfieldID g_fidWeekdays;
jobject JavaHoursMinutes(JNIEnv * env, jlong hours, jlong minutes)
{
static const jclass dateUtilsClass = jni::GetGlobalClassRef(env,
"app/organicmaps/sdk/util/DateUtils");
static jclass const dateUtilsClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/util/DateUtils");
static jmethodID const is24HourFormatMethod =
jni::GetStaticMethodID(env,
dateUtilsClass,
"is24HourFormat",
"(Landroid/content/Context;)Z");
jni::GetStaticMethodID(env, dateUtilsClass, "is24HourFormat", "(Landroid/content/Context;)Z");
jobject context = android::Platform::Instance().GetContext();
jboolean const is24HourFormat = env->CallStaticBooleanMethod(dateUtilsClass,
is24HourFormatMethod,
context);
jobject const hoursMinutes = env->NewObject(g_clazzHoursMinutes,
g_ctorHoursMinutes,
hours,
minutes,
is24HourFormat);
jboolean const is24HourFormat = env->CallStaticBooleanMethod(dateUtilsClass, is24HourFormatMethod, context);
jobject const hoursMinutes = env->NewObject(g_clazzHoursMinutes, g_ctorHoursMinutes, hours, minutes, is24HourFormat);
ASSERT(hoursMinutes, (jni::DescribeException()));
return hoursMinutes;
}
@@ -74,8 +63,7 @@ jobject JavaTimespan(JNIEnv * env, osmoh::Timespan const & timespan)
{
auto const start = timespan.GetStart();
auto const end = timespan.GetEnd();
return JavaTimespan(env,
JavaHoursMinutes(env, start.GetHoursCount(), start.GetMinutesCount()),
return JavaTimespan(env, JavaHoursMinutes(env, start.GetHoursCount(), start.GetMinutesCount()),
JavaHoursMinutes(env, end.GetHoursCount(), end.GetMinutesCount()));
}
@@ -92,22 +80,16 @@ jobject JavaTimetable(JNIEnv * env, TimeTable const & tt)
std::set<Weekday> weekdays = tt.GetOpeningDays();
std::vector<int> weekdaysVector;
weekdaysVector.reserve(weekdays.size());
std::transform(weekdays.begin(), weekdays.end(), std::back_inserter(weekdaysVector), [](Weekday weekday)
{
return static_cast<int>(weekday);
});
std::transform(weekdays.begin(), weekdays.end(), std::back_inserter(weekdaysVector),
[](Weekday weekday) { return static_cast<int>(weekday); });
jintArray jWeekdays = env->NewIntArray(static_cast<jsize>(weekdays.size()));
env->SetIntArrayRegion(jWeekdays, 0, static_cast<jsize>(weekdaysVector.size()),
&weekdaysVector[0]);
env->SetIntArrayRegion(jWeekdays, 0, static_cast<jsize>(weekdaysVector.size()), &weekdaysVector[0]);
return JavaTimetable(env,
JavaTimespan(env, tt.GetOpeningTime()),
jni::ToJavaArray(env, g_clazzTimespan, tt.GetExcludeTime(), [](JNIEnv * env, osmoh::Timespan const & timespan)
{
return JavaTimespan(env, timespan);
}),
tt.IsTwentyFourHours(),
jWeekdays);
return JavaTimetable(
env, JavaTimespan(env, tt.GetOpeningTime()),
jni::ToJavaArray(env, g_clazzTimespan, tt.GetExcludeTime(),
[](JNIEnv * env, osmoh::Timespan const & timespan) { return JavaTimespan(env, timespan); }),
tt.IsTwentyFourHours(), jWeekdays);
}
jobjectArray JavaTimetables(JNIEnv * env, TimeTableSet & tts)
@@ -142,7 +124,7 @@ TimeTable NativeTimetable(JNIEnv * env, jobject jTimetable)
{
TimeTable tt = TimeTable::GetPredefinedTimeTable();
jintArray const jWeekdays = static_cast<jintArray>(env->GetObjectField(jTimetable, g_fidWeekdays));
int * weekdaysArr = static_cast<int*>(env->GetIntArrayElements(jWeekdays, nullptr));
int * weekdaysArr = static_cast<int *>(env->GetIntArrayElements(jWeekdays, nullptr));
jint size = env->GetArrayLength(jWeekdays);
std::set<Weekday> weekdays;
for (int i = 0; i < size; i++)
@@ -181,8 +163,7 @@ TimeTableSet NativeTimetableSet(JNIEnv * env, jobjectArray jTimetables)
extern "C"
{
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeInit(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeInit(JNIEnv * env, jclass clazz)
{
g_clazzHoursMinutes = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/data/HoursMinutes");
// Java signature : HoursMinutes(@IntRange(from = 0, to = 24) long hours, @IntRange(from = 0, to = 60) long minutes)
@@ -195,8 +176,9 @@ Java_app_organicmaps_sdk_editor_OpeningHours_nativeInit(JNIEnv * env, jclass cla
g_clazzTimespan = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/data/Timespan");
// Java signature : Timespan(HoursMinutes start, HoursMinutes end)
g_ctorTimespan =
env->GetMethodID(g_clazzTimespan, "<init>","(Lapp/organicmaps/sdk/editor/data/HoursMinutes;Lapp/organicmaps/sdk/editor/data/HoursMinutes;)V");
g_ctorTimespan = env->GetMethodID(
g_clazzTimespan, "<init>",
"(Lapp/organicmaps/sdk/editor/data/HoursMinutes;Lapp/organicmaps/sdk/editor/data/HoursMinutes;)V");
ASSERT(g_ctorTimespan, (jni::DescribeException()));
g_fidStart = env->GetFieldID(g_clazzTimespan, "start", "Lapp/organicmaps/sdk/editor/data/HoursMinutes;");
ASSERT(g_fidStart, (jni::DescribeException()));
@@ -206,11 +188,14 @@ Java_app_organicmaps_sdk_editor_OpeningHours_nativeInit(JNIEnv * env, jclass cla
g_clazzTimetable = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/data/Timetable");
// Java signature : Timetable(Timespan workingTime, Timespan[] closedHours, boolean isFullday, int weekdays[])
g_ctorTimetable =
env->GetMethodID(g_clazzTimetable, "<init>","(Lapp/organicmaps/sdk/editor/data/Timespan;[Lapp/organicmaps/sdk/editor/data/Timespan;Z[I)V");
env->GetMethodID(g_clazzTimetable, "<init>",
"(Lapp/organicmaps/sdk/editor/data/Timespan;[Lapp/organicmaps/sdk/editor/data/Timespan;Z[I)V");
ASSERT(g_ctorTimetable, (jni::DescribeException()));
g_fidWorkingTimespan = env->GetFieldID(g_clazzTimetable, "workingTimespan", "Lapp/organicmaps/sdk/editor/data/Timespan;");
g_fidWorkingTimespan =
env->GetFieldID(g_clazzTimetable, "workingTimespan", "Lapp/organicmaps/sdk/editor/data/Timespan;");
ASSERT(g_fidWorkingTimespan, (jni::DescribeException()));
g_fidClosedTimespans = env->GetFieldID(g_clazzTimetable, "closedTimespans", "[Lapp/organicmaps/sdk/editor/data/Timespan;");
g_fidClosedTimespans =
env->GetFieldID(g_clazzTimetable, "closedTimespans", "[Lapp/organicmaps/sdk/editor/data/Timespan;");
ASSERT(g_fidClosedTimespans, (jni::DescribeException()));
g_fidIsFullday = env->GetFieldID(g_clazzTimetable, "isFullday", "Z");
ASSERT(g_fidIsFullday, (jni::DescribeException()));
@@ -218,23 +203,22 @@ Java_app_organicmaps_sdk_editor_OpeningHours_nativeInit(JNIEnv * env, jclass cla
ASSERT(g_fidWeekdays, (jni::DescribeException()));
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeGetDefaultTimetables(JNIEnv * env, jclass clazz)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeGetDefaultTimetables(JNIEnv * env,
jclass clazz)
{
TimeTableSet tts;
return JavaTimetables(env, tts);
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeGetComplementTimetable(JNIEnv * env, jclass clazz, jobjectArray timetables)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeGetComplementTimetable(
JNIEnv * env, jclass clazz, jobjectArray timetables)
{
TimeTableSet const tts = NativeTimetableSet(env, timetables);
return JavaTimetable(env, tts.GetComplementTimeTable());
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeRemoveWorkingDay(JNIEnv * env, jclass clazz,
jobjectArray timetables, jint ttIndex, jint dayIndex)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeRemoveWorkingDay(
JNIEnv * env, jclass clazz, jobjectArray timetables, jint ttIndex, jint dayIndex)
{
TimeTableSet tts = NativeTimetableSet(env, timetables);
auto tt = tts.Get(ttIndex);
@@ -243,9 +227,8 @@ Java_app_organicmaps_sdk_editor_OpeningHours_nativeRemoveWorkingDay(JNIEnv * env
return JavaTimetables(env, tts);
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeAddWorkingDay(JNIEnv * env, jclass clazz,
jobjectArray timetables, jint ttIndex, jint dayIndex)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeAddWorkingDay(
JNIEnv * env, jclass clazz, jobjectArray timetables, jint ttIndex, jint dayIndex)
{
TimeTableSet tts = NativeTimetableSet(env, timetables);
auto tt = tts.Get(ttIndex);
@@ -254,9 +237,9 @@ Java_app_organicmaps_sdk_editor_OpeningHours_nativeAddWorkingDay(JNIEnv * env, j
return JavaTimetables(env, tts);
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeSetIsFullday(JNIEnv * env, jclass clazz,
jobject jTimetable, jboolean jIsFullday)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeSetIsFullday(JNIEnv * env, jclass clazz,
jobject jTimetable,
jboolean jIsFullday)
{
TimeTable tt = NativeTimetable(env, jTimetable);
if (jIsFullday)
@@ -269,46 +252,49 @@ Java_app_organicmaps_sdk_editor_OpeningHours_nativeSetIsFullday(JNIEnv * env, jc
return JavaTimetable(env, tt);
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeSetOpeningTime(JNIEnv * env, jclass clazz,
jobject jTimetable, jobject jOpeningTime)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeSetOpeningTime(JNIEnv * env, jclass clazz,
jobject jTimetable,
jobject jOpeningTime)
{
TimeTable tt = NativeTimetable(env, jTimetable);
tt.SetOpeningTime(NativeTimespan(env, jOpeningTime));
return JavaTimetable(env, tt);
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeAddClosedSpan(JNIEnv * env, jclass clazz,
jobject jTimetable, jobject jClosedSpan)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeAddClosedSpan(JNIEnv * env, jclass clazz,
jobject jTimetable,
jobject jClosedSpan)
{
TimeTable tt = NativeTimetable(env, jTimetable);
tt.AddExcludeTime(NativeTimespan(env, jClosedSpan));
return JavaTimetable(env, tt);
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeRemoveClosedSpan(JNIEnv * env, jclass clazz,
jobject jTimetable, jint jClosedSpanIndex)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeRemoveClosedSpan(JNIEnv * env,
jclass clazz,
jobject jTimetable,
jint jClosedSpanIndex)
{
TimeTable tt = NativeTimetable(env, jTimetable);
tt.RemoveExcludeTime(static_cast<size_t>(jClosedSpanIndex));
return JavaTimetable(env, tt);
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeTimetablesFromString(JNIEnv * env, jclass clazz, jstring jSource)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeTimetablesFromString(JNIEnv * env,
jclass clazz,
jstring jSource)
{
TimeTableSet tts;
std::string const source = jni::ToNativeString(env, jSource);
if (!source.empty() && MakeTimeTableSet(OpeningHours(source), tts))
if (!source.empty() && MakeTimeTableSet(OpeningHours(source), tts))
return JavaTimetables(env, tts);
return nullptr;
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeTimetablesToString(JNIEnv * env, jclass clazz, jobjectArray jTts)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeTimetablesToString(JNIEnv * env,
jclass clazz,
jobjectArray jTts)
{
TimeTableSet tts = NativeTimetableSet(env, jTts);
std::stringstream sstr;
@@ -316,35 +302,34 @@ Java_app_organicmaps_sdk_editor_OpeningHours_nativeTimetablesToString(JNIEnv * e
return jni::ToJavaString(env, sstr.str());
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeIsTimetableStringValid(JNIEnv * env, jclass clazz, jstring jSource)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeIsTimetableStringValid(JNIEnv * env,
jclass clazz,
jstring jSource)
{
return OpeningHours(jni::ToNativeString(env, jSource)).IsValid();
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_editor_OpeningHours_nativeCurrentState(JNIEnv * env, jclass clazz, jobjectArray jTts)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeCurrentState(JNIEnv * env, jclass clazz,
jobjectArray jTts)
{
TimeTableSet tts = NativeTimetableSet(env, jTts);
time_t const now = time(nullptr);
/// @todo We should check closed/open time for specific feature's timezone.
OpeningHours::InfoT ohInfo = MakeOpeningHours(tts).GetInfo(now);
jclass ohStateClass = jni::GetGlobalClassRef(env, "app/organicmaps/editor/OhState");
jclass ruleStateClass = jni::GetGlobalClassRef(env, "app/organicmaps/editor/OhState$State");
jclass ohStateClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/OhState");
jclass ruleStateClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/OhState$State");
static const std::unordered_map<RuleState, const char*> ruleState = {
{RuleState::Open, "Open"},
{RuleState::Closed, "Closed"},
{RuleState::Unknown, "Unknown"}
};
static std::unordered_map<RuleState, char const *> const ruleState = {
{RuleState::Open, "Open"}, {RuleState::Closed, "Closed"}, {RuleState::Unknown, "Unknown"}};
jfieldID stateField = env->GetStaticFieldID(ruleStateClass, ruleState.at(ohInfo.state), "Lapp/organicmaps/editor/OhState$State;");
jfieldID stateField =
env->GetStaticFieldID(ruleStateClass, ruleState.at(ohInfo.state), "Lapp/organicmaps/sdk/editor/OhState$State;");
jobject stateObj = env->GetStaticObjectField(ruleStateClass, stateField);
jmethodID constructor = env->GetMethodID(ohStateClass, "<init>", "(Lapp/organicmaps/editor/OhState$State;JJ)V");
jobject javaOhState = env->NewObject(ohStateClass, constructor, stateObj, (jlong) ohInfo.nextTimeOpen, (jlong) ohInfo.nextTimeClosed);
jmethodID constructor = env->GetMethodID(ohStateClass, "<init>", "(Lapp/organicmaps/sdk/editor/OhState$State;JJ)V");
jobject javaOhState =
env->NewObject(ohStateClass, constructor, stateObj, (jlong)ohInfo.nextTimeOpen, (jlong)ohInfo.nextTimeClosed);
return javaOhState;
}
} // extern "C"
} // extern "C"

View File

@@ -1,7 +1,7 @@
#include <jni.h>
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "app/organicmaps/sdk/Framework.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "base/logging.hpp"
#include "base/string_utils.hpp"
@@ -25,17 +25,15 @@ bool LoadOsmUserPreferences(std::string const & oauthToken, UserPreferences & ou
extern "C"
{
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOAuth2Url(JNIEnv * env, jclass)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOAuth2Url(JNIEnv * env, jclass)
{
auto const auth = OsmOAuth::ServerAuth();
return ToJavaString(env, auth.BuildOAuth2Url());
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_OsmOAuth_nativeAuthWithPassword(JNIEnv * env, jclass clazz,
jstring login, jstring password)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_OsmOAuth_nativeAuthWithPassword(JNIEnv * env, jclass clazz,
jstring login,
jstring password)
{
OsmOAuth auth = OsmOAuth::ServerAuth();
try
@@ -51,8 +49,8 @@ Java_app_organicmaps_sdk_editor_OsmOAuth_nativeAuthWithPassword(JNIEnv * env, jc
return nullptr;
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_OsmOAuth_nativeAuthWithOAuth2Code(JNIEnv * env, jclass, jstring oauth2code)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_OsmOAuth_nativeAuthWithOAuth2Code(JNIEnv * env, jclass,
jstring oauth2code)
{
OsmOAuth auth = OsmOAuth::ServerAuth();
try
@@ -60,8 +58,8 @@ Java_app_organicmaps_sdk_editor_OsmOAuth_nativeAuthWithOAuth2Code(JNIEnv * env,
auto token = auth.FinishAuthorization(ToNativeString(env, oauth2code));
if (!token.empty())
{
auth.SetAuthToken(token);
return ToJavaString(env, token);
auth.SetAuthToken(token);
return ToJavaString(env, token);
}
LOG(LWARNING, ("nativeAuthWithOAuth2Code: invalid OAuth2 code", oauth2code));
}
@@ -72,8 +70,8 @@ Java_app_organicmaps_sdk_editor_OsmOAuth_nativeAuthWithOAuth2Code(JNIEnv * env,
return nullptr;
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOsmUsername(JNIEnv * env, jclass, jstring oauthToken)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOsmUsername(JNIEnv * env, jclass,
jstring oauthToken)
{
UserPreferences prefs;
if (LoadOsmUserPreferences(jni::ToNativeString(env, oauthToken), prefs))
@@ -81,8 +79,8 @@ Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOsmUsername(JNIEnv * env, jcla
return nullptr;
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOsmChangesetsCount(JNIEnv * env, jclass, jstring oauthToken)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOsmChangesetsCount(JNIEnv * env, jclass,
jstring oauthToken)
{
UserPreferences prefs;
if (LoadOsmUserPreferences(jni::ToNativeString(env, oauthToken), prefs))
@@ -90,8 +88,8 @@ Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOsmChangesetsCount(JNIEnv * en
return -1;
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOsmProfilePictureUrl(JNIEnv * env, jclass, jstring oauthToken)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOsmProfilePictureUrl(JNIEnv * env, jclass,
jstring oauthToken)
{
UserPreferences prefs;
if (LoadOsmUserPreferences(jni::ToNativeString(env, oauthToken), prefs))
@@ -99,15 +97,14 @@ Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetOsmProfilePictureUrl(JNIEnv *
return nullptr;
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetHistoryUrl(JNIEnv * env, jclass, jstring user)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetHistoryUrl(JNIEnv * env, jclass,
jstring user)
{
return jni::ToJavaString(env, OsmOAuth::ServerAuth().GetHistoryURL(jni::ToNativeString(env, user)));
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetNotesUrl(JNIEnv * env, jclass, jstring user)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_editor_OsmOAuth_nativeGetNotesUrl(JNIEnv * env, jclass, jstring user)
{
return jni::ToJavaString(env, OsmOAuth::ServerAuth().GetNotesURL(jni::ToNativeString(env, user)));
}
} // extern "C"
} // extern "C"

View File

@@ -7,39 +7,34 @@ using namespace std::placeholders;
extern "C"
{
static void IsolinesStateChanged(IsolinesManager::IsolinesState state,
std::shared_ptr<jobject> const & listener)
static void IsolinesStateChanged(IsolinesManager::IsolinesState state, std::shared_ptr<jobject> const & listener)
{
LOG(LINFO, (static_cast<int>(state)));
JNIEnv * env = jni::GetEnv();
env->CallVoidMethod(*listener,
jni::GetMethodID(env, *listener, "onStateChanged", "(I)V"),
static_cast<jint>(state));
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener, "onStateChanged", "(I)V"), static_cast<jint>(state));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_maplayer_isolines_IsolinesManager_nativeAddListener(JNIEnv *env, jclass clazz, jobject listener)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_maplayer_isolines_IsolinesManager_nativeAddListener(JNIEnv * env,
jclass clazz,
jobject listener)
{
CHECK(g_framework, ("Framework isn't created yet!"));
g_framework->SetIsolinesListener(std::bind(&IsolinesStateChanged,
std::placeholders::_1,
jni::make_global_ref(listener)));
g_framework->SetIsolinesListener(
std::bind(&IsolinesStateChanged, std::placeholders::_1, jni::make_global_ref(listener)));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_maplayer_isolines_IsolinesManager_nativeRemoveListener(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_maplayer_isolines_IsolinesManager_nativeRemoveListener(JNIEnv * env,
jclass clazz)
{
CHECK(g_framework, ("Framework isn't created yet!"));
g_framework->SetIsolinesListener(nullptr);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_maplayer_isolines_IsolinesManager_nativeShouldShowNotification(JNIEnv *env,
jclass clazz)
Java_app_organicmaps_sdk_maplayer_isolines_IsolinesManager_nativeShouldShowNotification(JNIEnv * env, jclass clazz)
{
CHECK(g_framework, ("Framework isn't created yet!"));
auto const &manager = g_framework->NativeFramework()->GetIsolinesManager();
auto const & manager = g_framework->NativeFramework()->GetIsolinesManager();
auto const visible = manager.IsVisible();
auto const enabled = manager.GetState() == IsolinesManager::IsolinesState::Enabled;
return static_cast<jboolean>(!visible && enabled);

View File

@@ -7,10 +7,7 @@
namespace android
{
ConfigComparator::ConfigComparator(EGLDisplay display)
: m_display(display)
{
}
ConfigComparator::ConfigComparator(EGLDisplay display) : m_display(display) {}
bool ConfigComparator::operator()(EGLConfig const & l, EGLConfig const & r) const
{
@@ -28,14 +25,10 @@ int ConfigComparator::configWeight(EGLConfig const & config) const
switch (val)
{
case EGL_NONE:
return 0;
case EGL_SLOW_CONFIG:
return 1;
case EGL_NON_CONFORMANT_CONFIG:
return 2;
default:
return 0;
case EGL_NONE: return 0;
case EGL_SLOW_CONFIG: return 1;
case EGL_NON_CONFORMANT_CONFIG: return 2;
default: return 0;
}
}
@@ -53,21 +46,21 @@ std::string GetEglError(EGLint error)
{
switch (error)
{
case EGL_NOT_INITIALIZED : return "EGL_NOT_INITIALIZED";
case EGL_BAD_ACCESS : return "EGL_BAD_ACCESS";
case EGL_BAD_ALLOC : return "EGL_BAD_ALLOC";
case EGL_BAD_ATTRIBUTE : return "EGL_BAD_ATTRIBUTE";
case EGL_BAD_CONFIG : return "EGL_BAD_CONFIG";
case EGL_BAD_CONTEXT : return "EGL_BAD_CONTEXT";
case EGL_BAD_CURRENT_SURFACE : return "EGL_BAD_CURRENT_SURFACE";
case EGL_BAD_DISPLAY : return "EGL_BAD_DISPLAY";
case EGL_BAD_MATCH : return "EGL_BAD_MATCH";
case EGL_BAD_NATIVE_PIXMAP : return "EGL_BAD_NATIVE_PIXMAP";
case EGL_BAD_NATIVE_WINDOW : return "EGL_BAD_NATIVE_WINDOW";
case EGL_BAD_PARAMETER : return "EGL_BAD_PARAMETER";
case EGL_BAD_SURFACE : return "EGL_BAD_SURFACE";
case EGL_CONTEXT_LOST : return "EGL_CONTEXT_LOST";
default: return strings::to_string(error);
case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
default: return strings::to_string(error);
}
}

View File

@@ -25,5 +25,16 @@ private:
void CheckEGL(base::SrcPoint const & src);
} // namespace android
#define CHECK_EGL(x) do { (x); android::CheckEGL(SRC());} while(false);
#define CHECK_EGL_CALL() do { android::CheckEGL(SRC());} while (false);
#define CHECK_EGL(x) \
do \
{ \
(x); \
android::CheckEGL(SRC()); \
} \
while (false);
#define CHECK_EGL_CALL() \
do \
{ \
android::CheckEGL(SRC()); \
} \
while (false);

View File

@@ -8,21 +8,14 @@
namespace android
{
static EGLint * getContextAttributesList(bool supportedES3)
static EGLint * getContextAttributesList()
{
static EGLint contextAttrList[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
static EGLint contextAttrListES3[] = {
EGL_CONTEXT_CLIENT_VERSION, 3,
EGL_NONE
};
return supportedES3 ? contextAttrListES3 : contextAttrList;
static EGLint contextAttrList[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
return contextAttrList;
}
AndroidOGLContext::AndroidOGLContext(bool supportedES3, EGLDisplay display, EGLSurface surface,
EGLConfig config, AndroidOGLContext * contextToShareWith)
AndroidOGLContext::AndroidOGLContext(EGLDisplay display, EGLSurface surface, EGLConfig config,
AndroidOGLContext * contextToShareWith)
: m_nativeContext(EGL_NO_CONTEXT)
, m_surface(surface)
, m_display(display)
@@ -32,7 +25,7 @@ AndroidOGLContext::AndroidOGLContext(bool supportedES3, EGLDisplay display, EGLS
ASSERT(m_display != EGL_NO_DISPLAY, ());
EGLContext sharedContext = (contextToShareWith == NULL) ? EGL_NO_CONTEXT : contextToShareWith->m_nativeContext;
m_nativeContext = eglCreateContext(m_display, config, sharedContext, getContextAttributesList(supportedES3));
m_nativeContext = eglCreateContext(m_display, config, sharedContext, getContextAttributesList());
CHECK(m_nativeContext != EGL_NO_CONTEXT, ());
}
@@ -86,8 +79,7 @@ bool AndroidOGLContext::Validate()
{
if (!m_presentAvailable)
return false;
return eglGetCurrentDisplay() != EGL_NO_DISPLAY &&
eglGetCurrentSurface(EGL_DRAW) != EGL_NO_SURFACE &&
return eglGetCurrentDisplay() != EGL_NO_DISPLAY && eglGetCurrentSurface(EGL_DRAW) != EGL_NO_SURFACE &&
eglGetCurrentContext() != EGL_NO_CONTEXT;
}

View File

@@ -10,8 +10,7 @@ namespace android
class AndroidOGLContext : public dp::OGLContext
{
public:
AndroidOGLContext(bool supportedES3, EGLDisplay display, EGLSurface surface,
EGLConfig config, AndroidOGLContext * contextToShareWith);
AndroidOGLContext(EGLDisplay display, EGLSurface surface, EGLConfig config, AndroidOGLContext * contextToShareWith);
~AndroidOGLContext();
void MakeCurrent() override;

View File

@@ -16,64 +16,40 @@
#define EGL_OPENGL_ES3_BIT 0x00000040
int constexpr kMinSdkVersionForES3 = 21;
namespace android
{
namespace
{
static EGLint * getConfigAttributesListRGB8(bool supportedES3)
static EGLint * getConfigAttributesListRGB8()
{
static EGLint attr_list[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_DEPTH_SIZE, 16,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
EGL_NONE
};
static EGLint attr_list_es3[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_DEPTH_SIZE, 16,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
EGL_NONE
};
return supportedES3 ? attr_list_es3 : attr_list;
static EGLint attr_list[] = {EGL_RED_SIZE,
8,
EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE,
8,
EGL_ALPHA_SIZE,
0,
EGL_STENCIL_SIZE,
0,
EGL_DEPTH_SIZE,
16,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES3_BIT,
EGL_SURFACE_TYPE,
EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
EGL_NONE};
return attr_list;
}
int const kMaxConfigCount = 40;
static EGLint * getConfigAttributesListR5G6B5()
{
// We do not support OpenGL ES3 for R5G6B5, because some Android devices
// are not able to create OpenGL context in such mode.
static EGLint attr_list[] = {
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_STENCIL_SIZE, 0,
EGL_DEPTH_SIZE, 16,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
EGL_NONE
};
return attr_list;
}
bool IsSupportedRGB8(EGLDisplay display, bool es3)
bool IsSupportedRGB8(EGLDisplay display)
{
EGLConfig configs[kMaxConfigCount];
int count = 0;
return eglChooseConfig(display, getConfigAttributesListRGB8(es3), configs,
kMaxConfigCount, &count) == EGL_TRUE && count != 0;
return eglChooseConfig(display, getConfigAttributesListRGB8(), configs, kMaxConfigCount, &count) == EGL_TRUE &&
count != 0;
}
size_t constexpr kGLThreadsCount = 2;
@@ -90,7 +66,6 @@ AndroidOGLContextFactory::AndroidOGLContextFactory(JNIEnv * env, jobject jsurfac
, m_surfaceWidth(0)
, m_surfaceHeight(0)
, m_windowSurfaceValid(false)
, m_supportedES3(false)
{
m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (m_display == EGL_NO_DISPLAY)
@@ -106,10 +81,7 @@ AndroidOGLContextFactory::AndroidOGLContextFactory(JNIEnv * env, jobject jsurfac
return;
}
// Check ES3 availability.
bool const isES3Supported = IsSupportedRGB8(m_display, true /* es3 */) &&
android_get_device_api_level() >= kMinSdkVersionForES3;
m_supportedES3 = isES3Supported && gl3stubInit();
CHECK(gl3stubInit(), ("Could not initialize OpenGL ES3"));
SetSurface(env, jsurface);
@@ -223,8 +195,7 @@ int AndroidOGLContextFactory::GetHeight() const
void AndroidOGLContextFactory::UpdateSurfaceSize(int w, int h)
{
ASSERT(IsValid(), ());
if ((m_surfaceWidth != w && m_surfaceWidth != h) ||
(m_surfaceHeight != w && m_surfaceHeight != h))
if ((m_surfaceWidth != w && m_surfaceWidth != h) || (m_surfaceHeight != w && m_surfaceHeight != h))
{
LOG(LINFO, ("Surface size changed and must be re-queried."));
if (!QuerySurfaceSize())
@@ -265,10 +236,7 @@ dp::GraphicsContext * AndroidOGLContextFactory::GetDrawContext()
ASSERT(IsValid(), ());
ASSERT(m_windowSurface != EGL_NO_SURFACE, ());
if (m_drawContext == nullptr)
{
m_drawContext = new AndroidOGLContext(m_supportedES3, m_display, m_windowSurface,
m_config, m_uploadContext);
}
m_drawContext = new AndroidOGLContext(m_display, m_windowSurface, m_config, m_uploadContext);
return m_drawContext;
}
@@ -277,10 +245,7 @@ dp::GraphicsContext * AndroidOGLContextFactory::GetResourcesUploadContext()
ASSERT(IsValid(), ());
ASSERT(m_pixelbufferSurface != EGL_NO_SURFACE, ());
if (m_uploadContext == nullptr)
{
m_uploadContext = new AndroidOGLContext(m_supportedES3, m_display, m_pixelbufferSurface,
m_config, m_drawContext);
}
m_uploadContext = new AndroidOGLContext(m_display, m_pixelbufferSurface, m_config, m_drawContext);
return m_uploadContext;
}
@@ -322,17 +287,14 @@ bool AndroidOGLContextFactory::CreateWindowSurface()
{
EGLConfig configs[kMaxConfigCount];
int count = 0;
if (eglChooseConfig(m_display, getConfigAttributesListRGB8(m_supportedES3), configs,
kMaxConfigCount, &count) != EGL_TRUE)
if (eglChooseConfig(m_display, getConfigAttributesListRGB8(), configs, kMaxConfigCount, &count) == EGL_TRUE)
{
ASSERT(!m_supportedES3, ());
VERIFY(eglChooseConfig(m_display, getConfigAttributesListR5G6B5(), configs,
kMaxConfigCount, &count) == EGL_TRUE, ());
LOG(LDEBUG, ("Backbuffer format: R5G6B5"));
CHECK(IsSupportedRGB8(m_display), ("RGB8 is not suported on this device"));
LOG(LDEBUG, ("Backbuffer format: RGB8"));
}
else
{
LOG(LDEBUG, ("Backbuffer format: RGB8"));
CHECK(false, ("OpenGL ES3 is not supported"));
}
ASSERT(count > 0, ("Didn't find any configs."));
@@ -345,7 +307,7 @@ bool AndroidOGLContextFactory::CreateWindowSurface()
eglGetConfigAttrib(m_display, currentConfig, EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry(m_nativeWindow, 0, 0, format);
EGLint surfaceAttributes[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };
EGLint surfaceAttributes[] = {EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE};
m_windowSurface = eglCreateWindowSurface(m_display, currentConfig, m_nativeWindow, surfaceAttributes);
if (m_windowSurface == EGL_NO_SURFACE)
continue;
@@ -366,14 +328,10 @@ bool AndroidOGLContextFactory::CreateWindowSurface()
bool AndroidOGLContextFactory::CreatePixelbufferSurface()
{
//ASSERT(m_config != NULL, ());
// ASSERT(m_config != NULL, ());
const GLuint size = 1; // yes, 1 is the correct size, we dont really draw on it
static EGLint surfaceConfig[] = {
EGL_WIDTH, size,
EGL_HEIGHT, size,
EGL_NONE
};
GLuint const size = 1; // yes, 1 is the correct size, we dont really draw on it
static EGLint surfaceConfig[] = {EGL_WIDTH, size, EGL_HEIGHT, size, EGL_NONE};
m_pixelbufferSurface = eglCreatePbufferSurface(m_display, m_config, surfaceConfig);

View File

@@ -1,7 +1,7 @@
#pragma once
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "androidoglcontext.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "drape/graphics_context_factory.hpp"
#include "base/src_point.hpp"
@@ -33,8 +33,6 @@ public:
int GetHeight() const;
void UpdateSurfaceSize(int w, int h);
bool IsSupportedOpenGLES3() const { return m_supportedES3; }
private:
bool QuerySurfaceSize();
@@ -47,7 +45,7 @@ private:
EGLSurface m_windowSurface;
EGLSurface m_pixelbufferSurface;
EGLConfig m_config;
EGLConfig m_config;
ANativeWindow * m_nativeWindow;
EGLDisplay m_display;
@@ -56,7 +54,6 @@ private:
int m_surfaceHeight;
bool m_windowSurfaceValid;
bool m_supportedES3;
bool m_isInitialized = false;
size_t m_initializationCounter = 0;

View File

@@ -16,327 +16,289 @@
#include "gl3stub.h"
GLboolean gl3stubInit() {
#define FIND_PROC(s) s = reinterpret_cast<decltype(s)>(eglGetProcAddress(#s))
FIND_PROC(glReadBuffer);
FIND_PROC(glDrawRangeElements);
FIND_PROC(glTexImage3D);
FIND_PROC(glTexSubImage3D);
FIND_PROC(glCopyTexSubImage3D);
FIND_PROC(glCompressedTexImage3D);
FIND_PROC(glCompressedTexSubImage3D);
FIND_PROC(glGenQueries);
FIND_PROC(glDeleteQueries);
FIND_PROC(glIsQuery);
FIND_PROC(glBeginQuery);
FIND_PROC(glEndQuery);
FIND_PROC(glGetQueryiv);
FIND_PROC(glGetQueryObjectuiv);
FIND_PROC(glUnmapBuffer);
FIND_PROC(glGetBufferPointerv);
FIND_PROC(glDrawBuffers);
FIND_PROC(glUniformMatrix2x3fv);
FIND_PROC(glUniformMatrix3x2fv);
FIND_PROC(glUniformMatrix2x4fv);
FIND_PROC(glUniformMatrix4x2fv);
FIND_PROC(glUniformMatrix3x4fv);
FIND_PROC(glUniformMatrix4x3fv);
FIND_PROC(glBlitFramebuffer);
FIND_PROC(glRenderbufferStorageMultisample);
FIND_PROC(glFramebufferTextureLayer);
FIND_PROC(glMapBufferRange);
FIND_PROC(glFlushMappedBufferRange);
FIND_PROC(glBindVertexArray);
FIND_PROC(glDeleteVertexArrays);
FIND_PROC(glGenVertexArrays);
FIND_PROC(glIsVertexArray);
FIND_PROC(glGetIntegeri_v);
FIND_PROC(glBeginTransformFeedback);
FIND_PROC(glEndTransformFeedback);
FIND_PROC(glBindBufferRange);
FIND_PROC(glBindBufferBase);
FIND_PROC(glTransformFeedbackVaryings);
FIND_PROC(glGetTransformFeedbackVarying);
FIND_PROC(glVertexAttribIPointer);
FIND_PROC(glGetVertexAttribIiv);
FIND_PROC(glGetVertexAttribIuiv);
FIND_PROC(glVertexAttribI4i);
FIND_PROC(glVertexAttribI4ui);
FIND_PROC(glVertexAttribI4iv);
FIND_PROC(glVertexAttribI4uiv);
FIND_PROC(glGetUniformuiv);
FIND_PROC(glGetFragDataLocation);
FIND_PROC(glUniform1ui);
FIND_PROC(glUniform2ui);
FIND_PROC(glUniform3ui);
FIND_PROC(glUniform4ui);
FIND_PROC(glUniform1uiv);
FIND_PROC(glUniform2uiv);
FIND_PROC(glUniform3uiv);
FIND_PROC(glUniform4uiv);
FIND_PROC(glClearBufferiv);
FIND_PROC(glClearBufferuiv);
FIND_PROC(glClearBufferfv);
FIND_PROC(glClearBufferfi);
FIND_PROC(glGetStringi);
FIND_PROC(glCopyBufferSubData);
FIND_PROC(glGetUniformIndices);
FIND_PROC(glGetActiveUniformsiv);
FIND_PROC(glGetUniformBlockIndex);
FIND_PROC(glGetActiveUniformBlockiv);
FIND_PROC(glGetActiveUniformBlockName);
FIND_PROC(glUniformBlockBinding);
FIND_PROC(glDrawArraysInstanced);
FIND_PROC(glDrawElementsInstanced);
FIND_PROC(glFenceSync);
FIND_PROC(glIsSync);
FIND_PROC(glDeleteSync);
FIND_PROC(glClientWaitSync);
FIND_PROC(glWaitSync);
FIND_PROC(glGetInteger64v);
FIND_PROC(glGetSynciv);
FIND_PROC(glGetInteger64i_v);
FIND_PROC(glGetBufferParameteri64v);
FIND_PROC(glGenSamplers);
FIND_PROC(glDeleteSamplers);
FIND_PROC(glIsSampler);
FIND_PROC(glBindSampler);
FIND_PROC(glSamplerParameteri);
FIND_PROC(glSamplerParameteriv);
FIND_PROC(glSamplerParameterf);
FIND_PROC(glSamplerParameterfv);
FIND_PROC(glGetSamplerParameteriv);
FIND_PROC(glGetSamplerParameterfv);
FIND_PROC(glVertexAttribDivisor);
FIND_PROC(glBindTransformFeedback);
FIND_PROC(glDeleteTransformFeedbacks);
FIND_PROC(glGenTransformFeedbacks);
FIND_PROC(glIsTransformFeedback);
FIND_PROC(glPauseTransformFeedback);
FIND_PROC(glResumeTransformFeedback);
FIND_PROC(glGetProgramBinary);
FIND_PROC(glProgramBinary);
FIND_PROC(glProgramParameteri);
FIND_PROC(glInvalidateFramebuffer);
FIND_PROC(glInvalidateSubFramebuffer);
FIND_PROC(glTexStorage2D);
FIND_PROC(glTexStorage3D);
FIND_PROC(glGetInternalformativ);
#undef FIND_PROC
GLboolean gl3stubInit()
{
#define FIND_PROC(s) s = reinterpret_cast<decltype(s)>(eglGetProcAddress(#s))
FIND_PROC(glReadBuffer);
FIND_PROC(glDrawRangeElements);
FIND_PROC(glTexImage3D);
FIND_PROC(glTexSubImage3D);
FIND_PROC(glCopyTexSubImage3D);
FIND_PROC(glCompressedTexImage3D);
FIND_PROC(glCompressedTexSubImage3D);
FIND_PROC(glGenQueries);
FIND_PROC(glDeleteQueries);
FIND_PROC(glIsQuery);
FIND_PROC(glBeginQuery);
FIND_PROC(glEndQuery);
FIND_PROC(glGetQueryiv);
FIND_PROC(glGetQueryObjectuiv);
FIND_PROC(glUnmapBuffer);
FIND_PROC(glGetBufferPointerv);
FIND_PROC(glDrawBuffers);
FIND_PROC(glUniformMatrix2x3fv);
FIND_PROC(glUniformMatrix3x2fv);
FIND_PROC(glUniformMatrix2x4fv);
FIND_PROC(glUniformMatrix4x2fv);
FIND_PROC(glUniformMatrix3x4fv);
FIND_PROC(glUniformMatrix4x3fv);
FIND_PROC(glBlitFramebuffer);
FIND_PROC(glRenderbufferStorageMultisample);
FIND_PROC(glFramebufferTextureLayer);
FIND_PROC(glMapBufferRange);
FIND_PROC(glFlushMappedBufferRange);
FIND_PROC(glBindVertexArray);
FIND_PROC(glDeleteVertexArrays);
FIND_PROC(glGenVertexArrays);
FIND_PROC(glIsVertexArray);
FIND_PROC(glGetIntegeri_v);
FIND_PROC(glBeginTransformFeedback);
FIND_PROC(glEndTransformFeedback);
FIND_PROC(glBindBufferRange);
FIND_PROC(glBindBufferBase);
FIND_PROC(glTransformFeedbackVaryings);
FIND_PROC(glGetTransformFeedbackVarying);
FIND_PROC(glVertexAttribIPointer);
FIND_PROC(glGetVertexAttribIiv);
FIND_PROC(glGetVertexAttribIuiv);
FIND_PROC(glVertexAttribI4i);
FIND_PROC(glVertexAttribI4ui);
FIND_PROC(glVertexAttribI4iv);
FIND_PROC(glVertexAttribI4uiv);
FIND_PROC(glGetUniformuiv);
FIND_PROC(glGetFragDataLocation);
FIND_PROC(glUniform1ui);
FIND_PROC(glUniform2ui);
FIND_PROC(glUniform3ui);
FIND_PROC(glUniform4ui);
FIND_PROC(glUniform1uiv);
FIND_PROC(glUniform2uiv);
FIND_PROC(glUniform3uiv);
FIND_PROC(glUniform4uiv);
FIND_PROC(glClearBufferiv);
FIND_PROC(glClearBufferuiv);
FIND_PROC(glClearBufferfv);
FIND_PROC(glClearBufferfi);
FIND_PROC(glGetStringi);
FIND_PROC(glCopyBufferSubData);
FIND_PROC(glGetUniformIndices);
FIND_PROC(glGetActiveUniformsiv);
FIND_PROC(glGetUniformBlockIndex);
FIND_PROC(glGetActiveUniformBlockiv);
FIND_PROC(glGetActiveUniformBlockName);
FIND_PROC(glUniformBlockBinding);
FIND_PROC(glDrawArraysInstanced);
FIND_PROC(glDrawElementsInstanced);
FIND_PROC(glFenceSync);
FIND_PROC(glIsSync);
FIND_PROC(glDeleteSync);
FIND_PROC(glClientWaitSync);
FIND_PROC(glWaitSync);
FIND_PROC(glGetInteger64v);
FIND_PROC(glGetSynciv);
FIND_PROC(glGetInteger64i_v);
FIND_PROC(glGetBufferParameteri64v);
FIND_PROC(glGenSamplers);
FIND_PROC(glDeleteSamplers);
FIND_PROC(glIsSampler);
FIND_PROC(glBindSampler);
FIND_PROC(glSamplerParameteri);
FIND_PROC(glSamplerParameteriv);
FIND_PROC(glSamplerParameterf);
FIND_PROC(glSamplerParameterfv);
FIND_PROC(glGetSamplerParameteriv);
FIND_PROC(glGetSamplerParameterfv);
FIND_PROC(glVertexAttribDivisor);
FIND_PROC(glBindTransformFeedback);
FIND_PROC(glDeleteTransformFeedbacks);
FIND_PROC(glGenTransformFeedbacks);
FIND_PROC(glIsTransformFeedback);
FIND_PROC(glPauseTransformFeedback);
FIND_PROC(glResumeTransformFeedback);
FIND_PROC(glGetProgramBinary);
FIND_PROC(glProgramBinary);
FIND_PROC(glProgramParameteri);
FIND_PROC(glInvalidateFramebuffer);
FIND_PROC(glInvalidateSubFramebuffer);
FIND_PROC(glTexStorage2D);
FIND_PROC(glTexStorage3D);
FIND_PROC(glGetInternalformativ);
#undef FIND_PROC
if (!glReadBuffer ||
!glDrawRangeElements ||
!glTexImage3D ||
!glTexSubImage3D ||
!glCopyTexSubImage3D ||
!glCompressedTexImage3D ||
!glCompressedTexSubImage3D ||
!glGenQueries ||
!glDeleteQueries ||
!glIsQuery ||
!glBeginQuery ||
!glEndQuery ||
!glGetQueryiv ||
!glGetQueryObjectuiv ||
!glUnmapBuffer ||
!glGetBufferPointerv ||
!glDrawBuffers ||
!glUniformMatrix2x3fv ||
!glUniformMatrix3x2fv ||
!glUniformMatrix2x4fv ||
!glUniformMatrix4x2fv ||
!glUniformMatrix3x4fv ||
!glUniformMatrix4x3fv ||
!glBlitFramebuffer ||
!glRenderbufferStorageMultisample ||
!glFramebufferTextureLayer ||
!glMapBufferRange ||
!glFlushMappedBufferRange ||
!glBindVertexArray ||
!glDeleteVertexArrays ||
!glGenVertexArrays ||
!glIsVertexArray ||
!glGetIntegeri_v ||
!glBeginTransformFeedback ||
!glEndTransformFeedback ||
!glBindBufferRange ||
!glBindBufferBase ||
!glTransformFeedbackVaryings ||
!glGetTransformFeedbackVarying ||
!glVertexAttribIPointer ||
!glGetVertexAttribIiv ||
!glGetVertexAttribIuiv ||
!glVertexAttribI4i ||
!glVertexAttribI4ui ||
!glVertexAttribI4iv ||
!glVertexAttribI4uiv ||
!glGetUniformuiv ||
!glGetFragDataLocation ||
!glUniform1ui ||
!glUniform2ui ||
!glUniform3ui ||
!glUniform4ui ||
!glUniform1uiv ||
!glUniform2uiv ||
!glUniform3uiv ||
!glUniform4uiv ||
!glClearBufferiv ||
!glClearBufferuiv ||
!glClearBufferfv ||
!glClearBufferfi ||
!glGetStringi ||
!glCopyBufferSubData ||
!glGetUniformIndices ||
!glGetActiveUniformsiv ||
!glGetUniformBlockIndex ||
!glGetActiveUniformBlockiv ||
!glGetActiveUniformBlockName ||
!glUniformBlockBinding ||
!glDrawArraysInstanced ||
!glDrawElementsInstanced ||
!glFenceSync ||
!glIsSync ||
!glDeleteSync ||
!glClientWaitSync ||
!glWaitSync ||
!glGetInteger64v ||
!glGetSynciv ||
!glGetInteger64i_v ||
!glGetBufferParameteri64v ||
!glGenSamplers ||
!glDeleteSamplers ||
!glIsSampler ||
!glBindSampler ||
!glSamplerParameteri ||
!glSamplerParameteriv ||
!glSamplerParameterf ||
!glSamplerParameterfv ||
!glGetSamplerParameteriv ||
!glGetSamplerParameterfv ||
!glVertexAttribDivisor ||
!glBindTransformFeedback ||
!glDeleteTransformFeedbacks ||
!glGenTransformFeedbacks ||
!glIsTransformFeedback ||
!glPauseTransformFeedback ||
!glResumeTransformFeedback ||
!glGetProgramBinary ||
!glProgramBinary ||
!glProgramParameteri ||
!glInvalidateFramebuffer ||
!glInvalidateSubFramebuffer ||
!glTexStorage2D ||
!glTexStorage3D ||
!glGetInternalformativ)
{
return GL_FALSE;
}
if (!glReadBuffer || !glDrawRangeElements || !glTexImage3D || !glTexSubImage3D || !glCopyTexSubImage3D ||
!glCompressedTexImage3D || !glCompressedTexSubImage3D || !glGenQueries || !glDeleteQueries || !glIsQuery ||
!glBeginQuery || !glEndQuery || !glGetQueryiv || !glGetQueryObjectuiv || !glUnmapBuffer || !glGetBufferPointerv ||
!glDrawBuffers || !glUniformMatrix2x3fv || !glUniformMatrix3x2fv || !glUniformMatrix2x4fv ||
!glUniformMatrix4x2fv || !glUniformMatrix3x4fv || !glUniformMatrix4x3fv || !glBlitFramebuffer ||
!glRenderbufferStorageMultisample || !glFramebufferTextureLayer || !glMapBufferRange ||
!glFlushMappedBufferRange || !glBindVertexArray || !glDeleteVertexArrays || !glGenVertexArrays ||
!glIsVertexArray || !glGetIntegeri_v || !glBeginTransformFeedback || !glEndTransformFeedback ||
!glBindBufferRange || !glBindBufferBase || !glTransformFeedbackVaryings || !glGetTransformFeedbackVarying ||
!glVertexAttribIPointer || !glGetVertexAttribIiv || !glGetVertexAttribIuiv || !glVertexAttribI4i ||
!glVertexAttribI4ui || !glVertexAttribI4iv || !glVertexAttribI4uiv || !glGetUniformuiv ||
!glGetFragDataLocation || !glUniform1ui || !glUniform2ui || !glUniform3ui || !glUniform4ui || !glUniform1uiv ||
!glUniform2uiv || !glUniform3uiv || !glUniform4uiv || !glClearBufferiv || !glClearBufferuiv || !glClearBufferfv ||
!glClearBufferfi || !glGetStringi || !glCopyBufferSubData || !glGetUniformIndices || !glGetActiveUniformsiv ||
!glGetUniformBlockIndex || !glGetActiveUniformBlockiv || !glGetActiveUniformBlockName || !glUniformBlockBinding ||
!glDrawArraysInstanced || !glDrawElementsInstanced || !glFenceSync || !glIsSync || !glDeleteSync ||
!glClientWaitSync || !glWaitSync || !glGetInteger64v || !glGetSynciv || !glGetInteger64i_v ||
!glGetBufferParameteri64v || !glGenSamplers || !glDeleteSamplers || !glIsSampler || !glBindSampler ||
!glSamplerParameteri || !glSamplerParameteriv || !glSamplerParameterf || !glSamplerParameterfv ||
!glGetSamplerParameteriv || !glGetSamplerParameterfv || !glVertexAttribDivisor || !glBindTransformFeedback ||
!glDeleteTransformFeedbacks || !glGenTransformFeedbacks || !glIsTransformFeedback || !glPauseTransformFeedback ||
!glResumeTransformFeedback || !glGetProgramBinary || !glProgramBinary || !glProgramParameteri ||
!glInvalidateFramebuffer || !glInvalidateSubFramebuffer || !glTexStorage2D || !glTexStorage3D ||
!glGetInternalformativ)
{
return GL_FALSE;
}
return GL_TRUE;
return GL_TRUE;
}
/* Function pointer definitions */
GL_APICALL void (* GL_APIENTRY glReadBuffer) (GLenum mode);
GL_APICALL void (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
GL_APICALL void (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
GL_APICALL void (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
GL_APICALL void (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids);
GL_APICALL void (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids);
GL_APICALL GLboolean (* GL_APIENTRY glIsQuery) (GLuint id);
GL_APICALL void (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id);
GL_APICALL void (* GL_APIENTRY glEndQuery) (GLenum target);
GL_APICALL void (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params);
GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params);
GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer) (GLenum target);
GL_APICALL void (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params);
GL_APICALL void (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs);
GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
GL_APICALL void (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length);
GL_APICALL void (* GL_APIENTRY glBindVertexArray) (GLuint array);
GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays);
GL_APICALL void (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays);
GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray) (GLuint array);
GL_APICALL void (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data);
GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode);
GL_APICALL void (* GL_APIENTRY glEndTransformFeedback) (void);
GL_APICALL void (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
GL_APICALL void (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer);
GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params);
GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params);
GL_APICALL void (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w);
GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v);
GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v);
GL_APICALL void (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params);
GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name);
GL_APICALL void (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0);
GL_APICALL void (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1);
GL_APICALL void (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2);
GL_APICALL void (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
GL_APICALL void (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value);
GL_APICALL void (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value);
GL_APICALL void (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value);
GL_APICALL void (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value);
GL_APICALL void (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value);
GL_APICALL void (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value);
GL_APICALL void (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
GL_APICALL void (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index);
GL_APICALL void (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
GL_APICALL void (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName);
GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
GL_APICALL void (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
GL_APICALL GLsync (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags);
GL_APICALL GLboolean (* GL_APIENTRY glIsSync) (GLsync sync);
GL_APICALL void (* GL_APIENTRY glDeleteSync) (GLsync sync);
GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
GL_APICALL void (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
GL_APICALL void (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params);
GL_APICALL void (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
GL_APICALL void (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data);
GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params);
GL_APICALL void (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers);
GL_APICALL void (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers);
GL_APICALL GLboolean (* GL_APIENTRY glIsSampler) (GLuint sampler);
GL_APICALL void (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler);
GL_APICALL void (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param);
GL_APICALL void (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param);
GL_APICALL void (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param);
GL_APICALL void (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param);
GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params);
GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params);
GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor);
GL_APICALL void (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id);
GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids);
GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids);
GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback) (GLuint id);
GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback) (void);
GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback) (void);
GL_APICALL void (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
GL_APICALL void (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
GL_APICALL void (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value);
GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
GL_APICALL void (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
GL_APICALL void (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
GL_APICALL void (*GL_APIENTRY glReadBuffer)(GLenum mode);
GL_APICALL void (*GL_APIENTRY glDrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
GLvoid const * indices);
GL_APICALL void (*GL_APIENTRY glTexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type,
GLvoid const * pixels);
GL_APICALL void (*GL_APIENTRY glTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
GLvoid const * pixels);
GL_APICALL void (*GL_APIENTRY glCopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void (*GL_APIENTRY glCompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLint border, GLsizei imageSize,
GLvoid const * data);
GL_APICALL void (*GL_APIENTRY glCompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLsizei imageSize, GLvoid const * data);
GL_APICALL void (*GL_APIENTRY glGenQueries)(GLsizei n, GLuint * ids);
GL_APICALL void (*GL_APIENTRY glDeleteQueries)(GLsizei n, GLuint const * ids);
GL_APICALL GLboolean (*GL_APIENTRY glIsQuery)(GLuint id);
GL_APICALL void (*GL_APIENTRY glBeginQuery)(GLenum target, GLuint id);
GL_APICALL void (*GL_APIENTRY glEndQuery)(GLenum target);
GL_APICALL void (*GL_APIENTRY glGetQueryiv)(GLenum target, GLenum pname, GLint * params);
GL_APICALL void (*GL_APIENTRY glGetQueryObjectuiv)(GLuint id, GLenum pname, GLuint * params);
GL_APICALL GLboolean (*GL_APIENTRY glUnmapBuffer)(GLenum target);
GL_APICALL void (*GL_APIENTRY glGetBufferPointerv)(GLenum target, GLenum pname, GLvoid ** params);
GL_APICALL void (*GL_APIENTRY glDrawBuffers)(GLsizei n, GLenum const * bufs);
GL_APICALL void (*GL_APIENTRY glUniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose,
GLfloat const * value);
GL_APICALL void (*GL_APIENTRY glUniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose,
GLfloat const * value);
GL_APICALL void (*GL_APIENTRY glUniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose,
GLfloat const * value);
GL_APICALL void (*GL_APIENTRY glUniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose,
GLfloat const * value);
GL_APICALL void (*GL_APIENTRY glUniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose,
GLfloat const * value);
GL_APICALL void (*GL_APIENTRY glUniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose,
GLfloat const * value);
GL_APICALL void (*GL_APIENTRY glBlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
GL_APICALL void (*GL_APIENTRY glRenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat,
GLsizei width, GLsizei height);
GL_APICALL void (*GL_APIENTRY glFramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level,
GLint layer);
GL_APICALL GLvoid * (*GL_APIENTRY glMapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length,
GLbitfield access);
GL_APICALL void (*GL_APIENTRY glFlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length);
GL_APICALL void (*GL_APIENTRY glBindVertexArray)(GLuint array);
GL_APICALL void (*GL_APIENTRY glDeleteVertexArrays)(GLsizei n, GLuint const * arrays);
GL_APICALL void (*GL_APIENTRY glGenVertexArrays)(GLsizei n, GLuint * arrays);
GL_APICALL GLboolean (*GL_APIENTRY glIsVertexArray)(GLuint array);
GL_APICALL void (*GL_APIENTRY glGetIntegeri_v)(GLenum target, GLuint index, GLint * data);
GL_APICALL void (*GL_APIENTRY glBeginTransformFeedback)(GLenum primitiveMode);
GL_APICALL void (*GL_APIENTRY glEndTransformFeedback)(void);
GL_APICALL void (*GL_APIENTRY glBindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptr offset,
GLsizeiptr size);
GL_APICALL void (*GL_APIENTRY glBindBufferBase)(GLenum target, GLuint index, GLuint buffer);
GL_APICALL void (*GL_APIENTRY glTransformFeedbackVaryings)(GLuint program, GLsizei count,
GLchar const * const * varyings, GLenum bufferMode);
GL_APICALL void (*GL_APIENTRY glGetTransformFeedbackVarying)(GLuint program, GLuint index, GLsizei bufSize,
GLsizei * length, GLsizei * size, GLenum * type,
GLchar * name);
GL_APICALL void (*GL_APIENTRY glVertexAttribIPointer)(GLuint index, GLint size, GLenum type, GLsizei stride,
GLvoid const * pointer);
GL_APICALL void (*GL_APIENTRY glGetVertexAttribIiv)(GLuint index, GLenum pname, GLint * params);
GL_APICALL void (*GL_APIENTRY glGetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint * params);
GL_APICALL void (*GL_APIENTRY glVertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w);
GL_APICALL void (*GL_APIENTRY glVertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
GL_APICALL void (*GL_APIENTRY glVertexAttribI4iv)(GLuint index, GLint const * v);
GL_APICALL void (*GL_APIENTRY glVertexAttribI4uiv)(GLuint index, GLuint const * v);
GL_APICALL void (*GL_APIENTRY glGetUniformuiv)(GLuint program, GLint location, GLuint * params);
GL_APICALL GLint (*GL_APIENTRY glGetFragDataLocation)(GLuint program, GLchar const * name);
GL_APICALL void (*GL_APIENTRY glUniform1ui)(GLint location, GLuint v0);
GL_APICALL void (*GL_APIENTRY glUniform2ui)(GLint location, GLuint v0, GLuint v1);
GL_APICALL void (*GL_APIENTRY glUniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2);
GL_APICALL void (*GL_APIENTRY glUniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
GL_APICALL void (*GL_APIENTRY glUniform1uiv)(GLint location, GLsizei count, GLuint const * value);
GL_APICALL void (*GL_APIENTRY glUniform2uiv)(GLint location, GLsizei count, GLuint const * value);
GL_APICALL void (*GL_APIENTRY glUniform3uiv)(GLint location, GLsizei count, GLuint const * value);
GL_APICALL void (*GL_APIENTRY glUniform4uiv)(GLint location, GLsizei count, GLuint const * value);
GL_APICALL void (*GL_APIENTRY glClearBufferiv)(GLenum buffer, GLint drawbuffer, GLint const * value);
GL_APICALL void (*GL_APIENTRY glClearBufferuiv)(GLenum buffer, GLint drawbuffer, GLuint const * value);
GL_APICALL void (*GL_APIENTRY glClearBufferfv)(GLenum buffer, GLint drawbuffer, GLfloat const * value);
GL_APICALL void (*GL_APIENTRY glClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
GL_APICALL const GLubyte * (*GL_APIENTRY glGetStringi)(GLenum name, GLuint index);
GL_APICALL void (*GL_APIENTRY glCopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset,
GLintptr writeOffset, GLsizeiptr size);
GL_APICALL void (*GL_APIENTRY glGetUniformIndices)(GLuint program, GLsizei uniformCount,
GLchar const * const * uniformNames, GLuint * uniformIndices);
GL_APICALL void (*GL_APIENTRY glGetActiveUniformsiv)(GLuint program, GLsizei uniformCount,
GLuint const * uniformIndices, GLenum pname, GLint * params);
GL_APICALL GLuint (*GL_APIENTRY glGetUniformBlockIndex)(GLuint program, GLchar const * uniformBlockName);
GL_APICALL void (*GL_APIENTRY glGetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname,
GLint * params);
GL_APICALL void (*GL_APIENTRY glGetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize,
GLsizei * length, GLchar * uniformBlockName);
GL_APICALL void (*GL_APIENTRY glUniformBlockBinding)(GLuint program, GLuint uniformBlockIndex,
GLuint uniformBlockBinding);
GL_APICALL void (*GL_APIENTRY glDrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
GL_APICALL void (*GL_APIENTRY glDrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, GLvoid const * indices,
GLsizei instanceCount);
GL_APICALL GLsync (*GL_APIENTRY glFenceSync)(GLenum condition, GLbitfield flags);
GL_APICALL GLboolean (*GL_APIENTRY glIsSync)(GLsync sync);
GL_APICALL void (*GL_APIENTRY glDeleteSync)(GLsync sync);
GL_APICALL GLenum (*GL_APIENTRY glClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout);
GL_APICALL void (*GL_APIENTRY glWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout);
GL_APICALL void (*GL_APIENTRY glGetInteger64v)(GLenum pname, GLint64 * params);
GL_APICALL void (*GL_APIENTRY glGetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length,
GLint * values);
GL_APICALL void (*GL_APIENTRY glGetInteger64i_v)(GLenum target, GLuint index, GLint64 * data);
GL_APICALL void (*GL_APIENTRY glGetBufferParameteri64v)(GLenum target, GLenum pname, GLint64 * params);
GL_APICALL void (*GL_APIENTRY glGenSamplers)(GLsizei count, GLuint * samplers);
GL_APICALL void (*GL_APIENTRY glDeleteSamplers)(GLsizei count, GLuint const * samplers);
GL_APICALL GLboolean (*GL_APIENTRY glIsSampler)(GLuint sampler);
GL_APICALL void (*GL_APIENTRY glBindSampler)(GLuint unit, GLuint sampler);
GL_APICALL void (*GL_APIENTRY glSamplerParameteri)(GLuint sampler, GLenum pname, GLint param);
GL_APICALL void (*GL_APIENTRY glSamplerParameteriv)(GLuint sampler, GLenum pname, GLint const * param);
GL_APICALL void (*GL_APIENTRY glSamplerParameterf)(GLuint sampler, GLenum pname, GLfloat param);
GL_APICALL void (*GL_APIENTRY glSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat const * param);
GL_APICALL void (*GL_APIENTRY glGetSamplerParameteriv)(GLuint sampler, GLenum pname, GLint * params);
GL_APICALL void (*GL_APIENTRY glGetSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat * params);
GL_APICALL void (*GL_APIENTRY glVertexAttribDivisor)(GLuint index, GLuint divisor);
GL_APICALL void (*GL_APIENTRY glBindTransformFeedback)(GLenum target, GLuint id);
GL_APICALL void (*GL_APIENTRY glDeleteTransformFeedbacks)(GLsizei n, GLuint const * ids);
GL_APICALL void (*GL_APIENTRY glGenTransformFeedbacks)(GLsizei n, GLuint * ids);
GL_APICALL GLboolean (*GL_APIENTRY glIsTransformFeedback)(GLuint id);
GL_APICALL void (*GL_APIENTRY glPauseTransformFeedback)(void);
GL_APICALL void (*GL_APIENTRY glResumeTransformFeedback)(void);
GL_APICALL void (*GL_APIENTRY glGetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei * length,
GLenum * binaryFormat, GLvoid * binary);
GL_APICALL void (*GL_APIENTRY glProgramBinary)(GLuint program, GLenum binaryFormat, GLvoid const * binary,
GLsizei length);
GL_APICALL void (*GL_APIENTRY glProgramParameteri)(GLuint program, GLenum pname, GLint value);
GL_APICALL void (*GL_APIENTRY glInvalidateFramebuffer)(GLenum target, GLsizei numAttachments,
GLenum const * attachments);
GL_APICALL void (*GL_APIENTRY glInvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments,
GLenum const * attachments, GLint x, GLint y, GLsizei width,
GLsizei height);
GL_APICALL void (*GL_APIENTRY glTexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width,
GLsizei height);
GL_APICALL void (*GL_APIENTRY glTexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth);
GL_APICALL void (*GL_APIENTRY glGetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname,
GLsizei bufSize, GLint * params);

View File

@@ -22,17 +22,15 @@ std::string Platform::GetMemoryInfo() const
if (env == nullptr)
return std::string();
static std::shared_ptr<jobject> classLogsManager = jni::make_global_ref(env->FindClass("app/organicmaps/sdk/util/log/LogsManager"));
static std::shared_ptr<jobject> classLogsManager =
jni::make_global_ref(env->FindClass("app/organicmaps/sdk/util/log/LogsManager"));
ASSERT(classLogsManager, ());
jobject context = android::Platform::Instance().GetContext();
static jmethodID const getMemoryInfoId
= jni::GetStaticMethodID(env,
static_cast<jclass>(*classLogsManager),
"getMemoryInfo",
"(Landroid/content/Context;)Ljava/lang/String;");
jstring const memInfoString = static_cast<jstring>(env->CallStaticObjectMethod(
static_cast<jclass>(*classLogsManager), getMemoryInfoId, context));
static jmethodID const getMemoryInfoId = jni::GetStaticMethodID(
env, static_cast<jclass>(*classLogsManager), "getMemoryInfo", "(Landroid/content/Context;)Ljava/lang/String;");
jstring const memInfoString = static_cast<jstring>(
env->CallStaticObjectMethod(static_cast<jclass>(*classLogsManager), getMemoryInfoId, context));
ASSERT(memInfoString, ());
return jni::ToNativeString(env, memInfoString);
@@ -41,20 +39,18 @@ std::string Platform::GetMemoryInfo() const
std::string Platform::DeviceName() const
{
JNIEnv * env = jni::GetEnv();
static jmethodID const getDeviceNameId = jni::GetStaticMethodID(env, g_utilsClazz, "getDeviceName",
"()Ljava/lang/String;");
auto const deviceName = static_cast<jstring>(env->CallStaticObjectMethod(g_utilsClazz,
getDeviceNameId));
static jmethodID const getDeviceNameId =
jni::GetStaticMethodID(env, g_utilsClazz, "getDeviceName", "()Ljava/lang/String;");
auto const deviceName = static_cast<jstring>(env->CallStaticObjectMethod(g_utilsClazz, getDeviceNameId));
return jni::ToNativeString(env, deviceName);
}
std::string Platform::DeviceModel() const
{
JNIEnv * env = jni::GetEnv();
static jmethodID const getDeviceModelId = jni::GetStaticMethodID(env, g_utilsClazz, "getDeviceModel",
"()Ljava/lang/String;");
auto const deviceModel = static_cast<jstring>(env->CallStaticObjectMethod(g_utilsClazz,
getDeviceModelId));
static jmethodID const getDeviceModelId =
jni::GetStaticMethodID(env, g_utilsClazz, "getDeviceModel", "()Ljava/lang/String;");
auto const deviceModel = static_cast<jstring>(env->CallStaticObjectMethod(g_utilsClazz, getDeviceModelId));
return jni::ToNativeString(env, deviceModel);
}
@@ -79,11 +75,14 @@ Platform::EConnectionType Platform::ConnectionStatus()
if (env == nullptr)
return EConnectionType::CONNECTION_NONE;
static std::shared_ptr<jobject> clazzConnectionState = jni::make_global_ref(env->FindClass("app/organicmaps/sdk/util/ConnectionState"));
static std::shared_ptr<jobject> clazzConnectionState =
jni::make_global_ref(env->FindClass("app/organicmaps/sdk/util/ConnectionState"));
ASSERT(clazzConnectionState, ());
static jmethodID const getConnectionMethodId = jni::GetStaticMethodID(env, static_cast<jclass>(*clazzConnectionState), "getConnectionState", "()B");
return static_cast<Platform::EConnectionType>(env->CallStaticByteMethod(static_cast<jclass>(*clazzConnectionState), getConnectionMethodId));
static jmethodID const getConnectionMethodId =
jni::GetStaticMethodID(env, static_cast<jclass>(*clazzConnectionState), "getConnectionState", "()B");
return static_cast<Platform::EConnectionType>(
env->CallStaticByteMethod(static_cast<jclass>(*clazzConnectionState), getConnectionMethodId));
}
Platform::ChargingStatus Platform::GetChargingStatus()
@@ -92,8 +91,7 @@ Platform::ChargingStatus Platform::GetChargingStatus()
if (env == nullptr)
return Platform::ChargingStatus::Unknown;
static jclass const clazzBatteryState =
jni::GetGlobalClassRef(env, "app/organicmaps/sdk/util/BatteryState");
static jclass const clazzBatteryState = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/util/BatteryState");
ASSERT(clazzBatteryState, ());
static jmethodID const getChargingMethodId =
@@ -109,8 +107,7 @@ uint8_t Platform::GetBatteryLevel()
if (env == nullptr)
return 100;
static auto const clazzBatteryState =
jni::GetGlobalClassRef(env, "app/organicmaps/sdk/util/BatteryState");
static auto const clazzBatteryState = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/util/BatteryState");
ASSERT(clazzBatteryState, ());
static auto const getLevelMethodId =
@@ -123,22 +120,21 @@ namespace platform
{
platform::NetworkPolicy GetCurrentNetworkPolicy()
{
JNIEnv *env = jni::GetEnv();
JNIEnv * env = jni::GetEnv();
return platform::NetworkPolicy(network_policy::GetCurrentNetworkUsageStatus(env));
}
}
} // namespace platform
namespace android
{
Platform::~Platform()
{
JNIEnv *env = jni::GetEnv();
JNIEnv * env = jni::GetEnv();
env->DeleteGlobalRef(m_context);
}
void Platform::Initialize(JNIEnv * env, jobject context, jstring apkPath,
jstring writablePath, jstring privatePath, jstring tmpPath,
jstring flavorName, jstring buildType, bool isTablet)
void Platform::Initialize(JNIEnv * env, jobject context, jstring apkPath, jstring writablePath, jstring privatePath,
jstring tmpPath, jstring flavorName, jstring buildType, bool isTablet)
{
m_context = env->NewGlobalRef(context);
m_guiThread = std::make_unique<GuiThread>();
@@ -156,12 +152,10 @@ void Platform::Initialize(JNIEnv * env, jobject context, jstring apkPath,
LOG(LINFO, ("Temporary path = ", m_tmpDir));
// IMPORTANT: This method SHOULD be called from UI thread to cache static jni ID-s inside.
(void) ConnectionStatus();
(void)ConnectionStatus();
}
void Platform::OnExternalStorageStatusChanged(bool isAvailable)
{
}
void Platform::OnExternalStorageStatusChanged(bool isAvailable) {}
void Platform::SetWritableDir(std::string const & dir)
{
@@ -173,7 +167,7 @@ void Platform::SetSettingsDir(std::string const & dir)
{
m_settingsDir = dir;
// Logger is not fully initialized here.
//LOG(LINFO, ("Settings path = ", m_settingsDir));
// LOG(LINFO, ("Settings path = ", m_settingsDir));
}
bool Platform::HasAvailableSpaceForWriting(uint64_t size) const
@@ -209,13 +203,11 @@ void Platform::AndroidSecureStorage::Save(std::string const & key, std::string c
Init(env);
static jmethodID const saveMethodId =
jni::GetStaticMethodID(env, m_secureStorageClass, "save",
"(Landroid/content/Context;Ljava/lang/String;"
"Ljava/lang/String;)V");
static jmethodID const saveMethodId = jni::GetStaticMethodID(env, m_secureStorageClass, "save",
"(Landroid/content/Context;Ljava/lang/String;"
"Ljava/lang/String;)V");
jobject context = android::Platform::Instance().GetContext();
env->CallStaticVoidMethod(m_secureStorageClass, saveMethodId,
context,
env->CallStaticVoidMethod(m_secureStorageClass, saveMethodId, context,
jni::TScopedLocalRef(env, jni::ToJavaString(env, key)).get(),
jni::TScopedLocalRef(env, jni::ToJavaString(env, value)).get());
}
@@ -228,14 +220,12 @@ bool Platform::AndroidSecureStorage::Load(std::string const & key, std::string &
Init(env);
static jmethodID const loadMethodId =
jni::GetStaticMethodID(env, m_secureStorageClass, "load",
"(Landroid/content/Context;Ljava/lang/String;)"
"Ljava/lang/String;");
static jmethodID const loadMethodId = jni::GetStaticMethodID(env, m_secureStorageClass, "load",
"(Landroid/content/Context;Ljava/lang/String;)"
"Ljava/lang/String;");
jobject context = android::Platform::Instance().GetContext();
auto const resultString = static_cast<jstring>(env->CallStaticObjectMethod(m_secureStorageClass,
loadMethodId, context,
jni::TScopedLocalRef(env, jni::ToJavaString(env, key)).get()));
auto const resultString = static_cast<jstring>(env->CallStaticObjectMethod(
m_secureStorageClass, loadMethodId, context, jni::TScopedLocalRef(env, jni::ToJavaString(env, key)).get()));
if (resultString == nullptr)
return false;
@@ -252,8 +242,7 @@ void Platform::AndroidSecureStorage::Remove(std::string const & key)
Init(env);
static jmethodID const removeMethodId =
jni::GetStaticMethodID(env, m_secureStorageClass, "remove",
"(Landroid/content/Context;Ljava/lang/String;)V");
jni::GetStaticMethodID(env, m_secureStorageClass, "remove", "(Landroid/content/Context;Ljava/lang/String;)V");
jobject context = android::Platform::Instance().GetContext();
env->CallStaticVoidMethod(m_secureStorageClass, removeMethodId, context,
jni::TScopedLocalRef(env, jni::ToJavaString(env, key)).get());

View File

@@ -20,8 +20,7 @@ public:
~Platform() override;
void Initialize(JNIEnv * env, jobject functorProcessObject, jstring apkPath, jstring writablePath,
jstring privatePath, jstring tmpPath, jstring flavorName,
jstring buildType, bool isTablet);
jstring privatePath, jstring tmpPath, jstring flavorName, jstring buildType, bool isTablet);
void OnExternalStorageStatusChanged(bool isAvailable);
@@ -53,4 +52,4 @@ private:
AndroidSecureStorage m_secureStorage;
jobject m_context;
};
} // namespace android
} // namespace android

View File

@@ -11,12 +11,8 @@ private:
jclass m_klass;
public:
HttpThread(std::string const & url,
downloader::IHttpThreadCallback & cb,
int64_t beg,
int64_t end,
int64_t expectedFileSize,
std::string const & pb)
HttpThread(std::string const & url, downloader::IHttpThreadCallback & cb, int64_t beg, int64_t end,
int64_t expectedFileSize, std::string const & pb)
{
JNIEnv * env = jni::GetEnv();
static jclass const klass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/downloader/ChunkTask");
@@ -35,14 +31,9 @@ public:
}
jni::TScopedLocalRef jUrl(env, jni::ToJavaString(env, url.c_str()));
jni::TScopedLocalRef localSelf(env, env->NewObject(klass,
initMethodId,
reinterpret_cast<jlong>(&cb),
jUrl.get(),
static_cast<jlong>(beg),
static_cast<jlong>(end),
static_cast<jlong>(expectedFileSize),
postBody.get()));
jni::TScopedLocalRef localSelf(
env, env->NewObject(klass, initMethodId, reinterpret_cast<jlong>(&cb), jUrl.get(), static_cast<jlong>(beg),
static_cast<jlong>(end), static_cast<jlong>(expectedFileSize), postBody.get()));
m_self = env->NewGlobalRef(localSelf.get());
ASSERT(m_self, ());
@@ -60,29 +51,26 @@ public:
namespace downloader
{
HttpThread * CreateNativeHttpThread(std::string const & url,
downloader::IHttpThreadCallback & cb,
int64_t beg,
int64_t end,
int64_t size,
std::string const & pb)
{
return new HttpThread(url, cb, beg, end, size, pb);
}
HttpThread * CreateNativeHttpThread(std::string const & url, downloader::IHttpThreadCallback & cb, int64_t beg,
int64_t end, int64_t size, std::string const & pb)
{
return new HttpThread(url, cb, beg, end, size, pb);
}
void DeleteNativeHttpThread(HttpThread * request)
{
delete request;
}
void DeleteNativeHttpThread(HttpThread * request)
{
delete request;
}
} // namespace downloader
extern "C"
{
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_ChunkTask_nativeOnWrite(JNIEnv * env, jclass clazz, jlong httpCallbackID, jlong beg, jbyteArray data, jlong size)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_ChunkTask_nativeOnWrite(JNIEnv * env, jclass clazz,
jlong httpCallbackID, jlong beg,
jbyteArray data, jlong size)
{
downloader::IHttpThreadCallback * cb = reinterpret_cast<downloader::IHttpThreadCallback*>(httpCallbackID);
downloader::IHttpThreadCallback * cb = reinterpret_cast<downloader::IHttpThreadCallback *>(httpCallbackID);
jbyte * buf = env->GetByteArrayElements(data, 0);
ASSERT(buf, ());
@@ -100,10 +88,12 @@ Java_app_organicmaps_sdk_downloader_ChunkTask_nativeOnWrite(JNIEnv * env, jclass
return ret;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_ChunkTask_nativeOnFinish(JNIEnv * env, jclass clazz, jlong httpCallbackID, jlong httpCode, jlong beg, jlong end)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_ChunkTask_nativeOnFinish(JNIEnv * env, jclass clazz,
jlong httpCallbackID,
jlong httpCode, jlong beg,
jlong end)
{
downloader::IHttpThreadCallback * cb = reinterpret_cast<downloader::IHttpThreadCallback*>(httpCallbackID);
downloader::IHttpThreadCallback * cb = reinterpret_cast<downloader::IHttpThreadCallback *>(httpCallbackID);
cb->OnFinish(static_cast<long>(httpCode), beg, end);
}
} // extern "C"
} // extern "C"

View File

@@ -1,5 +1,5 @@
#include "android/sdk/src/main/cpp/app/organicmaps/sdk/core/jni_helper.hpp"
#include "android/sdk/src/main/cpp/app/organicmaps/sdk/core/ScopedLocalRef.hpp"
#include "android/sdk/src/main/cpp/app/organicmaps/sdk/core/jni_helper.hpp"
#include "platform/locale.hpp"
@@ -22,11 +22,12 @@ std::string GetAndroidSystemLanguage()
}
static jclass const languageClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/util/Language");
static jmethodID const getDefaultLocaleId = jni::GetStaticMethodID(env, languageClass, "getDefaultLocale", "()Ljava/lang/String;");
static jmethodID const getDefaultLocaleId =
jni::GetStaticMethodID(env, languageClass, "getDefaultLocale", "()Ljava/lang/String;");
jni::TScopedLocalRef localeRef(env, env->CallStaticObjectMethod(languageClass, getDefaultLocaleId));
std::string res = jni::ToNativeString(env, (jstring) localeRef.get());
std::string res = jni::ToNativeString(env, (jstring)localeRef.get());
if (res.empty())
res = DEFAULT_LANG;
@@ -38,24 +39,24 @@ namespace platform
Locale GetCurrentLocale()
{
JNIEnv * env = jni::GetEnv();
static jmethodID const getLanguageCodeId = jni::GetStaticMethodID(env, g_utilsClazz, "getLanguageCode",
"()Ljava/lang/String;");
static jmethodID const getLanguageCodeId =
jni::GetStaticMethodID(env, g_utilsClazz, "getLanguageCode", "()Ljava/lang/String;");
jni::ScopedLocalRef languageCode(env, env->CallStaticObjectMethod(g_utilsClazz, getLanguageCodeId));
static jmethodID const getCountryCodeId = jni::GetStaticMethodID(env, g_utilsClazz, "getCountryCode",
"()Ljava/lang/String;");
static jmethodID const getCountryCodeId =
jni::GetStaticMethodID(env, g_utilsClazz, "getCountryCode", "()Ljava/lang/String;");
jni::ScopedLocalRef countryCode(env, env->CallStaticObjectMethod(g_utilsClazz, getCountryCodeId));
static jmethodID const getCurrencyCodeId = jni::GetStaticMethodID(env, g_utilsClazz, "getCurrencyCode",
"()Ljava/lang/String;");
static jmethodID const getCurrencyCodeId =
jni::GetStaticMethodID(env, g_utilsClazz, "getCurrencyCode", "()Ljava/lang/String;");
jni::ScopedLocalRef currencyCode(env, env->CallStaticObjectMethod(g_utilsClazz, getCurrencyCodeId));
static jmethodID const getDecimalSeparatorId = jni::GetStaticMethodID(env, g_utilsClazz, "getDecimalSeparator",
"()Ljava/lang/String;");
jni::ScopedLocalRef decimalSeparatorChar(env, env->CallStaticObjectMethod(g_utilsClazz, getDecimalSeparatorId));
static jmethodID const getDecimalSeparatorId =
jni::GetStaticMethodID(env, g_utilsClazz, "getDecimalSeparator", "()Ljava/lang/String;");
jni::ScopedLocalRef decimalSeparatorChar(env, env->CallStaticObjectMethod(g_utilsClazz, getDecimalSeparatorId));
static jmethodID const getGroupingSeparatorId = jni::GetStaticMethodID(env, g_utilsClazz, "getGroupingSeparator",
"()Ljava/lang/String;");
static jmethodID const getGroupingSeparatorId =
jni::GetStaticMethodID(env, g_utilsClazz, "getGroupingSeparator", "()Ljava/lang/String;");
jni::ScopedLocalRef groupingSeparatorChar(env, env->CallStaticObjectMethod(g_utilsClazz, getGroupingSeparatorId));
return {jni::ToNativeString(env, static_cast<jstring>(languageCode.get())),

View File

@@ -1,7 +1,7 @@
#include <jni.h>
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "app/organicmaps/sdk/core/ScopedLocalRef.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "app/organicmaps/sdk/platform/AndroidPlatform.hpp"
#include "platform/localization.hpp"
@@ -23,8 +23,7 @@ std::string GetLocalizedStringByUtil(jmethodID const & methodId, std::string con
jni::TScopedLocalRef strRef(env, jni::ToJavaString(env, str));
jobject context = android::Platform::Instance().GetContext();
jni::TScopedLocalRef localizedStrRef(env, env->CallStaticObjectMethod(g_utilsClazz, methodId,
context, strRef.get()));
jni::TScopedLocalRef localizedStrRef(env, env->CallStaticObjectMethod(g_utilsClazz, methodId, context, strRef.get()));
return jni::ToNativeString(env, static_cast<jstring>(localizedStrRef.get()));
}
} // namespace
@@ -52,12 +51,11 @@ std::string GetLocalizedString(std::string const & key)
std::string GetCurrencySymbol(std::string const & currencyCode)
{
JNIEnv * env = jni::GetEnv();
static auto const methodId = jni::GetStaticMethodID(env, g_utilsClazz, "getCurrencySymbol",
"(Ljava/lang/String;)Ljava/lang/String;");
static auto const methodId =
jni::GetStaticMethodID(env, g_utilsClazz, "getCurrencySymbol", "(Ljava/lang/String;)Ljava/lang/String;");
jni::TScopedLocalRef currencyCodeRef(env, jni::ToJavaString(env, currencyCode));
jni::TScopedLocalRef localizedStrRef(
env, env->CallStaticObjectMethod(g_utilsClazz, methodId, currencyCodeRef.get()));
jni::TScopedLocalRef localizedStrRef(env, env->CallStaticObjectMethod(g_utilsClazz, methodId, currencyCodeRef.get()));
return jni::ToNativeString(env, static_cast<jstring>(localizedStrRef.get()));
}

View File

@@ -30,8 +30,7 @@ public:
bool Open(std::string const & host, uint16_t port)
{
JNIEnv * env = jni::GetEnv();
static jmethodID const openMethod =
jni::GetMethodID(env, m_self, "open", "(Ljava/lang/String;I)Z");
static jmethodID const openMethod = jni::GetMethodID(env, m_self, "open", "(Ljava/lang/String;I)Z");
jni::TScopedLocalRef hostRef(env, jni::ToJavaString(env, host));
jboolean result = env->CallBooleanMethod(m_self, openMethod, hostRef.get(), static_cast<jint>(port));
if (jni::HandleJavaException(env))
@@ -55,7 +54,7 @@ public:
jboolean result = env->CallBooleanMethod(m_self, readMethod, array, static_cast<jint>(count));
if (jni::HandleJavaException(env))
return false;
//this call copies java byte array to native buffer
// this call copies java byte array to native buffer
env->GetByteArrayRegion(array, 0, count, reinterpret_cast<jbyte *>(data));
if (jni::HandleJavaException(env))
return false;
@@ -66,8 +65,8 @@ public:
{
JNIEnv * env = jni::GetEnv();
jni::TScopedLocalByteArrayRef arrayRef(env, env->NewByteArray(count));
//this call copies native buffer to java byte array
env->SetByteArrayRegion(arrayRef.get(), 0, count, reinterpret_cast<const jbyte *>(data));
// this call copies native buffer to java byte array
env->SetByteArrayRegion(arrayRef.get(), 0, count, reinterpret_cast<jbyte const *>(data));
static jmethodID const writeMethod = jni::GetMethodID(env, m_self, "write", "([BI)Z");
jboolean result = env->CallBooleanMethod(m_self, writeMethod, arrayRef.get(), static_cast<jint>(count));
if (jni::HandleJavaException(env))
@@ -81,11 +80,14 @@ public:
static jmethodID const setTimeoutMethod = jni::GetMethodID(env, m_self, "setTimeout", "(I)V");
env->CallVoidMethod(m_self, setTimeoutMethod, static_cast<jint>(milliseconds));
jni::HandleJavaException(env);
};
}
private:
jobject m_self;
};
std::unique_ptr<Socket> CreateSocket() { return std::make_unique<SocketImpl>(); }
std::unique_ptr<Socket> CreateSocket()
{
return std::make_unique<SocketImpl>();
}
} // namespace platform

View File

@@ -14,9 +14,8 @@ jobjectArray CreateJunctionInfoArray(JNIEnv * env, std::vector<geometry::PointWi
return jni::ToJavaArray(env, junctionClazz, junctionPoints,
[](JNIEnv * env, geometry::PointWithAltitude const & pointWithAltitude)
{
auto & point = pointWithAltitude.GetPoint();
return env->NewObject(junctionClazz, junctionConstructor, mercator::YToLat(point.y),
mercator::XToLon(point.x));
});
{
auto & point = pointWithAltitude.GetPoint();
return env->NewObject(junctionClazz, junctionConstructor, mercator::YToLat(point.y), mercator::XToLon(point.x));
});
}

View File

@@ -13,17 +13,15 @@ jobjectArray CreateRouteMarkDataArray(JNIEnv * env, std::vector<RouteMarkData> c
// int intermediateIndex, boolean isVisible, boolean isMyPosition,
// boolean isPassed, double lat, double lon)
static jmethodID const pointConstructor =
jni::GetConstructorID(env, pointClazz, "(Ljava/lang/String;Ljava/lang/String;IIZZZDD)V");
return jni::ToJavaArray(env, pointClazz, points,
[&](JNIEnv * jEnv, RouteMarkData const & data)
{
jni::TScopedLocalRef const title(env, jni::ToJavaString(env, data.m_title));
jni::TScopedLocalRef const subtitle(env, jni::ToJavaString(env, data.m_subTitle));
return env->NewObject(
pointClazz, pointConstructor, title.get(), subtitle.get(),
static_cast<jint>(data.m_pointType), static_cast<jint>(data.m_intermediateIndex),
static_cast<jboolean>(data.m_isVisible), static_cast<jboolean>(data.m_isMyPosition),
static_cast<jboolean>(data.m_isPassed), mercator::YToLat(data.m_position.y),
mercator::XToLon(data.m_position.x));
});
jni::GetConstructorID(env, pointClazz, "(Ljava/lang/String;Ljava/lang/String;IIZZZDD)V");
return jni::ToJavaArray(env, pointClazz, points, [&](JNIEnv * jEnv, RouteMarkData const & data)
{
jni::TScopedLocalRef const title(env, jni::ToJavaString(env, data.m_title));
jni::TScopedLocalRef const subtitle(env, jni::ToJavaString(env, data.m_subTitle));
return env->NewObject(pointClazz, pointConstructor, title.get(), subtitle.get(),
static_cast<jint>(data.m_pointType), static_cast<jint>(data.m_intermediateIndex),
static_cast<jboolean>(data.m_isVisible), static_cast<jboolean>(data.m_isMyPosition),
static_cast<jboolean>(data.m_isPassed), mercator::YToLat(data.m_position.y),
mercator::XToLon(data.m_position.x));
});
}

View File

@@ -15,21 +15,21 @@ jobject CreateRoutingInfo(JNIEnv * env, routing::FollowingInfo const & info, Rou
// vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
// int totalTime, SingleLaneInfo[] lanes)
static jmethodID const ctorRouteInfoID =
jni::GetConstructorID(env, klass,
"(Lapp/organicmaps/sdk/util/Distance;Lapp/organicmaps/sdk/util/Distance;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;DIIIII"
"[Lapp/organicmaps/sdk/routing/SingleLaneInfo;DZZ)V");
jni::GetConstructorID(env, klass,
"(Lapp/organicmaps/sdk/util/Distance;Lapp/organicmaps/sdk/util/Distance;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;DIIIII"
"[Lapp/organicmaps/sdk/routing/SingleLaneInfo;DZZ)V");
jobjectArray jLanes = CreateLanesInfo(env, info.m_lanes);
auto const isSpeedCamLimitExceeded = rm.IsSpeedCamLimitExceeded();
auto const shouldPlaySignal = rm.GetSpeedCamManager().ShouldPlayBeepSignal();
jobject const result = env->NewObject(
klass, ctorRouteInfoID, ToJavaDistance(env, info.m_distToTarget), ToJavaDistance(env, info.m_distToTurn),
jni::ToJavaString(env, info.m_currentStreetName), jni::ToJavaString(env, info.m_nextStreetName),
jni::ToJavaString(env, info.m_nextNextStreetName), info.m_completionPercent, info.m_turn, info.m_nextTurn,
info.m_pedestrianTurn, info.m_exitNum, info.m_time, jLanes, info.m_speedLimitMps,
static_cast<jboolean>(isSpeedCamLimitExceeded), static_cast<jboolean>(shouldPlaySignal));
klass, ctorRouteInfoID, ToJavaDistance(env, info.m_distToTarget), ToJavaDistance(env, info.m_distToTurn),
jni::ToJavaString(env, info.m_currentStreetName), jni::ToJavaString(env, info.m_nextStreetName),
jni::ToJavaString(env, info.m_nextNextStreetName), info.m_completionPercent, info.m_turn, info.m_nextTurn,
info.m_pedestrianTurn, info.m_exitNum, info.m_time, jLanes, info.m_speedLimitMps,
static_cast<jboolean>(isSpeedCamLimitExceeded), static_cast<jboolean>(shouldPlaySignal));
ASSERT(result, (jni::DescribeException()));
return result;
}

View File

@@ -25,7 +25,7 @@ jobjectArray CreateLanesInfo(JNIEnv * env, std::vector<routing::FollowingInfo::S
env->SetByteArrayRegion(singleLane.get(), 0, laneSize, lanes[j].m_lane.data());
jni::TScopedLocalRef singleLaneInfo(
env, env->NewObject(laneClass, ctorSingleLaneInfoID, singleLane.get(), lanes[j].m_isRecommended));
env, env->NewObject(laneClass, ctorSingleLaneInfoID, singleLane.get(), lanes[j].m_isRecommended));
ASSERT(singleLaneInfo.get(), (jni::DescribeException()));
env->SetObjectArrayElement(jLanes, j, singleLaneInfo.get());
}

View File

@@ -11,16 +11,16 @@ jobject CreateTransitRouteInfo(JNIEnv * env, TransitRouteInfo const & routeInfo)
jobjectArray steps = CreateTransitStepInfoArray(env, routeInfo.m_steps);
static jclass const transitRouteInfoClass =
jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/TransitRouteInfo");
jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/TransitRouteInfo");
// Java signature : TransitRouteInfo(@NonNull String totalDistance, @NonNull String totalDistanceUnits,
// int totalTimeInSec, @NonNull String totalPedestrianDistance, @NonNull String
// totalPedestrianDistanceUnits, int totalPedestrianTimeInSec, @NonNull
// TransitStepInfo[] steps)
static jmethodID const transitRouteInfoConstructor =
jni::GetConstructorID(env, transitRouteInfoClass,
"(Ljava/lang/String;Ljava/lang/String;I"
"Ljava/lang/String;Ljava/lang/String;I"
"[Lapp/organicmaps/sdk/routing/TransitStepInfo;)V");
jni::GetConstructorID(env, transitRouteInfoClass,
"(Ljava/lang/String;Ljava/lang/String;I"
"Ljava/lang/String;Ljava/lang/String;I"
"[Lapp/organicmaps/sdk/routing/TransitStepInfo;)V");
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, routeInfo.m_totalDistanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, routeInfo.m_totalDistanceUnitsSuffix));
jni::TScopedLocalRef const distancePedestrian(env, jni::ToJavaString(env, routeInfo.m_totalPedestrianDistanceStr));

View File

@@ -12,17 +12,15 @@ jobjectArray CreateTransitStepInfoArray(JNIEnv * env, std::vector<TransitStepInf
// Java signature : TransitStepInfo(int type, @Nullable String distance, @Nullable String distanceUnits,
// int timeInSec, @Nullable String number, int color, int intermediateIndex)
static jmethodID const transitStepConstructor =
jni::GetConstructorID(env, transitStepClass, "(ILjava/lang/String;Ljava/lang/String;ILjava/lang/String;II)V");
jni::GetConstructorID(env, transitStepClass, "(ILjava/lang/String;Ljava/lang/String;ILjava/lang/String;II)V");
return jni::ToJavaArray(
env, transitStepClass, steps,
[&](JNIEnv * jEnv, TransitStepInfo const & stepInfo)
{
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, stepInfo.m_distanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, stepInfo.m_distanceUnitsSuffix));
jni::TScopedLocalRef const number(env, jni::ToJavaString(env, stepInfo.m_number));
return env->NewObject(transitStepClass, transitStepConstructor, static_cast<jint>(stepInfo.m_type),
distance.get(), distanceUnits.get(), static_cast<jint>(stepInfo.m_timeInSec), number.get(),
static_cast<jint>(stepInfo.m_colorARGB), static_cast<jint>(stepInfo.m_intermediateIndex));
});
return jni::ToJavaArray(env, transitStepClass, steps, [&](JNIEnv * jEnv, TransitStepInfo const & stepInfo)
{
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, stepInfo.m_distanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, stepInfo.m_distanceUnitsSuffix));
jni::TScopedLocalRef const number(env, jni::ToJavaString(env, stepInfo.m_number));
return env->NewObject(transitStepClass, transitStepConstructor, static_cast<jint>(stepInfo.m_type), distance.get(),
distanceUnits.get(), static_cast<jint>(stepInfo.m_timeInSec), number.get(),
static_cast<jint>(stepInfo.m_colorARGB), static_cast<jint>(stepInfo.m_intermediateIndex));
});
}

View File

@@ -13,8 +13,9 @@ JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_search_DisplayedCategori
return jni::ToJavaStringArray(env, categories.GetKeys());
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_search_DisplayedCategories_nativeIsLangSupported(
JNIEnv * env, jclass, jstring langCode)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_search_DisplayedCategories_nativeIsLangSupported(JNIEnv * env,
jclass,
jstring langCode)
{
return search::DisplayedCategories::IsLanguageSupported(jni::ToNativeString(env, langCode));
}

View File

@@ -65,13 +65,12 @@ bool PopularityHasHigherPriority(bool hasPosition, double distanceInMeters)
return !hasPosition || distanceInMeters > search::Result::kPopularityHighPriorityMinDistance;
}
jobject ToJavaResult(Result const & result, search::ProductInfo const & productInfo,
bool hasPosition, double lat, double lon)
jobject ToJavaResult(Result const & result, search::ProductInfo const & productInfo, bool hasPosition, double lat,
double lon)
{
JNIEnv * env = jni::GetEnv();
jni::TScopedLocalIntArrayRef ranges(
env, env->NewIntArray(static_cast<jsize>(result.GetHighlightRangesCount() * 2)));
jni::TScopedLocalIntArrayRef ranges(env, env->NewIntArray(static_cast<jsize>(result.GetHighlightRangesCount() * 2)));
jint * rawArr = env->GetIntArrayElements(ranges, nullptr);
for (size_t i = 0; i < result.GetHighlightRangesCount(); i++)
{
@@ -81,8 +80,8 @@ jobject ToJavaResult(Result const & result, search::ProductInfo const & productI
}
env->ReleaseIntArrayElements(ranges.get(), rawArr, 0);
jni::TScopedLocalIntArrayRef descRanges(env, env->NewIntArray(
static_cast<jsize>(result.GetDescHighlightRangesCount() * 2)));
jni::TScopedLocalIntArrayRef descRanges(
env, env->NewIntArray(static_cast<jsize>(result.GetDescHighlightRangesCount() * 2)));
jint * rawArr2 = env->GetIntArrayElements(descRanges, nullptr);
for (size_t i = 0; i < result.GetDescHighlightRangesCount(); i++)
{
@@ -100,7 +99,8 @@ jobject ToJavaResult(Result const & result, search::ProductInfo const & productI
{
jni::TScopedLocalRef name(env, jni::ToJavaString(env, result.GetString()));
jni::TScopedLocalRef suggest(env, jni::ToJavaString(env, result.GetSuggestionString()));
return env->NewObject(g_resultClass, g_suggestConstructor, name.get(), suggest.get(), ll.m_lat, ll.m_lon, ranges.get(),descRanges.get());
return env->NewObject(g_resultClass, g_suggestConstructor, name.get(), suggest.get(), ll.m_lat, ll.m_lon,
ranges.get(), descRanges.get());
}
platform::Distance distance;
@@ -113,34 +113,31 @@ jobject ToJavaResult(Result const & result, search::ProductInfo const & productI
bool const popularityHasHigherPriority = PopularityHasHigherPriority(hasPosition, distanceInMeters);
bool const isFeature = result.GetResultType() == Result::Type::Feature;
jni::TScopedLocalRef featureId(env, usermark_helper::CreateFeatureId(env, isFeature ?
result.GetFeatureID() :
kEmptyFeatureId));
jni::TScopedLocalRef featureId(
env, usermark_helper::CreateFeatureId(env, isFeature ? result.GetFeatureID() : kEmptyFeatureId));
jni::TScopedLocalRef featureType(env, jni::ToJavaString(env, result.GetLocalizedFeatureType()));
jni::TScopedLocalRef address(env, jni::ToJavaString(env, result.GetAddress()));
jni::TScopedLocalRef dist(env, ToJavaDistance(env, distance));
jni::TScopedLocalRef description(env, jni::ToJavaString(env, result.GetFeatureDescription()));
jni::TScopedLocalRef desc(env, env->NewObject(g_descriptionClass, g_descriptionConstructor,
featureId.get(), featureType.get(), address.get(),
dist.get(), description.get(),
static_cast<jint>(result.IsOpenNow()),
result.GetMinutesUntilOpen(),result.GetMinutesUntilClosed(),
static_cast<jboolean>(popularityHasHigherPriority)));
jni::TScopedLocalRef desc(
env,
env->NewObject(g_descriptionClass, g_descriptionConstructor, featureId.get(), featureType.get(), address.get(),
dist.get(), description.get(), static_cast<jint>(result.IsOpenNow()), result.GetMinutesUntilOpen(),
result.GetMinutesUntilClosed(), static_cast<jboolean>(popularityHasHigherPriority)));
jni::TScopedLocalRef name(env, jni::ToJavaString(env, result.GetString()));
jni::TScopedLocalRef popularity(env, env->NewObject(g_popularityClass,
g_popularityConstructor,
jni::TScopedLocalRef popularity(env, env->NewObject(g_popularityClass, g_popularityConstructor,
/// @todo Restore when popularity will be available
0/*static_cast<jint>(result.GetRankingInfo().m_popularity)*/));
0 /*static_cast<jint>(result.GetRankingInfo().m_popularity)*/));
return env->NewObject(g_resultClass, g_resultConstructor, name.get(), desc.get(), ll.m_lat, ll.m_lon,
ranges.get(), descRanges.get(), popularity.get());
return env->NewObject(g_resultClass, g_resultConstructor, name.get(), desc.get(), ll.m_lat, ll.m_lon, ranges.get(),
descRanges.get(), popularity.get());
}
jobjectArray BuildSearchResults(vector<search::ProductInfo> const & productInfo,
bool hasPosition, double lat, double lon)
jobjectArray BuildSearchResults(vector<search::ProductInfo> const & productInfo, bool hasPosition, double lat,
double lon)
{
JNIEnv * env = jni::GetEnv();
@@ -154,8 +151,8 @@ jobjectArray BuildSearchResults(vector<search::ProductInfo> const & productInfo,
return jResults;
}
void OnResults(Results results, vector<search::ProductInfo> const & productInfo,
jlong timestamp, bool isMapAndTable, bool hasPosition, double lat, double lon)
void OnResults(Results results, vector<search::ProductInfo> const & productInfo, jlong timestamp, bool isMapAndTable,
bool hasPosition, double lat, double lon)
{
// Ignore results from obsolete searches.
if (g_queryTimestamp > timestamp)
@@ -203,8 +200,8 @@ void OnMapSearchResults(storage::DownloaderSearchResults const & results, long l
JNIEnv * env = jni::GetEnv();
jni::TScopedLocalObjectArrayRef jResults(env, BuildJavaMapResults(results.m_results));
env->CallVoidMethod(g_javaListener, g_mapResultsMethod, jResults.get(),
static_cast<jlong>(timestamp), results.m_endMarker);
env->CallVoidMethod(g_javaListener, g_mapResultsMethod, jResults.get(), static_cast<jlong>(timestamp),
results.m_endMarker);
}
void OnBookmarksSearchResults(search::BookmarksSearchParams::Results results,
@@ -221,8 +218,8 @@ void OnBookmarksSearchResults(search::BookmarksSearchParams::Results results,
vector<jlong> const tmp(results.cbegin(), results.cend());
env->SetLongArrayRegion(jResults.get(), 0, static_cast<jsize>(tmp.size()), tmp.data());
auto const method = (status == search::BookmarksSearchParams::Status::InProgress) ?
g_updateBookmarksResultsId : g_endBookmarksResultsId;
auto const method = (status == search::BookmarksSearchParams::Status::InProgress) ? g_updateBookmarksResultsId
: g_endBookmarksResultsId;
env->CallVoidMethod(g_javaListener, method, jResults.get(), static_cast<jlong>(timestamp));
}
@@ -231,151 +228,139 @@ void OnBookmarksSearchResults(search::BookmarksSearchParams::Results results,
extern "C"
{
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_search_SearchEngine_nativeInit(JNIEnv * env, jobject thiz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeInit(JNIEnv * env, jobject thiz)
{
g_javaListener = env->NewGlobalRef(thiz);
// public void onResultsUpdate(@NonNull SearchResult[] results, long timestamp)
g_updateResultsId =
jni::GetMethodID(env, g_javaListener, "onResultsUpdate", "([Lapp/organicmaps/sdk/search/SearchResult;J)V");
// public void onResultsEnd(long timestamp)
g_endResultsId = jni::GetMethodID(env, g_javaListener, "onResultsEnd", "(J)V");
g_resultClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/search/SearchResult");
g_resultConstructor =
jni::GetConstructorID(env, g_resultClass,
"(Ljava/lang/String;Lapp/organicmaps/sdk/search/SearchResult$Description;DD[I[I"
"Lapp/organicmaps/sdk/search/Popularity;)V");
g_suggestConstructor = jni::GetConstructorID(env, g_resultClass, "(Ljava/lang/String;Ljava/lang/String;DD[I[I)V");
g_descriptionClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/search/SearchResult$Description");
/*
Description(FeatureId featureId, String featureType, String region, Distance distance,
String description, int openNow, int minutesUntilOpen, int minutesUntilClosed,
boolean hasPopularityHigherPriority)
*/
g_descriptionConstructor =
jni::GetConstructorID(env, g_descriptionClass,
"(Lapp/organicmaps/sdk/bookmarks/data/FeatureId;"
"Ljava/lang/String;Ljava/lang/String;Lapp/organicmaps/sdk/util/Distance;"
"Ljava/lang/String;IIIZ)V");
g_popularityClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/search/Popularity");
g_popularityConstructor = jni::GetConstructorID(env, g_popularityClass, "(I)V");
g_mapResultsMethod = jni::GetMethodID(env, g_javaListener, "onMapSearchResults",
"([Lapp/organicmaps/sdk/search/MapSearchListener$Result;JZ)V");
g_mapResultClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/search/MapSearchListener$Result");
g_mapResultCtor = jni::GetConstructorID(env, g_mapResultClass, "(Ljava/lang/String;Ljava/lang/String;)V");
g_updateBookmarksResultsId = jni::GetMethodID(env, g_javaListener, "onBookmarkSearchResultsUpdate", "([JJ)V");
g_endBookmarksResultsId = jni::GetMethodID(env, g_javaListener, "onBookmarkSearchResultsEnd", "([JJ)V");
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeRunSearch(
JNIEnv * env, jclass clazz, jbyteArray bytes, jboolean isCategory, jstring lang, jlong timestamp,
jboolean hasPosition, jdouble lat, jdouble lon)
{
search::EverywhereSearchParams params{jni::ToNativeString(env, bytes),
jni::ToNativeString(env, lang),
{}, // default timeout
static_cast<bool>(isCategory),
bind(&OnResults, _1, _2, timestamp, false, hasPosition, lat, lon)};
bool const searchStarted = g_framework->NativeFramework()->GetSearchAPI().SearchEverywhere(std::move(params));
if (searchStarted)
g_queryTimestamp = timestamp;
return searchStarted;
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeRunInteractiveSearch(
JNIEnv * env, jclass clazz, jbyteArray bytes, jboolean isCategory, jstring lang, jlong timestamp,
jboolean isMapAndTable, jboolean hasPosition, jdouble lat, jdouble lon)
{
search::ViewportSearchParams vparams{
jni::ToNativeString(env, bytes),
jni::ToNativeString(env, lang),
{}, // Default timeout
static_cast<bool>(isCategory),
{}, // Empty m_onStarted callback
{}, // Empty m_onCompleted callback
};
// TODO (@alexzatsepin): set up vparams.m_onCompleted here and use
// HotelsClassifier for hotel queries detection.
// Don't move vparams here, because it's used below.
g_framework->NativeFramework()->GetSearchAPI().SearchInViewport(vparams);
if (isMapAndTable)
{
g_javaListener = env->NewGlobalRef(thiz);
// public void onResultsUpdate(@NonNull SearchResult[] results, long timestamp)
g_updateResultsId = jni::GetMethodID(env, g_javaListener, "onResultsUpdate",
"([Lapp/organicmaps/sdk/search/SearchResult;J)V");
// public void onResultsEnd(long timestamp)
g_endResultsId = jni::GetMethodID(env, g_javaListener, "onResultsEnd", "(J)V");
g_resultClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/search/SearchResult");
g_resultConstructor = jni::GetConstructorID(
env, g_resultClass,
"(Ljava/lang/String;Lapp/organicmaps/sdk/search/SearchResult$Description;DD[I[I"
"Lapp/organicmaps/sdk/search/Popularity;)V");
g_suggestConstructor = jni::GetConstructorID(env, g_resultClass, "(Ljava/lang/String;Ljava/lang/String;DD[I[I)V");
g_descriptionClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/search/SearchResult$Description");
/*
Description(FeatureId featureId, String featureType, String region, Distance distance,
String description, int openNow, int minutesUntilOpen, int minutesUntilClosed,
boolean hasPopularityHigherPriority)
*/
g_descriptionConstructor = jni::GetConstructorID(env, g_descriptionClass,
"(Lapp/organicmaps/sdk/bookmarks/data/FeatureId;"
"Ljava/lang/String;Ljava/lang/String;Lapp/organicmaps/sdk/util/Distance;"
"Ljava/lang/String;IIIZ)V");
search::EverywhereSearchParams eparams{std::move(vparams.m_query),
std::move(vparams.m_inputLocale),
{}, // default timeout
static_cast<bool>(isCategory),
bind(&OnResults, _1, _2, timestamp, isMapAndTable, hasPosition, lat, lon)};
g_popularityClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/search/Popularity");
g_popularityConstructor = jni::GetConstructorID(env, g_popularityClass, "(I)V");
g_mapResultsMethod = jni::GetMethodID(env, g_javaListener, "onMapSearchResults",
"([Lapp/organicmaps/sdk/search/MapSearchListener$Result;JZ)V");
g_mapResultClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/search/MapSearchListener$Result");
g_mapResultCtor = jni::GetConstructorID(env, g_mapResultClass, "(Ljava/lang/String;Ljava/lang/String;)V");
g_updateBookmarksResultsId =
jni::GetMethodID(env, g_javaListener, "onBookmarkSearchResultsUpdate", "([JJ)V");
g_endBookmarksResultsId =
jni::GetMethodID(env, g_javaListener, "onBookmarkSearchResultsEnd", "([JJ)V");
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeRunSearch(
JNIEnv * env, jclass clazz, jbyteArray bytes, jboolean isCategory,
jstring lang, jlong timestamp, jboolean hasPosition, jdouble lat, jdouble lon)
{
search::EverywhereSearchParams params{
jni::ToNativeString(env, bytes),
jni::ToNativeString(env, lang),
{}, // default timeout
static_cast<bool>(isCategory),
bind(&OnResults, _1, _2, timestamp, false, hasPosition, lat, lon)
};
bool const searchStarted = g_framework->NativeFramework()->GetSearchAPI().SearchEverywhere(std::move(params));
if (searchStarted)
g_queryTimestamp = timestamp;
return searchStarted;
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeRunInteractiveSearch(
JNIEnv * env, jclass clazz, jbyteArray bytes, jboolean isCategory,
jstring lang, jlong timestamp, jboolean isMapAndTable, jboolean hasPosition, jdouble lat, jdouble lon)
{
search::ViewportSearchParams vparams{
jni::ToNativeString(env, bytes),
jni::ToNativeString(env, lang),
{}, // Default timeout
static_cast<bool>(isCategory),
{}, // Empty m_onStarted callback
{}, // Empty m_onCompleted callback
};
// TODO (@alexzatsepin): set up vparams.m_onCompleted here and use
// HotelsClassifier for hotel queries detection.
// Don't move vparams here, because it's used below.
g_framework->NativeFramework()->GetSearchAPI().SearchInViewport(vparams);
if (isMapAndTable)
{
search::EverywhereSearchParams eparams{
std::move(vparams.m_query),
std::move(vparams.m_inputLocale),
{}, // default timeout
static_cast<bool>(isCategory),
bind(&OnResults, _1, _2, timestamp, isMapAndTable, hasPosition, lat, lon)
};
if (g_framework->NativeFramework()->GetSearchAPI().SearchEverywhere(std::move(eparams)))
g_queryTimestamp = timestamp;
}
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeRunSearchMaps(
JNIEnv * env, jclass clazz, jbyteArray bytes, jstring lang, jlong timestamp)
{
storage::DownloaderSearchParams params{
jni::ToNativeString(env, bytes),
jni::ToNativeString(env, lang),
bind(&OnMapSearchResults, _1, timestamp)
};
if (g_framework->NativeFramework()->GetSearchAPI().SearchInDownloader(std::move(params)))
if (g_framework->NativeFramework()->GetSearchAPI().SearchEverywhere(std::move(eparams)))
g_queryTimestamp = timestamp;
}
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeRunSearchInBookmarks(
JNIEnv * env, jclass clazz, jbyteArray query, jlong catId, jlong timestamp)
{
search::BookmarksSearchParams params{
jni::ToNativeString(env, query),
static_cast<kml::MarkGroupId>(catId),
bind(&OnBookmarksSearchResults, _1, _2, timestamp)
};
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeRunSearchMaps(JNIEnv * env, jclass clazz,
jbyteArray bytes, jstring lang,
jlong timestamp)
{
storage::DownloaderSearchParams params{jni::ToNativeString(env, bytes), jni::ToNativeString(env, lang),
bind(&OnMapSearchResults, _1, timestamp)};
bool const searchStarted = g_framework->NativeFramework()->GetSearchAPI().SearchInBookmarks(std::move(params));
if (searchStarted)
g_queryTimestamp = timestamp;
return searchStarted;
}
if (g_framework->NativeFramework()->GetSearchAPI().SearchInDownloader(std::move(params)))
g_queryTimestamp = timestamp;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_search_SearchEngine_nativeShowResult(JNIEnv * env, jclass clazz, jint index)
{
g_framework->NativeFramework()->ShowSearchResult(g_results[index]);
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeRunSearchInBookmarks(
JNIEnv * env, jclass clazz, jbyteArray query, jlong catId, jlong timestamp)
{
search::BookmarksSearchParams params{jni::ToNativeString(env, query), static_cast<kml::MarkGroupId>(catId),
bind(&OnBookmarksSearchResults, _1, _2, timestamp)};
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_search_SearchEngine_nativeCancelInteractiveSearch(JNIEnv * env, jclass clazz)
{
g_framework->NativeFramework()->GetSearchAPI().CancelSearch(search::Mode::Viewport);
}
bool const searchStarted = g_framework->NativeFramework()->GetSearchAPI().SearchInBookmarks(std::move(params));
if (searchStarted)
g_queryTimestamp = timestamp;
return searchStarted;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_search_SearchEngine_nativeCancelEverywhereSearch(JNIEnv * env, jclass clazz)
{
g_framework->NativeFramework()->GetSearchAPI().CancelSearch(search::Mode::Everywhere);
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeShowResult(JNIEnv * env, jclass clazz,
jint index)
{
g_framework->NativeFramework()->ShowSearchResult(g_results[index]);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_search_SearchEngine_nativeCancelAllSearches(JNIEnv * env, jclass clazz)
{
g_framework->NativeFramework()->GetSearchAPI().CancelAllSearches();
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeCancelInteractiveSearch(JNIEnv * env,
jclass clazz)
{
g_framework->NativeFramework()->GetSearchAPI().CancelSearch(search::Mode::Viewport);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_search_SearchEngine_nativeUpdateViewportWithLastResults(JNIEnv * env, jclass clazz)
{
g_framework->NativeFramework()->UpdateViewport(g_results);
}
} // extern "C"
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeCancelEverywhereSearch(JNIEnv * env,
jclass clazz)
{
g_framework->NativeFramework()->GetSearchAPI().CancelSearch(search::Mode::Everywhere);
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeCancelAllSearches(JNIEnv * env, jclass clazz)
{
g_framework->NativeFramework()->GetSearchAPI().CancelAllSearches();
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_search_SearchEngine_nativeUpdateViewportWithLastResults(JNIEnv * env,
jclass clazz)
{
g_framework->NativeFramework()->UpdateViewport(g_results);
}
} // extern "C"

View File

@@ -6,14 +6,13 @@
extern "C"
{
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_settings_MapLanguageCode_setMapLanguageCode(JNIEnv * env, jobject, jstring languageCode)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_settings_MapLanguageCode_setMapLanguageCode(JNIEnv * env, jobject,
jstring languageCode)
{
g_framework->SetMapLanguageCode(jni::ToNativeString(env, languageCode));
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_settings_MapLanguageCode_getMapLanguageCode(JNIEnv * env, jobject)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_settings_MapLanguageCode_getMapLanguageCode(JNIEnv * env, jobject)
{
return jni::ToJavaString(env, g_framework->GetMapLanguageCode());
}

View File

@@ -5,19 +5,17 @@
extern "C"
{
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_settings_UnitLocale_setCurrentUnits(JNIEnv * env, jobject thiz, jint units)
{
measurement_utils::Units const u = static_cast<measurement_utils::Units>(units);
settings::Set(settings::kMeasurementUnits, u);
g_framework->SetupMeasurementSystem();
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_settings_UnitLocale_getCurrentUnits(JNIEnv * env, jobject thiz)
{
measurement_utils::Units u;
return static_cast<jint>(
settings::Get(settings::kMeasurementUnits, u) ? u : measurement_utils::Units::Metric);
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_settings_UnitLocale_setCurrentUnits(JNIEnv * env, jobject thiz,
jint units)
{
measurement_utils::Units const u = static_cast<measurement_utils::Units>(units);
settings::Set(settings::kMeasurementUnits, u);
g_framework->SetupMeasurementSystem();
}
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_settings_UnitLocale_getCurrentUnits(JNIEnv * env, jobject thiz)
{
measurement_utils::Units u;
return static_cast<jint>(settings::Get(settings::kMeasurementUnits, u) ? u : measurement_utils::Units::Metric);
}
}

View File

@@ -1,30 +1,49 @@
#include "app/organicmaps/sdk/Framework.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "app/organicmaps/sdk/core/jni_java_methods.hpp"
#include "platform/languages.hpp"
extern "C"
{
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_sound_TtsPlayer_nativeEnableTurnNotifications(JNIEnv *, jclass, jboolean enable)
{
return frm()->GetRoutingManager().EnableTurnNotifications(static_cast<bool>(enable));
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_sound_TtsPlayer_nativeEnableTurnNotifications(JNIEnv *, jclass,
jboolean enable)
{
return frm()->GetRoutingManager().EnableTurnNotifications(static_cast<bool>(enable));
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_sound_TtsPlayer_nativeAreTurnNotificationsEnabled(JNIEnv *, jclass)
{
return static_cast<jboolean>(frm()->GetRoutingManager().AreTurnNotificationsEnabled());
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_sound_TtsPlayer_nativeAreTurnNotificationsEnabled(JNIEnv *, jclass)
{
return static_cast<jboolean>(frm()->GetRoutingManager().AreTurnNotificationsEnabled());
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_sound_TtsPlayer_nativeSetTurnNotificationsLocale(JNIEnv * env, jclass, jstring jLocale)
{
frm()->GetRoutingManager().SetTurnNotificationsLocale(jni::ToNativeString(env, jLocale));
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_sound_TtsPlayer_nativeSetTurnNotificationsLocale(JNIEnv * env, jclass,
jstring jLocale)
{
frm()->GetRoutingManager().SetTurnNotificationsLocale(jni::ToNativeString(env, jLocale));
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_sound_TtsPlayer_nativeGetTurnNotificationsLocale(JNIEnv * env, jclass)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_sound_TtsPlayer_nativeGetTurnNotificationsLocale(JNIEnv * env,
jclass)
{
return jni::ToJavaString(env, frm()->GetRoutingManager().GetTurnNotificationsLocale());
}
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_sound_TtsPlayer_nativeGetSupportedLanguages(JNIEnv * env, jclass)
{
auto const & supportedLanguages = routing::turns::sound::kLanguageList;
auto const & listBuilder = jni::ListBuilder::Instance(env);
jobject const list = listBuilder.CreateArray(env, supportedLanguages.size());
for (auto const & [lang, name] : supportedLanguages)
{
return jni::ToJavaString(env, frm()->GetRoutingManager().GetTurnNotificationsLocale());
jni::TScopedLocalRef const jLangString(env, jni::ToJavaString(env, lang));
jni::TScopedLocalRef const jNameString(env, jni::ToJavaString(env, name));
jni::TScopedLocalRef const pair(env,
jni::PairBuilder::Instance(env).Create(env, jLangString.get(), jNameString.get()));
env->CallBooleanMethod(list, listBuilder.m_add, pair.get());
}
} // extern "C"
return list;
}
} // extern "C"

View File

@@ -9,22 +9,21 @@ static void TransitSchemeStateChanged(TransitReadManager::TransitSchemeState sta
std::shared_ptr<jobject> const & listener)
{
JNIEnv * env = jni::GetEnv();
env->CallVoidMethod(*listener,
jni::GetMethodID(env, *listener, "onTransitStateChanged", "(I)V"),
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener, "onTransitStateChanged", "(I)V"),
static_cast<jint>(state));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_maplayer_subway_SubwayManager_nativeAddListener(JNIEnv *env, jclass clazz, jobject listener)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_maplayer_subway_SubwayManager_nativeAddListener(JNIEnv * env,
jclass clazz,
jobject listener)
{
CHECK(g_framework, ("Framework isn't created yet!"));
g_framework->SetTransitSchemeListener(std::bind(&TransitSchemeStateChanged,
std::placeholders::_1,
jni::make_global_ref(listener)));
g_framework->SetTransitSchemeListener(
std::bind(&TransitSchemeStateChanged, std::placeholders::_1, jni::make_global_ref(listener)));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_maplayer_subway_SubwayManager_nativeRemoveListener(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_maplayer_subway_SubwayManager_nativeRemoveListener(JNIEnv * env,
jclass clazz)
{
CHECK(g_framework, ("Framework isn't created yet!"));
g_framework->SetTransitSchemeListener(TransitReadManager::TransitStateChangedFn());

View File

@@ -1,196 +1,192 @@
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "app/organicmaps/sdk/Framework.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "platform/settings.hpp"
extern "C"
{
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_util_Config_nativeHasConfigValue(JNIEnv * env, jclass thiz, jstring name)
{
std::string value;
return settings::Get(jni::ToNativeString(env, name), value);
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_util_Config_nativeHasConfigValue(JNIEnv * env, jclass thiz,
jstring name)
{
std::string value;
return settings::Get(jni::ToNativeString(env, name), value);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeDeleteConfigValue(JNIEnv * env, jclass thiz, jstring name)
{
settings::Delete(jni::ToNativeString(env, name));
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_util_Config_nativeDeleteConfigValue(JNIEnv * env, jclass thiz,
jstring name)
{
settings::Delete(jni::ToNativeString(env, name));
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetBoolean(JNIEnv * env, jclass thiz, jstring name, jboolean defaultVal)
{
bool val;
if (settings::Get(jni::ToNativeString(env, name), val))
return static_cast<jboolean>(val);
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_util_Config_nativeGetBoolean(JNIEnv * env, jclass thiz,
jstring name, jboolean defaultVal)
{
bool val;
if (settings::Get(jni::ToNativeString(env, name), val))
return static_cast<jboolean>(val);
return defaultVal;
}
return defaultVal;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetBoolean(JNIEnv * env, jclass thiz, jstring name, jboolean val)
{
(void)settings::Set(jni::ToNativeString(env, name), static_cast<bool>(val));
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_util_Config_nativeSetBoolean(JNIEnv * env, jclass thiz, jstring name,
jboolean val)
{
(void)settings::Set(jni::ToNativeString(env, name), static_cast<bool>(val));
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetInt(JNIEnv * env, jclass thiz, jstring name, jint defaultValue)
{
int32_t value;
if (settings::Get(jni::ToNativeString(env, name), value))
return static_cast<jint>(value);
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_util_Config_nativeGetInt(JNIEnv * env, jclass thiz, jstring name,
jint defaultValue)
{
int32_t value;
if (settings::Get(jni::ToNativeString(env, name), value))
return static_cast<jint>(value);
return defaultValue;
}
return defaultValue;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetInt(JNIEnv * env, jclass thiz, jstring name, jint value)
{
(void)settings::Set(jni::ToNativeString(env, name), static_cast<int32_t>(value));
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_util_Config_nativeSetInt(JNIEnv * env, jclass thiz, jstring name,
jint value)
{
(void)settings::Set(jni::ToNativeString(env, name), static_cast<int32_t>(value));
}
JNIEXPORT jlong JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetLong(JNIEnv * env, jclass thiz, jstring name, jlong defaultValue)
{
int64_t value;
if (settings::Get(jni::ToNativeString(env, name), value))
return static_cast<jlong>(value);
JNIEXPORT jlong JNICALL Java_app_organicmaps_sdk_util_Config_nativeGetLong(JNIEnv * env, jclass thiz, jstring name,
jlong defaultValue)
{
int64_t value;
if (settings::Get(jni::ToNativeString(env, name), value))
return static_cast<jlong>(value);
return defaultValue;
}
return defaultValue;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetLong(JNIEnv * env, jclass thiz, jstring name, jlong value)
{
(void)settings::Set(jni::ToNativeString(env, name), static_cast<int64_t>(value));
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_util_Config_nativeSetLong(JNIEnv * env, jclass thiz, jstring name,
jlong value)
{
(void)settings::Set(jni::ToNativeString(env, name), static_cast<int64_t>(value));
}
JNIEXPORT jdouble JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetDouble(JNIEnv * env, jclass thiz, jstring name, jdouble defaultValue)
{
double value;
if (settings::Get(jni::ToNativeString(env, name), value))
return static_cast<jdouble>(value);
JNIEXPORT jdouble JNICALL Java_app_organicmaps_sdk_util_Config_nativeGetDouble(JNIEnv * env, jclass thiz, jstring name,
jdouble defaultValue)
{
double value;
if (settings::Get(jni::ToNativeString(env, name), value))
return static_cast<jdouble>(value);
return defaultValue;
}
return defaultValue;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetDouble(JNIEnv * env, jclass thiz, jstring name, jdouble value)
{
(void)settings::Set(jni::ToNativeString(env, name), static_cast<double>(value));
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_util_Config_nativeSetDouble(JNIEnv * env, jclass thiz, jstring name,
jdouble value)
{
(void)settings::Set(jni::ToNativeString(env, name), static_cast<double>(value));
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetString(JNIEnv * env, jclass thiz, jstring name, jstring defaultValue)
{
std::string value;
if (settings::Get(jni::ToNativeString(env, name), value))
return jni::ToJavaString(env, value);
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_util_Config_nativeGetString(JNIEnv * env, jclass thiz, jstring name,
jstring defaultValue)
{
std::string value;
if (settings::Get(jni::ToNativeString(env, name), value))
return jni::ToJavaString(env, value);
return defaultValue;
}
return defaultValue;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetString(JNIEnv * env, jclass thiz, jstring name, jstring value)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_util_Config_nativeSetString(JNIEnv * env, jclass thiz, jstring name,
jstring value)
{
(void)settings::Set(jni::ToNativeString(env, name), jni::ToNativeString(env, value));
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_util_Config_nativeGetLargeFontsSize(JNIEnv * env, jclass thiz)
{
return frm()->LoadLargeFontsSize();
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_util_Config_nativeSetLargeFontsSize(JNIEnv * env, jclass thiz,
jboolean value)
{
frm()->SetLargeFontsSize(value);
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_util_Config_nativeGetTransliteration(JNIEnv * env, jclass thiz)
{
return frm()->LoadTransliteration();
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_util_Config_nativeSetTransliteration(JNIEnv * env, jclass thiz,
jboolean value)
{
frm()->SaveTransliteration(value);
frm()->AllowTransliteration(value);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetTrafficHttpEnabled(JNIEnv * env, jclass thiz)
{
return frm()->LoadTrafficHttpEnabled();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetTrafficHttpEnabled(JNIEnv * env, jclass thiz,
jboolean value)
{
frm()->SaveTrafficHttpEnabled(value);
frm()->SetTrafficHttpEnabled(value);
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetTrafficHttpUrl(JNIEnv * env, jclass thiz)
{
std::string value = frm()->LoadTrafficHttpUrl();
return jni::ToJavaString(env, value);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetTrafficHttpUrl(JNIEnv * env, jclass thiz,
jstring value)
{
frm()->SaveTrafficHttpUrl(jni::ToNativeString(env, value));
frm()->SetTrafficHttpUrl(jni::ToNativeString(env, value));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_applyTrafficLegacyEnabled(JNIEnv * env, jclass thiz,
jboolean value)
{
TrafficManager & tm = g_framework->GetTrafficManager();
tm.RemoveTraffSourceIf([](traffxml::TraffSource* source) {
if (traffxml::AndroidTraffSourceV0_7* traffSource = dynamic_cast<traffxml::AndroidTraffSourceV0_7*>(source))
{
(void)settings::Set(jni::ToNativeString(env, name), jni::ToNativeString(env, value));
traffSource->Close();
return true;
}
else
return false;
});
if (value)
traffxml::AndroidTraffSourceV0_7::Create(tm);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetLargeFontsSize(JNIEnv * env, jclass thiz)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_applyTrafficApps(JNIEnv * env, jclass thiz, jobjectArray value)
{
jsize valueLen = env->GetArrayLength(value);
TrafficManager & tm = g_framework->GetTrafficManager();
tm.RemoveTraffSourceIf([](traffxml::TraffSource* source) {
if (traffxml::AndroidTraffSourceV0_8* traffSource = dynamic_cast<traffxml::AndroidTraffSourceV0_8*>(source))
{
return frm()->LoadLargeFontsSize();
traffSource->Close();
return true;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetLargeFontsSize(JNIEnv * env, jclass thiz,
jboolean value)
{
frm()->SetLargeFontsSize(value);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetTransliteration(JNIEnv * env, jclass thiz)
{
return frm()->LoadTransliteration();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetTransliteration(JNIEnv * env, jclass thiz,
jboolean value)
{
frm()->SaveTransliteration(value);
frm()->AllowTransliteration(value);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetTrafficHttpEnabled(JNIEnv * env, jclass thiz)
{
return frm()->LoadTrafficHttpEnabled();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetTrafficHttpEnabled(JNIEnv * env, jclass thiz,
jboolean value)
{
frm()->SaveTrafficHttpEnabled(value);
frm()->SetTrafficHttpEnabled(value);
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_util_Config_nativeGetTrafficHttpUrl(JNIEnv * env, jclass thiz)
{
std::string value = frm()->LoadTrafficHttpUrl();
return jni::ToJavaString(env, value);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_nativeSetTrafficHttpUrl(JNIEnv * env, jclass thiz,
jstring value)
{
frm()->SaveTrafficHttpUrl(jni::ToNativeString(env, value));
frm()->SetTrafficHttpUrl(jni::ToNativeString(env, value));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_applyTrafficLegacyEnabled(JNIEnv * env, jclass thiz,
jboolean value)
{
TrafficManager & tm = g_framework->GetTrafficManager();
tm.RemoveTraffSourceIf([](traffxml::TraffSource* source) {
if (traffxml::AndroidTraffSourceV0_7* traffSource = dynamic_cast<traffxml::AndroidTraffSourceV0_7*>(source))
{
traffSource->Close();
return true;
}
else
return false;
});
if (value)
traffxml::AndroidTraffSourceV0_7::Create(tm);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_Config_applyTrafficApps(JNIEnv * env, jclass thiz, jobjectArray value)
{
jsize valueLen = env->GetArrayLength(value);
TrafficManager & tm = g_framework->GetTrafficManager();
tm.RemoveTraffSourceIf([](traffxml::TraffSource* source) {
if (traffxml::AndroidTraffSourceV0_8* traffSource = dynamic_cast<traffxml::AndroidTraffSourceV0_8*>(source))
{
traffSource->Close();
return true;
}
else
return false;
});
for (jsize i = 0; i < valueLen; i++)
{
jstring jAppId = (jstring)env->GetObjectArrayElement(value, i);
std::string appId = jni::ToNativeString(env, jAppId);
traffxml::AndroidTraffSourceV0_8::Create(tm, appId);
env->DeleteLocalRef(jAppId);
}
}
} // extern "C"
else
return false;
});
for (jsize i = 0; i < valueLen; i++)
{
jstring jAppId = (jstring)env->GetObjectArrayElement(value, i);
std::string appId = jni::ToNativeString(env, jAppId);
traffxml::AndroidTraffSourceV0_8::Create(tm, appId);
env->DeleteLocalRef(jAppId);
}
}
} // extern "C"

View File

@@ -10,9 +10,9 @@ inline jobject ToJavaDistance(JNIEnv * env, platform::Distance const & distance)
static jmethodID const distanceConstructor = jni::GetConstructorID(env, distanceClass, "(DLjava/lang/String;B)V");
jobject distanceObject = env->NewObject(
distanceClass, distanceConstructor,
distance.GetDistance(), jni::ToJavaString(env, distance.GetDistanceString()), static_cast<uint8_t>(distance.GetUnits()));
jobject distanceObject =
env->NewObject(distanceClass, distanceConstructor, distance.GetDistance(),
jni::ToJavaString(env, distance.GetDistanceString()), static_cast<uint8_t>(distance.GetUnits()));
return distanceObject;
}

View File

@@ -4,9 +4,8 @@
extern "C"
{
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_util_GeoUtils_nativeToLatLon(
JNIEnv * env, jobject thiz, jdouble mercX, jdouble mercY)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_util_GeoUtils_nativeToLatLon(JNIEnv * env, jobject thiz,
jdouble mercX, jdouble mercY)
{
auto const mercPoint = m2::PointD(static_cast<double>(mercX), static_cast<double>(mercY));
auto const latLon = mercator::ToLatLon(mercPoint);

View File

@@ -23,9 +23,9 @@ SOFTWARE.
*******************************************************************************/
#include <jni.h>
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "app/organicmaps/sdk/core/ScopedEnv.hpp"
#include "app/organicmaps/sdk/core/ScopedLocalRef.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "platform/http_client.hpp"
@@ -33,8 +33,8 @@ SOFTWARE.
#include "base/exception.hpp"
#include "base/logging.hpp"
#include <string>
#include <iterator>
#include <string>
#include <unordered_map>
DECLARE_EXCEPTION(JniException, RootException);
@@ -51,8 +51,7 @@ void RethrowOnJniException(ScopedEnv & env)
MYTHROW(JniException, ());
}
jfieldID GetHttpParamsFieldId(ScopedEnv & env, const char * name,
const char * signature = "Ljava/lang/String;")
jfieldID GetHttpParamsFieldId(ScopedEnv & env, char const * name, char const * signature = "Ljava/lang/String;")
{
return env->GetFieldID(g_httpParamsClazz, name, signature);
}
@@ -85,8 +84,8 @@ void SetInt(ScopedEnv & env, jobject params, jfieldID const fieldId, int const v
// Get string value from HttpClient.Params object, throws JniException.
void GetString(ScopedEnv & env, jobject const params, jfieldID const fieldId, std::string & result)
{
jni::ScopedLocalRef<jstring> const wrappedValue(
env.get(), static_cast<jstring>(env->GetObjectField(params, fieldId)));
jni::ScopedLocalRef<jstring> const wrappedValue(env.get(),
static_cast<jstring>(env->GetObjectField(params, fieldId)));
RethrowOnJniException(env);
if (wrappedValue)
result = jni::ToNativeString(env.get(), wrappedValue.get());
@@ -103,8 +102,8 @@ void SetHeaders(ScopedEnv & env, jobject const params, platform::HttpClient::Hea
if (headers.empty())
return;
static jmethodID const setHeaders = env->GetMethodID(
g_httpParamsClazz, "setHeaders", "([Lapp/organicmaps/sdk/util/KeyValue;)V");
static jmethodID const setHeaders =
env->GetMethodID(g_httpParamsClazz, "setHeaders", "([Lapp/organicmaps/sdk/util/KeyValue;)V");
RethrowOnJniException(env);
@@ -115,8 +114,7 @@ void SetHeaders(ScopedEnv & env, jobject const params, platform::HttpClient::Hea
void LoadHeaders(ScopedEnv & env, jobject const params, platform::HttpClient::Headers & headers)
{
static jmethodID const getHeaders =
env->GetMethodID(g_httpParamsClazz, "getHeaders", "()[Ljava/lang/Object;");
static jmethodID const getHeaders = env->GetMethodID(g_httpParamsClazz, "getHeaders", "()[Ljava/lang/Object;");
jni::ScopedLocalRef<jobjectArray> const headersArray(
env.get(), static_cast<jobjectArray>(env->CallObjectMethod(params, getHeaders)));
@@ -134,16 +132,15 @@ class Ids
public:
explicit Ids(ScopedEnv & env)
{
m_fieldIds =
{{"httpMethod", GetHttpParamsFieldId(env, "httpMethod")},
{"inputFilePath", GetHttpParamsFieldId(env, "inputFilePath")},
{"outputFilePath", GetHttpParamsFieldId(env, "outputFilePath")},
{"cookies", GetHttpParamsFieldId(env, "cookies")},
{"receivedUrl", GetHttpParamsFieldId(env, "receivedUrl")},
{"followRedirects", GetHttpParamsFieldId(env, "followRedirects", "Z")},
{"loadHeaders", GetHttpParamsFieldId(env, "loadHeaders", "Z")},
{"httpResponseCode", GetHttpParamsFieldId(env, "httpResponseCode", "I")},
{"timeoutMillisec", GetHttpParamsFieldId(env, "timeoutMillisec", "I")}};
m_fieldIds = {{"httpMethod", GetHttpParamsFieldId(env, "httpMethod")},
{"inputFilePath", GetHttpParamsFieldId(env, "inputFilePath")},
{"outputFilePath", GetHttpParamsFieldId(env, "outputFilePath")},
{"cookies", GetHttpParamsFieldId(env, "cookies")},
{"receivedUrl", GetHttpParamsFieldId(env, "receivedUrl")},
{"followRedirects", GetHttpParamsFieldId(env, "followRedirects", "Z")},
{"loadHeaders", GetHttpParamsFieldId(env, "loadHeaders", "Z")},
{"httpResponseCode", GetHttpParamsFieldId(env, "httpResponseCode", "I")},
{"timeoutMillisec", GetHttpParamsFieldId(env, "timeoutMillisec", "I")}};
}
jfieldID GetId(std::string const & fieldName) const
@@ -173,8 +170,7 @@ bool HttpClient::RunHttpRequest()
static Ids ids(env);
// Create and fill request params.
jni::ScopedLocalRef<jstring> const jniUrl(env.get(),
jni::ToJavaString(env.get(), m_urlRequested));
jni::ScopedLocalRef<jstring> const jniUrl(env.get(), jni::ToJavaString(env.get(), m_urlRequested));
if (jni::HandleJavaException(env.get()))
return false;
@@ -190,14 +186,14 @@ bool HttpClient::RunHttpRequest()
static jfieldID const dataField = env->GetFieldID(g_httpParamsClazz, "data", "[B");
if (!m_bodyData.empty())
{
jni::ScopedLocalRef<jbyteArray> const jniPostData(
env.get(), env->NewByteArray(static_cast<jsize>(m_bodyData.size())));
jni::ScopedLocalRef<jbyteArray> const jniPostData(env.get(),
env->NewByteArray(static_cast<jsize>(m_bodyData.size())));
if (jni::HandleJavaException(env.get()))
return false;
env->SetByteArrayRegion(jniPostData.get(), 0, static_cast<jsize>(m_bodyData.size()),
reinterpret_cast<const jbyte *>(m_bodyData.data()));
reinterpret_cast<jbyte const *>(m_bodyData.data()));
if (jni::HandleJavaException(env.get()))
return false;
@@ -216,8 +212,7 @@ bool HttpClient::RunHttpRequest()
SetString(env, httpParamsObject.get(), ids.GetId("cookies"), m_cookies);
SetBoolean(env, httpParamsObject.get(), ids.GetId("followRedirects"), m_followRedirects);
SetBoolean(env, httpParamsObject.get(), ids.GetId("loadHeaders"), m_loadHeaders);
SetInt(env, httpParamsObject.get(), ids.GetId("timeoutMillisec"),
static_cast<int>(m_timeoutSec * 1000));
SetInt(env, httpParamsObject.get(), ids.GetId("timeoutMillisec"), static_cast<int>(m_timeoutSec * 1000));
SetHeaders(env, httpParamsObject.get(), m_headers);
}
@@ -226,12 +221,12 @@ bool HttpClient::RunHttpRequest()
return false;
}
static jmethodID const httpClientClassRun =
env->GetStaticMethodID(g_httpClientClazz, "run",
"(Lapp/organicmaps/sdk/util/HttpClient$Params;)Lapp/organicmaps/sdk/util/HttpClient$Params;");
static jmethodID const httpClientClassRun = env->GetStaticMethodID(
g_httpClientClazz, "run",
"(Lapp/organicmaps/sdk/util/HttpClient$Params;)Lapp/organicmaps/sdk/util/HttpClient$Params;");
jni::ScopedLocalRef<jobject> const response(env.get(), env->CallStaticObjectMethod(g_httpClientClazz,
httpClientClassRun, httpParamsObject.get()));
jni::ScopedLocalRef<jobject> const response(
env.get(), env->CallStaticObjectMethod(g_httpClientClazz, httpClientClassRun, httpParamsObject.get()));
if (jni::HandleJavaException(env.get()))
return false;
@@ -247,8 +242,8 @@ bool HttpClient::RunHttpRequest()
}
// dataField is already cached above.
jni::ScopedLocalRef<jbyteArray> const jniData(
env.get(), static_cast<jbyteArray>(env->GetObjectField(response, dataField)));
jni::ScopedLocalRef<jbyteArray> const jniData(env.get(),
static_cast<jbyteArray>(env->GetObjectField(response, dataField)));
if (jni::HandleJavaException(env.get()))
return false;
if (jniData)
@@ -256,7 +251,7 @@ bool HttpClient::RunHttpRequest()
jbyte * buffer = env->GetByteArrayElements(jniData.get(), nullptr);
if (buffer)
{
m_serverResponse.assign(reinterpret_cast<const char *>(buffer), env->GetArrayLength(jniData.get()));
m_serverResponse.assign(reinterpret_cast<char const *>(buffer), env->GetArrayLength(jniData.get()));
env->ReleaseByteArrayElements(jniData.get(), buffer, JNI_ABORT);
}
}

View File

@@ -3,8 +3,8 @@
extern "C"
{
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_util_Language_nativeNormalize(JNIEnv *env, jclass type, jstring lang)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_util_Language_nativeNormalize(JNIEnv * env, jclass type,
jstring lang)
{
std::string locale = languages::Normalize(jni::ToNativeString(env, lang));
return jni::ToJavaString(env, locale);

View File

@@ -1,10 +1,11 @@
#include <jni.h>
#include "app/organicmaps/sdk/core/logging.hpp"
extern "C" {
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_log_LogsManager_nativeToggleCoreDebugLogs(
JNIEnv * /*env*/, jclass /*clazz*/, jboolean enabled)
extern "C"
{
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_util_log_LogsManager_nativeToggleCoreDebugLogs(JNIEnv * /*env*/,
jclass /*clazz*/,
jboolean enabled)
{
jni::ToggleDebugLogs(enabled);
}

View File

@@ -4,15 +4,14 @@ namespace network_policy
{
bool GetNetworkPolicyStatus(JNIEnv * env, jobject obj)
{
static jmethodID const networkPolicyCanUseMethod =
jni::GetMethodID(env, obj, "canUseNetwork", "()Z");
static jmethodID const networkPolicyCanUseMethod = jni::GetMethodID(env, obj, "canUseNetwork", "()Z");
return env->CallBooleanMethod(obj, networkPolicyCanUseMethod);
}
bool GetCurrentNetworkUsageStatus(JNIEnv * env)
{
static jmethodID const method =
jni::GetStaticMethodID(env, g_networkPolicyClazz, "getCurrentNetworkUsageStatus", "()Z");
jni::GetStaticMethodID(env, g_networkPolicyClazz, "getCurrentNetworkUsageStatus", "()Z");
return env->CallStaticBooleanMethod(g_networkPolicyClazz, method);
}
} // namespace network_policy

View File

@@ -4,4 +4,4 @@ namespace network_policy
{
bool GetNetworkPolicyStatus(JNIEnv * env, jobject obj);
bool GetCurrentNetworkUsageStatus(JNIEnv * env);
}
} // namespace network_policy

View File

@@ -20,20 +20,21 @@ jobject MakeJavaPair(JNIEnv * env, std::string const & first, std::string const
extern "C"
{
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_util_StringUtils_nativeIsHtml(JNIEnv * env, jclass thiz, jstring text)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeIsHtml(JNIEnv * env, jclass thiz,
jstring text)
{
return strings::IsHTML(jni::ToNativeString(env, text));
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_util_StringUtils_nativeContainsNormalized(JNIEnv * env, jclass thiz, jstring str, jstring substr)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeContainsNormalized(JNIEnv * env, jclass thiz,
jstring str,
jstring substr)
{
return search::ContainsNormalized(jni::ToNativeString(env, str), jni::ToNativeString(env, substr));
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_sdk_util_StringUtils_nativeFilterContainsNormalized(JNIEnv * env, jclass thiz, jobjectArray src, jstring jSubstr)
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeFilterContainsNormalized(
JNIEnv * env, jclass thiz, jobjectArray src, jstring jSubstr)
{
std::string const substr = jni::ToNativeString(env, jSubstr);
int const length = env->GetArrayLength(src);
@@ -49,43 +50,42 @@ Java_app_organicmaps_sdk_util_StringUtils_nativeFilterContainsNormalized(JNIEnv
return jni::ToJavaStringArray(env, filtered);
}
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeFormatSpeed(
JNIEnv * env, jclass thiz, jdouble metersPerSecond)
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeFormatSpeed(JNIEnv * env, jclass thiz,
jdouble metersPerSecond)
{
return measurement_utils::FormatSpeed(metersPerSecond, measurement_utils::GetMeasurementUnits());
}
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeFormatSpeedAndUnits(
JNIEnv * env, jclass thiz, jdouble metersPerSecond)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeFormatSpeedAndUnits(JNIEnv * env, jclass thiz,
jdouble metersPerSecond)
{
auto const units = measurement_utils::GetMeasurementUnits();
return MakeJavaPair(env, measurement_utils::FormatSpeedNumeric(metersPerSecond, units),
platform::GetLocalizedSpeedUnits(units));
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_util_StringUtils_nativeFormatDistance(JNIEnv * env, jclass, jdouble distanceInMeters)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeFormatDistance(JNIEnv * env, jclass,
jdouble distanceInMeters)
{
return ToJavaDistance(env, platform::Distance::CreateFormatted(distanceInMeters));
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_util_StringUtils_nativeGetLocalizedDistanceUnits(JNIEnv * env, jclass)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeGetLocalizedDistanceUnits(JNIEnv * env,
jclass)
{
auto const localizedUnits = platform::GetLocalizedDistanceUnits();
return MakeJavaPair(env, localizedUnits.m_high, localizedUnits.m_low);
}
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_util_StringUtils_nativeGetLocalizedAltitudeUnits(JNIEnv * env, jclass)
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeGetLocalizedAltitudeUnits(JNIEnv * env,
jclass)
{
auto const localizedUnits = platform::GetLocalizedAltitudeUnits();
return MakeJavaPair(env, localizedUnits.m_high, localizedUnits.m_low);
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_util_StringUtils_nativeGetLocalizedSpeedUnits(JNIEnv * env, jclass)
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_util_StringUtils_nativeGetLocalizedSpeedUnits(JNIEnv * env, jclass)
{
return jni::ToJavaString(env, platform::GetLocalizedSpeedUnits());
}
} // extern "C"
} // extern "C"

View File

@@ -4,8 +4,8 @@
extern "C"
{
// static void nativeProcessTask(long taskPointer);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_util_concurrency_UiThread_nativeProcessTask(JNIEnv * env, jclass clazz, jlong taskPointer)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_util_concurrency_UiThread_nativeProcessTask(JNIEnv * env, jclass clazz,
jlong taskPointer)
{
android::GuiThread::ProcessTask(taskPointer);
}

View File

@@ -43,8 +43,7 @@ void AndroidVulkanContextFactory::SetVulkanSurface()
createInfo.window = m_nativeWindow;
VkResult statusCode;
statusCode = vkCreateAndroidSurfaceKHR(m_vulkanInstance, &createInfo, nullptr,
&m_surface);
statusCode = vkCreateAndroidSurfaceKHR(m_vulkanInstance, &createInfo, nullptr, &m_surface);
if (statusCode != VK_SUCCESS)
{
LOG_ERROR_VK_CALL(vkCreateAndroidSurfaceKHR, statusCode);

View File

@@ -0,0 +1,36 @@
package app.organicmaps.sdk;
import androidx.annotation.NonNull;
public enum ChoosePositionMode
{
None(0),
Editor(1),
Api(2);
ChoosePositionMode(int mode)
{
this.mode = mode;
}
/**
* @param isBusiness selection area will be bounded by building borders, if its true (eg. true for businesses in
* buildings).
* @param applyPosition if true, map will be animated to currently selected object.
*/
public static void set(@NonNull ChoosePositionMode mode, boolean isBusiness, boolean applyPosition)
{
nativeSet(mode.mode, isBusiness, applyPosition);
}
public static ChoosePositionMode get()
{
return ChoosePositionMode.values()[nativeGet()];
}
private final int mode;
private static native void nativeSet(int mode, boolean isBusiness, boolean applyPosition);
private static native int nativeGet();
}

View File

@@ -0,0 +1,30 @@
package app.organicmaps.sdk;
import androidx.annotation.Keep;
public class DownloadResourcesLegacyActivity
{
// Error codes, should match the same codes in JNI
public static final int ERR_DOWNLOAD_SUCCESS = 0;
public static final int ERR_DISK_ERROR = -1;
public static final int ERR_NOT_ENOUGH_FREE_SPACE = -2;
public static final int ERR_STORAGE_DISCONNECTED = -3;
public static final int ERR_DOWNLOAD_ERROR = -4;
public static final int ERR_NO_MORE_FILES = -5;
public static final int ERR_FILE_IN_PROGRESS = -6;
public interface Listener
{
// Called by JNI.
@Keep
void onProgress(int bytesDownloaded);
// Called by JNI.
@Keep
void onFinish(int errorCode);
}
public static native int nativeGetBytesToDownload();
public static native int nativeStartNextFileDownload(Listener listener);
public static native void nativeCancelCurrentFile();
}

View File

@@ -0,0 +1,347 @@
package app.organicmaps.sdk;
import android.graphics.Bitmap;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
import app.organicmaps.sdk.api.ParsedRoutingData;
import app.organicmaps.sdk.api.ParsedSearchRequest;
import app.organicmaps.sdk.api.RequestType;
import app.organicmaps.sdk.bookmarks.data.DistanceAndAzimut;
import app.organicmaps.sdk.bookmarks.data.FeatureId;
import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.JunctionInfo;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.RoutingListener;
import app.organicmaps.sdk.routing.RoutingLoadPointsListener;
import app.organicmaps.sdk.routing.RoutingProgressListener;
import app.organicmaps.sdk.routing.RoutingRecommendationListener;
import app.organicmaps.sdk.routing.TransitRouteInfo;
import app.organicmaps.sdk.settings.SpeedCameraMode;
import app.organicmaps.sdk.util.Constants;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* This class wraps android::Framework.cpp class
* via static methods
*/
public class Framework
{
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public static class Params3dMode
{
public boolean enabled;
public boolean buildings;
}
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public static class RouteAltitudeLimits
{
public int totalAscent;
public int totalDescent;
public String totalAscentString;
public String totalDescentString;
public boolean isMetricUnits;
}
// this class is just bridge between Java and C++ worlds, we must not create it
private Framework() {}
public static String getHttpGe0Url(double lat, double lon, double zoomLevel, String name)
{
return nativeGetGe0Url(lat, lon, zoomLevel, name)
.replaceFirst(Constants.Url.SHORT_SHARE_PREFIX, Constants.Url.HTTP_SHARE_PREFIX);
}
/**
* Generates Bitmap with route altitude image chart taking into account current map style.
* @param width is width of the image.
* @param height is height of the image.
* @return Bitmap if there's pedestrian or bicycle route and null otherwise.
*/
@Nullable
public static Bitmap generateRouteAltitudeChart(int width, int height, @NonNull RouteAltitudeLimits limits)
{
if (width <= 0 || height <= 0)
return null;
final int[] altitudeChartBits = Framework.nativeGenerateRouteAltitudeChartBits(width, height, limits);
if (altitudeChartBits == null)
return null;
return Bitmap.createBitmap(altitudeChartBits, width, height, Bitmap.Config.ARGB_8888);
}
public static void setSpeedCamerasMode(@NonNull SpeedCameraMode mode)
{
nativeSetSpeedCamManagerMode(mode.ordinal());
}
public static native void nativeShowTrackRect(long track);
public static native int nativeGetDrawScale();
public static native void nativePokeSearchInViewport();
@Size(2)
public static native double[] nativeGetScreenRectCenter();
public static native DistanceAndAzimut nativeGetDistanceAndAzimuth(double dstMerX, double dstMerY, double srcLat,
double srcLon, double north);
public static native DistanceAndAzimut nativeGetDistanceAndAzimuthFromLatLon(double dstLat, double dstLon,
double srcLat, double srcLon,
double north);
public static native String nativeFormatLatLon(double lat, double lon, int coordFormat);
public static native String nativeFormatAltitude(double alt);
public static native String nativeFormatSpeed(double speed);
public static native String nativeGetGe0Url(double lat, double lon, double zoomLevel, String name);
public static native String nativeGetGeoUri(double lat, double lon, double zoomLevel, String name);
public static native String nativeGetAddress(double lat, double lon);
public static native void nativePlacePageActivationListener(@NonNull PlacePageActivationListener listener);
public static native void nativeRemovePlacePageActivationListener(@NonNull PlacePageActivationListener listener);
// @UiThread
// public static native String nativeGetOutdatedCountriesString();
//
// @UiThread
// @NonNull
// public static native String[] nativeGetOutdatedCountries();
//
// @UiThread
// @DoAfterUpdate
// public static native int nativeToDoAfterUpdate();
//
// public static native boolean nativeIsDataVersionChanged();
//
// public static native void nativeUpdateSavedDataVersion();
private static native long nativeGetDataVersion();
public static Date getDataVersion()
{
long dataVersion = nativeGetDataVersion();
final SimpleDateFormat format = new SimpleDateFormat("yyMMdd", Locale.ENGLISH);
try
{
return format.parse(String.valueOf(dataVersion));
}
catch (ParseException e)
{
throw new AssertionError("Invalid data version code: " + dataVersion);
}
}
public static native void nativeClearApiPoints();
@NonNull
public static native @RequestType int nativeParseAndSetApiUrl(String url);
public static native ParsedRoutingData nativeGetParsedRoutingData();
public static native ParsedSearchRequest nativeGetParsedSearchRequest();
public static native @Nullable String nativeGetParsedAppName();
public static native @Nullable String nativeGetParsedOAuth2Code();
@Nullable
@Size(2)
public static native double[] nativeGetParsedCenterLatLon();
public static native @Nullable String nativeGetParsedBackUrl();
public static native void nativeDeactivatePopup();
public static native void nativeDeactivateMapSelectionCircle(boolean restoreViewport);
public static native String nativeGetDataFileExt();
public static native String[] nativeGetMovableFilesExts();
public static native String[] nativeGetBookmarksFilesExts();
public static native String nativeGetBookmarkDir();
public static native String nativeGetSettingsDir();
public static native String nativeGetWritableDir();
public static native void nativeChangeWritableDir(String newPath);
// Routing.
public static native boolean nativeIsRoutingActive();
public static native boolean nativeIsRouteBuilt();
public static native boolean nativeIsRouteBuilding();
public static native void nativeCloseRouting();
public static native void nativeBuildRoute();
public static native void nativeRemoveRoute();
public static native void nativeFollowRoute();
public static native void nativeDisableFollowing();
@Nullable
public static native RoutingInfo nativeGetRouteFollowingInfo();
@Nullable
public static native JunctionInfo[] nativeGetRouteJunctionPoints();
@Nullable
public static native final int[] nativeGenerateRouteAltitudeChartBits(int width, int height,
RouteAltitudeLimits routeAltitudeLimits);
// When an end user is going to a turn he gets sound turn instructions.
// If C++ part wants the client to pronounce an instruction nativeGenerateTurnNotifications returns
// an array of one of more strings. C++ part assumes that all these strings shall be pronounced by the client's TTS.
// For example if C++ part wants the client to pronounce "Make a right turn." this method returns
// an array with one string "Make a right turn.". The next call of the method returns nothing.
// nativeGenerateTurnNotifications shall be called by the client when a new position is available.
@Nullable
public static native String[] nativeGenerateNotifications(boolean announceStreets);
private static native void nativeSetSpeedCamManagerMode(int mode);
public static native void nativeSetRoutingListener(@NonNull RoutingListener listener);
public static native void nativeSetRouteProgressListener(@NonNull RoutingProgressListener listener);
public static native void nativeSetRoutingRecommendationListener(@NonNull RoutingRecommendationListener listener);
public static native void nativeSetRoutingLoadPointsListener(@NonNull RoutingLoadPointsListener listener);
public static native void nativeShowCountry(String countryId, boolean zoomToDownloadButton);
public static void addRoutePoint(RouteMarkData point)
{
addRoutePoint(point, true);
}
public static void addRoutePoint(RouteMarkData point, boolean reorderIntermediatePoints)
{
Framework.nativeAddRoutePoint(point.mTitle, point.mSubtitle, point.mPointType, point.mIntermediateIndex,
point.mIsMyPosition, point.mLat, point.mLon, reorderIntermediatePoints);
}
public static native void nativeAddRoutePoint(String title, String subtitle, @NonNull RouteMarkType markType,
int intermediateIndex, boolean isMyPosition, double lat, double lon,
boolean reorderIntermediatePoints);
public static native void nativeRemoveRoutePoints();
public static native void nativeRemoveRoutePoint(@NonNull RouteMarkType markType, int intermediateIndex);
public static native void nativeRemoveIntermediateRoutePoints();
public static native boolean nativeCouldAddIntermediatePoint();
@NonNull
public static native RouteMarkData[] nativeGetRoutePoints();
public static native void nativeMoveRoutePoint(int currentIndex, int targetIndex);
@NonNull
public static native TransitRouteInfo nativeGetTransitRouteInfo();
/**
* Registers all maps(.mwms). Adds them to the models, generates indexes and does all necessary stuff.
*/
public static native void nativeReloadWorldMaps();
/**
* Determines if currently is day or night at the given location. Used to switch day/night styles.
* @param utcTimeSeconds Unix time in seconds.
* @param lat latitude of the current location.
* @param lon longitude of the current location.
* @return {@code true} if it is day now or {@code false} otherwise.
*/
public static native boolean nativeIsDayTime(long utcTimeSeconds, double lat, double lon);
public static native void nativeGet3dMode(Params3dMode result);
public static native void nativeSet3dMode(boolean allow3d, boolean allow3dBuildings);
public static native boolean nativeGetAutoZoomEnabled();
public static native void nativeSetAutoZoomEnabled(boolean enabled);
public static native void nativeSetTransitSchemeEnabled(boolean enabled);
public static native void nativeSaveSettingSchemeEnabled(boolean enabled);
public static native boolean nativeIsTransitSchemeEnabled();
public static native void nativeSetIsolinesLayerEnabled(boolean enabled);
public static native boolean nativeIsIsolinesLayerEnabled();
public static native void nativeSetOutdoorsLayerEnabled(boolean enabled);
public static native boolean nativeIsOutdoorsLayerEnabled();
@NonNull
public static native MapObject nativeDeleteBookmarkFromMapObject();
@NonNull
public static native String nativeGetPoiContactUrl(int metadataType);
public static native void nativeZoomToPoint(double lat, double lon, int zoom, boolean animate);
public static native boolean nativeIsDownloadedMapAtScreenCenter();
public static native String nativeGetActiveObjectFormattedCuisine();
public static native void nativeSetVisibleRect(int left, int top, int right, int bottom);
// Navigation.
public static native boolean nativeIsRouteFinished();
public static native void nativeRunFirstLaunchAnimation();
public static native int nativeOpenRoutePointsTransaction();
public static native void nativeApplyRoutePointsTransaction(int transactionId);
public static native void nativeCancelRoutePointsTransaction(int transactionId);
public static native int nativeInvalidRoutePointsTransactionId();
public static native boolean nativeHasSavedRoutePoints();
public static native void nativeLoadRoutePoints();
public static native void nativeSaveRoutePoints();
public static native void nativeDeleteSavedRoutePoints();
public static native void nativeShowFeature(@NonNull FeatureId featureId);
public static native void nativeMakeCrash();
public static native void nativeSetPowerManagerFacility(int facilityType, boolean state);
public static native int nativeGetPowerManagerScheme();
public static native void nativeSetPowerManagerScheme(int schemeType);
public static native void nativeSetViewportCenter(double lat, double lon, int zoom);
public static native void nativeStopLocationFollow();
public static native void nativeSetSearchViewport(double lat, double lon, int zoom);
/**
* In case of the app was dumped by system to the hard drive, Java map object can be
* restored from parcelable, but c++ framework is created from scratch and internal
* place page object is not initialized. So, do not restore place page in this case.
*
* @return true if c++ framework has initialized internal place page object, otherwise - false.
*/
public static native boolean nativeHasPlacePageInfo();
public static native void nativeMemoryWarning();
public static native void nativeSaveRoute();
}

View File

@@ -0,0 +1,423 @@
package app.organicmaps.sdk;
import android.content.Context;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.Surface;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.sdk.display.DisplayType;
import app.organicmaps.sdk.location.LocationHelper;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.ROMUtils;
import app.organicmaps.sdk.util.Utils;
import app.organicmaps.sdk.util.concurrency.UiThread;
import app.organicmaps.sdk.util.log.Logger;
public final class Map
{
public interface CallbackUnsupported
{
void report();
}
public static final String ARG_LAUNCH_BY_DEEP_LINK = "launch_by_deep_link";
private static final String TAG = Map.class.getSimpleName();
// Should correspond to android::MultiTouchAction from Framework.cpp
public static final int NATIVE_ACTION_UP = 0x01;
public static final int NATIVE_ACTION_DOWN = 0x02;
public static final int NATIVE_ACTION_MOVE = 0x03;
public static final int NATIVE_ACTION_CANCEL = 0x04;
// Should correspond to gui::EWidget from skin.hpp
public static final int WIDGET_RULER = 0x01;
public static final int WIDGET_COMPASS = 0x02;
public static final int WIDGET_COPYRIGHT = 0x04;
public static final int WIDGET_SCALE_FPS_LABEL = 0x08;
// Should correspond to dp::Anchor from drape_global.hpp
public static final int ANCHOR_CENTER = 0x00;
public static final int ANCHOR_LEFT = 0x01;
public static final int ANCHOR_RIGHT = (ANCHOR_LEFT << 1);
public static final int ANCHOR_TOP = (ANCHOR_RIGHT << 1);
public static final int ANCHOR_BOTTOM = (ANCHOR_TOP << 1);
public static final int ANCHOR_LEFT_TOP = (ANCHOR_LEFT | ANCHOR_TOP);
public static final int ANCHOR_RIGHT_TOP = (ANCHOR_RIGHT | ANCHOR_TOP);
public static final int ANCHOR_LEFT_BOTTOM = (ANCHOR_LEFT | ANCHOR_BOTTOM);
public static final int ANCHOR_RIGHT_BOTTOM = (ANCHOR_RIGHT | ANCHOR_BOTTOM);
// Should correspond to df::TouchEvent::INVALID_MASKED_POINTER from user_event_stream.cpp
public static final int INVALID_POINTER_MASK = 0xFF;
public static final int INVALID_TOUCH_ID = -1;
@NonNull
private final DisplayType mDisplayType;
@Nullable
private LocationHelper mLocationHelper;
private int mCurrentCompassOffsetX;
private int mCurrentCompassOffsetY;
private int mBottomWidgetOffsetX;
private int mBottomWidgetOffsetY;
private int mHeight;
private int mWidth;
private boolean mRequireResize;
private boolean mSurfaceCreated;
private boolean mSurfaceAttached;
private boolean mLaunchByDeepLink;
@Nullable
private String mUiThemeOnPause;
@Nullable
private MapRenderingListener mMapRenderingListener;
@Nullable
private CallbackUnsupported mCallbackUnsupported;
private static int sCurrentDpi = 0;
public Map(@NonNull DisplayType mapType)
{
mDisplayType = mapType;
onCreate(false);
}
public void setLocationHelper(@NonNull LocationHelper locationHelper)
{
mLocationHelper = locationHelper;
}
/**
* Moves the map compass using the given offsets.
*
* @param context Context.
* @param offsetX Pixel offset from the top. -1 to keep the previous value.
* @param offsetY Pixel offset from the right. -1 to keep the previous value.
* @param forceRedraw True to force the compass to redraw
*/
public void updateCompassOffset(final Context context, int offsetX, int offsetY, boolean forceRedraw)
{
final int x = offsetX < 0 ? mCurrentCompassOffsetX : offsetX;
final int y = offsetY < 0 ? mCurrentCompassOffsetY : offsetY;
final int navPadding = Utils.dimen(context, R.dimen.nav_frame_padding);
final int marginX = Utils.dimen(context, R.dimen.margin_compass) + navPadding;
final int marginY = Utils.dimen(context, R.dimen.margin_compass_top) + navPadding;
nativeSetupWidget(WIDGET_COMPASS, mWidth - x - marginX, y + marginY, ANCHOR_CENTER);
if (forceRedraw && mSurfaceCreated)
nativeApplyWidgets();
mCurrentCompassOffsetX = x;
mCurrentCompassOffsetY = y;
}
public static void onCompassUpdated(double north, boolean forceRedraw)
{
nativeCompassUpdated(north, forceRedraw);
}
/**
* Moves the ruler and copyright using the given offsets.
*
* @param context Context.
* @param offsetX Pixel offset from the left. -1 to keep the previous value.
* @param offsetY Pixel offset from the bottom. -1 to keep the previous value.
*/
public void updateBottomWidgetsOffset(final Context context, int offsetX, int offsetY)
{
final int x = offsetX < 0 ? mBottomWidgetOffsetX : offsetX;
final int y = offsetY < 0 ? mBottomWidgetOffsetY : offsetY;
updateRulerOffset(context, x, y);
updateAttributionOffset(context, x, y);
mBottomWidgetOffsetX = x;
mBottomWidgetOffsetY = y;
}
/**
* Moves my position arrow to the given offset.
*
* @param offsetY Pixel offset from the bottom.
*/
public void updateMyPositionRoutingOffset(int offsetY)
{
nativeUpdateMyPositionRoutingOffset(offsetY);
}
public void onSurfaceCreated(final Context context, final Surface surface, Rect surfaceFrame, int surfaceDpi)
{
assert mLocationHelper != null : "LocationHelper must be initialized before calling onSurfaceCreated";
if (isThemeChangingProcess())
{
Logger.d(TAG, "Theme changing process, skip 'onSurfaceCreated' callback");
return;
}
Logger.d(TAG, "mSurfaceCreated = " + mSurfaceCreated);
if (nativeIsEngineCreated())
{
if (sCurrentDpi != surfaceDpi)
{
nativeUpdateEngineDpi(surfaceDpi);
sCurrentDpi = surfaceDpi;
setupWidgets(context, surfaceFrame.width(), surfaceFrame.height());
}
if (!nativeAttachSurface(surface))
{
if (mCallbackUnsupported != null)
mCallbackUnsupported.report();
return;
}
mSurfaceCreated = true;
mSurfaceAttached = true;
mRequireResize = true;
nativeResumeSurfaceRendering();
return;
}
mRequireResize = false;
setupWidgets(context, surfaceFrame.width(), surfaceFrame.height());
final boolean firstStart = mLocationHelper.isInFirstRun();
if (!nativeCreateEngine(surface, surfaceDpi, firstStart, mLaunchByDeepLink, Config.getVersionCode(),
ROMUtils.isCustomROM()))
{
if (mCallbackUnsupported != null)
mCallbackUnsupported.report();
return;
}
sCurrentDpi = surfaceDpi;
if (firstStart)
UiThread.runLater(mLocationHelper::onExitFromFirstRun);
mSurfaceCreated = true;
mSurfaceAttached = true;
nativeResumeSurfaceRendering();
if (mMapRenderingListener != null)
mMapRenderingListener.onRenderingCreated();
}
public void onSurfaceChanged(final Context context, final Surface surface, Rect surfaceFrame,
boolean isSurfaceCreating)
{
if (isThemeChangingProcess())
{
Logger.d(TAG, "Theme changing process, skip 'onSurfaceChanged' callback");
return;
}
Logger.d(TAG, "mSurfaceCreated = " + mSurfaceCreated);
if (!mSurfaceCreated || (!mRequireResize && isSurfaceCreating))
return;
nativeSurfaceChanged(surface, surfaceFrame.width(), surfaceFrame.height());
mRequireResize = false;
setupWidgets(context, surfaceFrame.width(), surfaceFrame.height());
nativeApplyWidgets();
if (mMapRenderingListener != null)
mMapRenderingListener.onRenderingRestored();
}
public void onSurfaceDestroyed(boolean activityIsChangingConfigurations, boolean isAdded)
{
Logger.d(TAG, "mSurfaceCreated = " + mSurfaceCreated + ", mSurfaceAttached = " + mSurfaceAttached
+ ", isAdded = " + isAdded);
if (!mSurfaceCreated || !mSurfaceAttached || !isAdded)
return;
nativeDetachSurface(!activityIsChangingConfigurations);
mSurfaceCreated = !nativeDestroySurfaceOnDetach();
mSurfaceAttached = false;
}
public void setMapRenderingListener(MapRenderingListener mapRenderingListener)
{
mMapRenderingListener = mapRenderingListener;
}
public void setCallbackUnsupported(CallbackUnsupported callback)
{
mCallbackUnsupported = callback;
}
public void onCreate(boolean launchByDeeplink)
{
mLaunchByDeepLink = launchByDeeplink;
mCurrentCompassOffsetX = 0;
mCurrentCompassOffsetY = 0;
mBottomWidgetOffsetX = 0;
mBottomWidgetOffsetY = 0;
}
public void onStart()
{
nativeSetRenderingInitializationFinishedListener(mMapRenderingListener);
}
public void onStop()
{
nativeSetRenderingInitializationFinishedListener(null);
}
public void onPause(final Context context)
{
mUiThemeOnPause = Config.UiTheme.getCurrent();
// Pause/Resume can be called without surface creation/destroy.
if (mSurfaceAttached)
nativePauseSurfaceRendering();
}
public void onResume()
{
// Pause/Resume can be called without surface creation/destroy.
if (mSurfaceAttached)
nativeResumeSurfaceRendering();
}
public boolean isContextCreated()
{
return mSurfaceCreated;
}
public void onScroll(double distanceX, double distanceY)
{
Map.nativeOnScroll(distanceX, distanceY);
}
public static void zoomIn()
{
nativeScalePlus();
}
public static void zoomOut()
{
nativeScaleMinus();
}
public static void onScale(double factor, double focusX, double focusY, boolean isAnim)
{
nativeOnScale(factor, focusX, focusY, isAnim);
}
public static void onTouch(int actionType, MotionEvent event, int pointerIndex)
{
if (event.getPointerCount() == 1)
{
nativeOnTouch(actionType, event.getPointerId(0), event.getX(), event.getY(), Map.INVALID_TOUCH_ID, 0, 0, 0);
}
else
{
nativeOnTouch(actionType, event.getPointerId(0), event.getX(0), event.getY(0), event.getPointerId(1),
event.getX(1), event.getY(1), pointerIndex);
}
}
public static void onClick(float x, float y)
{
nativeOnTouch(NATIVE_ACTION_DOWN, 0, x, y, Map.INVALID_TOUCH_ID, 0, 0, 0);
nativeOnTouch(NATIVE_ACTION_UP, 0, x, y, Map.INVALID_TOUCH_ID, 0, 0, 0);
}
public static boolean isEngineCreated()
{
return nativeIsEngineCreated();
}
public static void executeMapApiRequest()
{
nativeExecuteMapApiRequest();
}
private void setupWidgets(final Context context, int width, int height)
{
mHeight = height;
mWidth = width;
nativeCleanWidgets();
updateBottomWidgetsOffset(context, mBottomWidgetOffsetX, mBottomWidgetOffsetY);
if (mDisplayType == DisplayType.Device)
{
nativeSetupWidget(WIDGET_SCALE_FPS_LABEL, Utils.dimen(context, R.dimen.margin_base),
Utils.dimen(context, R.dimen.margin_base) * 2, ANCHOR_LEFT_TOP);
updateCompassOffset(context, mCurrentCompassOffsetX, mCurrentCompassOffsetY, false);
}
else
{
nativeSetupWidget(WIDGET_SCALE_FPS_LABEL, (float) mWidth / 2 + Utils.dimen(context, R.dimen.margin_base) * 2,
Utils.dimen(context, R.dimen.margin_base), ANCHOR_LEFT_TOP);
updateCompassOffset(context, mWidth, mCurrentCompassOffsetY, true);
}
}
private void updateRulerOffset(final Context context, int offsetX, int offsetY)
{
nativeSetupWidget(WIDGET_RULER, Utils.dimen(context, R.dimen.margin_ruler) + offsetX,
mHeight - Utils.dimen(context, R.dimen.margin_ruler) - offsetY, ANCHOR_LEFT_BOTTOM);
if (mSurfaceCreated)
nativeApplyWidgets();
}
private void updateAttributionOffset(final Context context, int offsetX, int offsetY)
{
nativeSetupWidget(WIDGET_COPYRIGHT, Utils.dimen(context, R.dimen.margin_ruler) + offsetX,
mHeight - Utils.dimen(context, R.dimen.margin_ruler) - offsetY, ANCHOR_LEFT_BOTTOM);
if (mSurfaceCreated)
nativeApplyWidgets();
}
private boolean isThemeChangingProcess()
{
return mUiThemeOnPause != null && !mUiThemeOnPause.equals(Config.UiTheme.getCurrent());
}
// Engine
private static native boolean nativeCreateEngine(Surface surface, int density, boolean firstLaunch,
boolean isLaunchByDeepLink, int appVersionCode, boolean isCustomROM);
private static native boolean nativeIsEngineCreated();
private static native void nativeUpdateEngineDpi(int dpi);
private static native void nativeSetRenderingInitializationFinishedListener(@Nullable MapRenderingListener listener);
private static native void nativeExecuteMapApiRequest();
// Surface
private static native boolean nativeAttachSurface(Surface surface);
private static native void nativeDetachSurface(boolean destroySurface);
private static native void nativeSurfaceChanged(Surface surface, int w, int h);
private static native boolean nativeDestroySurfaceOnDetach();
private static native void nativePauseSurfaceRendering();
private static native void nativeResumeSurfaceRendering();
// Widgets
private static native void nativeApplyWidgets();
private static native void nativeCleanWidgets();
private static native void nativeUpdateMyPositionRoutingOffset(int offsetY);
private static native void nativeSetupWidget(int widget, float x, float y, int anchor);
private static native void nativeCompassUpdated(double north, boolean forceRedraw);
// Events
private static native void nativeScalePlus();
private static native void nativeScaleMinus();
private static native void nativeOnScroll(double distanceX, double distanceY);
private static native void nativeOnScale(double factor, double focusX, double focusY, boolean isAnim);
private static native void nativeOnTouch(int actionType, int id1, float x1, float y1, int id2, float x2, float y2,
int maskedPointer);
}

View File

@@ -0,0 +1,16 @@
package app.organicmaps.sdk;
import androidx.annotation.Keep;
public interface MapRenderingListener
{
default void onRenderingCreated() {}
default void onRenderingRestored() {}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
default void onRenderingInitializationFinished()
{}
}

View File

@@ -0,0 +1,59 @@
package app.organicmaps.sdk;
import androidx.annotation.NonNull;
public enum MapStyle
{
Clear(0),
Dark(1),
VehicleClear(3),
VehicleDark(4),
OutdoorsClear(5),
OutdoorsDark(6);
MapStyle(int value)
{
this.value = value;
}
@NonNull
public static MapStyle get()
{
return valueOf(nativeGet());
}
public static void set(@NonNull MapStyle mapStyle)
{
nativeSet(mapStyle.value);
}
/**
* This method allows to set new map style without immediate applying. It can be used before
* engine recreation instead of nativeSetMapStyle to avoid huge flow of OpenGL invocations.
*
* @param mapStyle style index
*/
public static void mark(@NonNull MapStyle mapStyle)
{
nativeMark(mapStyle.value);
}
@NonNull
public static MapStyle valueOf(int value)
{
for (MapStyle mapStyle : MapStyle.values())
{
if (mapStyle.value == value)
return mapStyle;
}
throw new IllegalArgumentException("Unknown map style value: " + value);
}
private final int value;
private static native void nativeSet(int mapStyle);
private static native int nativeGet();
private static native void nativeMark(int mapStyle);
}

View File

@@ -0,0 +1,234 @@
package app.organicmaps.sdk;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
import app.organicmaps.sdk.bookmarks.data.Icon;
import app.organicmaps.sdk.downloader.Android7RootCertificateWorkaround;
import app.organicmaps.sdk.editor.OsmOAuth;
import app.organicmaps.sdk.location.LocationHelper;
import app.organicmaps.sdk.location.LocationProviderFactory;
import app.organicmaps.sdk.location.SensorHelper;
import app.organicmaps.sdk.maplayer.isolines.IsolinesManager;
import app.organicmaps.sdk.maplayer.subway.SubwayManager;
import app.organicmaps.sdk.maplayer.traffic.TrafficManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.search.SearchEngine;
import app.organicmaps.sdk.settings.StoragePathManager;
import app.organicmaps.sdk.sound.TtsPlayer;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.SharedPropertiesUtils;
import app.organicmaps.sdk.util.StorageUtils;
import app.organicmaps.sdk.util.log.Logger;
import app.organicmaps.sdk.util.log.LogsManager;
import java.io.IOException;
public final class OrganicMaps implements DefaultLifecycleObserver
{
private static final String TAG = OrganicMaps.class.getSimpleName();
@NonNull
private final String mFlavor;
@NonNull
private final Context mContext;
@NonNull
private final SharedPreferences mPreferences;
@NonNull
private final IsolinesManager mIsolinesManager;
@NonNull
private final SubwayManager mSubwayManager;
@NonNull
private final LocationHelper mLocationHelper;
@NonNull
private final SensorHelper mSensorHelper;
private volatile boolean mFrameworkInitialized;
private volatile boolean mPlatformInitialized;
@NonNull
public LocationHelper getLocationHelper()
{
return mLocationHelper;
}
@NonNull
public SensorHelper getSensorHelper()
{
return mSensorHelper;
}
@NonNull
public SubwayManager getSubwayManager()
{
return mSubwayManager;
}
@NonNull
public IsolinesManager getIsolinesManager()
{
return mIsolinesManager;
}
public OrganicMaps(@NonNull Context context, @NonNull String flavor, @NonNull String applicationId, int versionCode,
@NonNull String versionName, @NonNull String fileProviderAuthority,
@NonNull LocationProviderFactory locationProviderFactory)
{
mFlavor = flavor;
mContext = context.getApplicationContext();
mPreferences = mContext.getSharedPreferences(context.getString(R.string.pref_file_name), Context.MODE_PRIVATE);
// Set configuration directory as early as possible.
// Other methods may explicitly use Config, which requires settingsDir to be set.
final String settingsPath = StorageUtils.getSettingsPath(mContext);
if (!StorageUtils.createDirectory(settingsPath))
throw new AssertionError("Can't create settingsDir " + settingsPath);
Logger.d(TAG, "Settings path = " + settingsPath);
nativeSetSettingsDir(settingsPath);
Config.init(mContext, mPreferences, flavor, applicationId, versionCode, versionName, fileProviderAuthority);
OsmOAuth.init(mPreferences);
SharedPropertiesUtils.init(mPreferences);
LogsManager.INSTANCE.initFileLogging(mContext, mPreferences);
Android7RootCertificateWorkaround.initializeIfNeeded(mContext);
Icon.loadDefaultIcons(mContext.getResources(), mContext.getPackageName());
mSensorHelper = new SensorHelper(mContext);
mLocationHelper = new LocationHelper(mContext, mSensorHelper, locationProviderFactory);
mIsolinesManager = new IsolinesManager();
mSubwayManager = new SubwayManager(mContext);
}
/**
* Initialize native core of application: platform and framework.
*
* @throws IOException - if failed to create directories. Caller must handle
* the exception and do nothing with native code if initialization is failed.
*/
public boolean init(@NonNull Runnable onComplete) throws IOException
{
initNativePlatform();
return initNativeFramework(onComplete);
}
public boolean arePlatformAndCoreInitialized()
{
return mFrameworkInitialized && mPlatformInitialized;
}
@Override
public void onStart(@NonNull LifecycleOwner owner)
{
nativeOnTransit(true);
}
@Override
public void onStop(@NonNull LifecycleOwner owner)
{
nativeOnTransit(false);
}
@NonNull
public SharedPreferences getPreferences()
{
return mPreferences;
}
private void initNativePlatform() throws IOException
{
if (mPlatformInitialized)
return;
final String apkPath = StorageUtils.getApkPath(mContext);
Logger.d(TAG, "Apk path = " + apkPath);
// Note: StoragePathManager uses Config, which requires SettingsDir to be set.
final String writablePath = StoragePathManager.findMapsStorage(mContext);
Logger.d(TAG, "Writable path = " + writablePath);
final String privatePath = StorageUtils.getPrivatePath(mContext);
Logger.d(TAG, "Private path = " + privatePath);
final String tempPath = StorageUtils.getTempPath(mContext);
Logger.d(TAG, "Temp path = " + tempPath);
// If platform directories are not created it means that native part of app will not be able
// to work at all. So, we just ignore native part initialization in this case, e.g. when the
// external storage is damaged or not available (read-only).
createPlatformDirectories(writablePath, privatePath, tempPath);
nativeInitPlatform(mContext, apkPath, writablePath, privatePath, tempPath, mFlavor, BuildConfig.BUILD_TYPE,
/* isTablet */ false);
Config.setStoragePath(writablePath);
Config.setStatisticsEnabled(SharedPropertiesUtils.isStatisticsEnabled());
mPlatformInitialized = true;
Logger.i(TAG, "Platform initialized");
}
private boolean initNativeFramework(@NonNull Runnable onComplete)
{
if (mFrameworkInitialized)
return false;
nativeInitFramework(onComplete);
initNativeStrings();
SearchEngine.INSTANCE.initialize();
BookmarkManager.loadBookmarks();
TtsPlayer.INSTANCE.initialize(mContext);
RoutingController.get().initialize(mLocationHelper);
TrafficManager.INSTANCE.initialize();
mSubwayManager.initialize();
mIsolinesManager.initialize();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
Logger.i(TAG, "Framework initialized");
mFrameworkInitialized = true;
return true;
}
private void createPlatformDirectories(@NonNull String writablePath, @NonNull String privatePath,
@NonNull String tempPath) throws IOException
{
SharedPropertiesUtils.emulateBadExternalStorage(mContext);
StorageUtils.requireDirectory(writablePath);
StorageUtils.requireDirectory(privatePath);
StorageUtils.requireDirectory(tempPath);
}
private void initNativeStrings()
{
nativeAddLocalization("core_entrance", mContext.getString(R.string.core_entrance));
nativeAddLocalization("core_exit", mContext.getString(R.string.core_exit));
nativeAddLocalization("core_my_places", mContext.getString(R.string.core_my_places));
nativeAddLocalization("core_my_position", mContext.getString(R.string.core_my_position));
nativeAddLocalization("core_placepage_unknown_place", mContext.getString(R.string.core_placepage_unknown_place));
nativeAddLocalization("postal_code", mContext.getString(R.string.postal_code));
nativeAddLocalization("wifi", mContext.getString(R.string.category_wifi));
}
private static native void nativeSetSettingsDir(String settingsPath);
private static native void nativeInitPlatform(Context context, String apkPath, String writablePath,
String privatePath, String tmpPath, String flavorName, String buildType,
boolean isTablet);
private static native void nativeInitFramework(@NonNull Runnable onComplete);
private static native void nativeAddLocalization(String name, String value);
private static native void nativeOnTransit(boolean foreground);
static
{
System.loadLibrary("organicmaps");
}
}

View File

@@ -0,0 +1,23 @@
package app.organicmaps.sdk;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import app.organicmaps.sdk.widget.placepage.PlacePageData;
public interface PlacePageActivationListener
{
// Called from JNI.
@Keep
@SuppressWarnings("unused")
void onPlacePageActivated(@NonNull PlacePageData data);
// Called from JNI
@Keep
@SuppressWarnings("unused")
void onPlacePageDeactivated();
// Called from JNI
@Keep
@SuppressWarnings("unused")
void onSwitchFullScreenMode();
}

View File

@@ -0,0 +1,52 @@
package app.organicmaps.sdk;
import androidx.annotation.NonNull;
public enum Router
{
Vehicle(0),
Pedestrian(1),
Bicycle(2),
Transit(3),
Ruler(4);
Router(int type)
{
this.type = type;
}
public static void set(@NonNull Router routerType)
{
nativeSet(routerType.type);
}
public static Router get()
{
return valueOf(nativeGet());
}
public static Router getLastUsed()
{
return valueOf(nativeGetLastUsed());
}
public static Router getBest(double srcLat, double srcLon, double dstLat, double dstLon)
{
return Router.values()[nativeGetBest(srcLat, srcLon, dstLat, dstLon)];
}
public static Router valueOf(int type)
{
return Router.values()[type];
}
private final int type;
private static native void nativeSet(int routerType);
private static native int nativeGet();
private static native int nativeGetLastUsed();
private static native int nativeGetBest(double srcLat, double srcLon, double dstLat, double dstLon);
}

View File

@@ -0,0 +1,22 @@
package app.organicmaps.sdk.api;
import androidx.annotation.Keep;
import app.organicmaps.sdk.Router;
/**
* Represents Framework::ParsedRoutingData from core.
*/
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public class ParsedRoutingData
{
public final RoutePoint[] mPoints;
public final Router mRouterType;
public ParsedRoutingData(RoutePoint[] points, int routerType)
{
this.mPoints = points;
this.mRouterType = Router.valueOf(routerType);
}
}

View File

@@ -0,0 +1,32 @@
package app.organicmaps.sdk.api;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Represents url_scheme::SearchRequest from core.
*/
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public final class ParsedSearchRequest
{
@NonNull
public final String mQuery;
@Nullable
public final String mLocale;
public final double mLat;
public final double mLon;
public final boolean mIsSearchOnMap;
public ParsedSearchRequest(@NonNull String query, @Nullable String locale, double lat, double lon,
boolean isSearchOnMap)
{
this.mQuery = query;
this.mLocale = locale;
this.mLat = lat;
this.mLon = lon;
this.mIsSearchOnMap = isSearchOnMap;
}
}

View File

@@ -0,0 +1,21 @@
package app.organicmaps.sdk.api;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.SOURCE)
@IntDef({RequestType.INCORRECT, RequestType.MAP, RequestType.ROUTE, RequestType.SEARCH, RequestType.CROSSHAIR,
RequestType.OAUTH2, RequestType.MENU, RequestType.SETTINGS})
public @interface RequestType
{
// Represents url_scheme::ParsedMapApi::UrlType from c++ part.
int INCORRECT = 0;
int MAP = 1;
int ROUTE = 2;
int SEARCH = 3;
int CROSSHAIR = 4;
int OAUTH2 = 5;
int MENU = 6;
int SETTINGS = 7;
}

View File

@@ -0,0 +1,23 @@
package app.organicmaps.sdk.api;
import androidx.annotation.Keep;
/**
* Represents url_scheme::RoutePoint from core.
*/
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public class RoutePoint
{
public final double mLat;
public final double mLon;
public final String mName;
public RoutePoint(double lat, double lon, String name)
{
mLat = lat;
mLon = lon;
mName = name;
}
}

View File

@@ -0,0 +1,158 @@
package app.organicmaps.sdk.bookmarks.data;
import android.annotation.SuppressLint;
import android.os.Parcel;
import androidx.annotation.ColorInt;
import androidx.annotation.IntRange;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.os.ParcelCompat;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.sdk.search.Popularity;
import app.organicmaps.sdk.util.Constants;
// TODO consider refactoring to remove hack with MapObject unmarshalling itself and Bookmark at the same time.
// Used by JNI.
@Keep
@SuppressWarnings("unused")
@SuppressLint("ParcelCreator")
public class Bookmark extends MapObject
{
private Icon mIcon;
private long mCategoryId;
private final long mBookmarkId;
private final double mMerX;
private final double mMerY;
public Bookmark(@NonNull FeatureId featureId, @IntRange(from = 0) long categoryId,
@IntRange(from = 0) long bookmarkId, String title, @Nullable String secondaryTitle,
@Nullable String subtitle, @Nullable String address, @Nullable RoutePointInfo routePointInfo,
@OpeningMode int openingMode, @NonNull Popularity popularity, @NonNull String description,
@Nullable String[] rawTypes)
{
super(featureId, BOOKMARK, title, secondaryTitle, subtitle, address, 0, 0, "", routePointInfo, openingMode,
popularity, description, RoadWarningMarkType.UNKNOWN.ordinal(), rawTypes);
mCategoryId = categoryId;
mBookmarkId = bookmarkId;
mIcon = getIconInternal();
final ParcelablePointD ll = BookmarkManager.INSTANCE.getBookmarkXY(mBookmarkId);
mMerX = ll.x;
mMerY = ll.y;
initXY();
}
private void initXY()
{
setLat(Math.toDegrees(2.0 * Math.atan(Math.exp(Math.toRadians(mMerY))) - Math.PI / 2.0));
setLon(mMerX);
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
super.writeToParcel(dest, flags);
dest.writeLong(mCategoryId);
dest.writeLong(mBookmarkId);
dest.writeParcelable(mIcon, flags);
dest.writeDouble(mMerX);
dest.writeDouble(mMerY);
}
// Do not use Core while restoring from Parcel! In some cases this constructor is called before
// the App is completely initialized.
// TODO: Method restoreHasCurrentPermission causes this strange behaviour, needs to be investigated.
protected Bookmark(@MapObjectType int type, Parcel source)
{
super(type, source);
mCategoryId = source.readLong();
mBookmarkId = source.readLong();
mIcon = ParcelCompat.readParcelable(source, Icon.class.getClassLoader(), Icon.class);
mMerX = source.readDouble();
mMerY = source.readDouble();
initXY();
}
@Override
public double getScale()
{
return BookmarkManager.INSTANCE.getBookmarkScale(mBookmarkId);
}
public DistanceAndAzimut getDistanceAndAzimuth(double cLat, double cLon, double north)
{
return Framework.nativeGetDistanceAndAzimuth(mMerX, mMerY, cLat, cLon, north);
}
private Icon getIconInternal()
{
return new Icon(BookmarkManager.INSTANCE.getBookmarkColor(mBookmarkId),
BookmarkManager.INSTANCE.getBookmarkIcon(mBookmarkId));
}
@Nullable
public Icon getIcon()
{
return mIcon;
}
public String getCategoryName()
{
return BookmarkManager.INSTANCE.getCategoryById(mCategoryId).getName();
}
public void setCategoryId(@IntRange(from = 0) long catId)
{
BookmarkManager.INSTANCE.notifyCategoryChanging(this, catId);
mCategoryId = catId;
}
public void setIconColor(@ColorInt int color)
{
Icon icon = new Icon(PredefinedColors.getPredefinedColorIndex(color),
BookmarkManager.INSTANCE.getBookmarkIcon(mBookmarkId));
BookmarkManager.INSTANCE.notifyParametersUpdating(this, getName(), icon, getBookmarkDescription());
mIcon = icon;
}
public void setParams(@NonNull String title, @Nullable Icon icon, @NonNull String description)
{
BookmarkManager.INSTANCE.notifyParametersUpdating(this, title, icon, description);
if (icon != null)
mIcon = icon;
setTitle(title);
setDescription(description);
}
public long getCategoryId()
{
return mCategoryId;
}
public long getBookmarkId()
{
return mBookmarkId;
}
@NonNull
public String getBookmarkDescription()
{
return BookmarkManager.INSTANCE.getBookmarkDescription(mBookmarkId);
}
@NonNull
public String getGe0Url(boolean addName)
{
return BookmarkManager.INSTANCE.encode2Ge0Url(mBookmarkId, addName);
}
@NonNull
public String getHttpGe0Url(boolean addName)
{
return getGe0Url(addName).replaceFirst(Constants.Url.SHORT_SHARE_PREFIX, Constants.Url.HTTP_SHARE_PREFIX);
}
}

View File

@@ -0,0 +1,15 @@
package app.organicmaps.sdk.bookmarks.data;
import androidx.annotation.NonNull;
import java.util.List;
public interface BookmarkCategoriesDataProvider
{
@NonNull
List<BookmarkCategory> getCategories();
int getCategoriesCount();
@NonNull
List<BookmarkCategory> getChildrenCategories(long parentId);
@NonNull
BookmarkCategory getCategoryById(long categoryId);
}

View File

@@ -0,0 +1,191 @@
package app.organicmaps.sdk.bookmarks.data;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.DrawableRes;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import app.organicmaps.sdk.R;
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public class BookmarkCategory implements Parcelable
{
private final long mId;
@NonNull
private final String mName;
@NonNull
private final String mAnnotation;
@NonNull
private final String mDescription;
private final int mTracksCount;
private final int mBookmarksCount;
private boolean mIsVisible;
public BookmarkCategory(long id, @NonNull String name, @NonNull String annotation, @NonNull String description,
int tracksCount, int bookmarksCount, boolean isVisible)
{
mId = id;
mName = name;
mAnnotation = annotation;
mDescription = description;
mTracksCount = tracksCount;
mBookmarksCount = bookmarksCount;
mIsVisible = isVisible;
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
BookmarkCategory that = (BookmarkCategory) o;
return mId == that.mId;
}
@Override
public int hashCode()
{
return (int) (mId ^ (mId >>> 32));
}
public long getId()
{
return mId;
}
@NonNull
public String getName()
{
return mName;
}
public int getTracksCount()
{
return mTracksCount;
}
public int getBookmarksCount()
{
return mBookmarksCount;
}
public boolean isVisible()
{
return mIsVisible;
}
public void setVisible(boolean isVisible)
{
mIsVisible = isVisible;
}
public int size()
{
return getBookmarksCount() + getTracksCount();
}
@NonNull
public String getAnnotation()
{
return mAnnotation;
}
@NonNull
public String getDescription()
{
return mDescription;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder("BookmarkCategory{");
sb.append("mId=").append(mId);
sb.append(", mName='").append(mName).append('\'');
sb.append(", mAnnotation='").append(mAnnotation).append('\'');
sb.append(", mDescription='").append(mDescription).append('\'');
sb.append(", mTracksCount=").append(mTracksCount);
sb.append(", mBookmarksCount=").append(mBookmarksCount);
sb.append(", mIsVisible=").append(mIsVisible);
sb.append('}');
return sb.toString();
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeLong(this.mId);
dest.writeString(this.mName);
dest.writeString(this.mAnnotation);
dest.writeString(this.mDescription);
dest.writeInt(this.mTracksCount);
dest.writeInt(this.mBookmarksCount);
dest.writeByte(this.mIsVisible ? (byte) 1 : (byte) 0);
}
protected BookmarkCategory(Parcel in)
{
this.mId = in.readLong();
this.mName = in.readString();
this.mAnnotation = in.readString();
this.mDescription = in.readString();
this.mTracksCount = in.readInt();
this.mBookmarksCount = in.readInt();
this.mIsVisible = in.readByte() != 0;
}
public static final Creator<BookmarkCategory> CREATOR = new Creator<>() {
@Override
public BookmarkCategory createFromParcel(Parcel source)
{
return new BookmarkCategory(source);
}
@Override
public BookmarkCategory[] newArray(int size)
{
return new BookmarkCategory[size];
}
};
public enum AccessRules
{
ACCESS_RULES_LOCAL(R.string.not_shared, R.drawable.ic_lock),
ACCESS_RULES_PUBLIC(R.string.public_access, R.drawable.ic_public_inline),
ACCESS_RULES_DIRECT_LINK(R.string.limited_access, R.drawable.ic_link_inline),
ACCESS_RULES_AUTHOR_ONLY(R.string.access_rules_author_only, R.drawable.ic_lock);
private final int mResId;
private final int mDrawableResId;
AccessRules(int resId, int drawableResId)
{
mResId = resId;
mDrawableResId = drawableResId;
}
@DrawableRes
public int getDrawableResId()
{
return mDrawableResId;
}
@StringRes
public int getNameResId()
{
return mResId;
}
}
}

View File

@@ -0,0 +1,106 @@
package app.organicmaps.sdk.bookmarks.data;
import androidx.annotation.IntRange;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.util.Distance;
import app.organicmaps.sdk.util.GeoUtils;
// Called from JNI.
@Keep
@SuppressWarnings("unused")
public class BookmarkInfo
{
private final long mCategoryId;
private final long mBookmarkId;
@NonNull
private final String mTitle;
@NonNull
private final String mFeatureType;
@NonNull
private final Icon mIcon;
private final double mMerX;
private final double mMerY;
private final double mScale;
@NonNull
private final String mAddress;
@NonNull
private final ParcelablePointD mLatLonPoint;
public BookmarkInfo(@IntRange(from = 0) long categoryId, @IntRange(from = 0) long bookmarkId)
{
mCategoryId = categoryId;
mBookmarkId = bookmarkId;
mTitle = BookmarkManager.INSTANCE.getBookmarkName(mBookmarkId);
mFeatureType = BookmarkManager.INSTANCE.getBookmarkFeatureType(mBookmarkId);
mIcon = new Icon(BookmarkManager.INSTANCE.getBookmarkColor(mBookmarkId),
BookmarkManager.INSTANCE.getBookmarkIcon(mBookmarkId));
final ParcelablePointD ll = BookmarkManager.INSTANCE.getBookmarkXY(mBookmarkId);
mMerX = ll.x;
mMerY = ll.y;
mScale = BookmarkManager.INSTANCE.getBookmarkScale(mBookmarkId);
mAddress = BookmarkManager.INSTANCE.getBookmarkAddress(mBookmarkId);
mLatLonPoint = GeoUtils.toLatLon(mMerX, mMerY);
}
public long getCategoryId()
{
return mCategoryId;
}
public long getBookmarkId()
{
return mBookmarkId;
}
public DistanceAndAzimut getDistanceAndAzimuth(double cLat, double cLon, double north)
{
return Framework.nativeGetDistanceAndAzimuth(mMerX, mMerY, cLat, cLon, north);
}
@NonNull
public String getFeatureType()
{
return mFeatureType;
}
@NonNull
public String getName()
{
return mTitle;
}
@NonNull
public Icon getIcon()
{
return mIcon;
}
@NonNull
public Distance getDistance(double latitude, double longitude, double v)
{
return getDistanceAndAzimuth(latitude, longitude, v).getDistance();
}
public double getLat()
{
return mLatLonPoint.x;
}
public double getLon()
{
return mLatLonPoint.y;
}
public double getScale()
{
return mScale;
}
@NonNull
public String getAddress()
{
return mAddress;
}
}

View File

@@ -0,0 +1,997 @@
package app.organicmaps.sdk.bookmarks.data;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
import androidx.annotation.Keep;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.util.KeyValue;
import app.organicmaps.sdk.util.StorageUtils;
import app.organicmaps.sdk.util.concurrency.UiThread;
import app.organicmaps.sdk.util.log.Logger;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@MainThread
public enum BookmarkManager {
INSTANCE;
@Retention(RetentionPolicy.SOURCE)
@IntDef({SORT_BY_TYPE, SORT_BY_DISTANCE, SORT_BY_TIME, SORT_BY_NAME})
public @interface SortingType
{}
public static final int SORT_BY_TYPE = 0;
public static final int SORT_BY_DISTANCE = 1;
public static final int SORT_BY_TIME = 2;
public static final int SORT_BY_NAME = 3;
// These values have to match the values of kml::CompilationType from kml/types.hpp
public static final int CATEGORY = 0;
private static final String[] BOOKMARKS_EXTENSIONS = Framework.nativeGetBookmarksFilesExts();
private static final String TAG = BookmarkManager.class.getSimpleName();
@NonNull
private final BookmarkCategoriesDataProvider mCategoriesCoreDataProvider = new CoreBookmarkCategoriesDataProvider();
@NonNull
private BookmarkCategoriesDataProvider mCurrentDataProvider = mCategoriesCoreDataProvider;
private final BookmarkCategoriesCache mBookmarkCategoriesCache = new BookmarkCategoriesCache();
@NonNull
private final List<BookmarksLoadingListener> mListeners = new ArrayList<>();
@NonNull
private final List<BookmarksSortingListener> mSortingListeners = new ArrayList<>();
@NonNull
private final List<BookmarksSharingListener> mSharingListeners = new ArrayList<>();
@Nullable
private OnElevationCurrentPositionChangedListener mOnElevationCurrentPositionChangedListener;
@Nullable
private OnElevationActivePointChangedListener mOnElevationActivePointChangedListener;
public void toggleCategoryVisibility(@NonNull BookmarkCategory category)
{
boolean isVisible = isVisible(category.getId());
setVisibility(category.getId(), !isVisible);
}
@Nullable
public Bookmark addNewBookmark(double lat, double lon)
{
return nativeAddBookmarkToLastEditedCategory(lat, lon);
}
public void addLoadingListener(@NonNull BookmarksLoadingListener listener)
{
mListeners.add(listener);
}
public void removeLoadingListener(@NonNull BookmarksLoadingListener listener)
{
mListeners.remove(listener);
}
public void addSortingListener(@NonNull BookmarksSortingListener listener)
{
mSortingListeners.add(listener);
}
public void removeSortingListener(@NonNull BookmarksSortingListener listener)
{
mSortingListeners.remove(listener);
}
public void addSharingListener(@NonNull BookmarksSharingListener listener)
{
mSharingListeners.add(listener);
}
public void removeSharingListener(@NonNull BookmarksSharingListener listener)
{
mSharingListeners.remove(listener);
}
public void setElevationActivePointChangedListener(@Nullable OnElevationActivePointChangedListener listener)
{
if (listener != null)
nativeSetElevationActiveChangedListener();
else
nativeRemoveElevationActiveChangedListener();
mOnElevationActivePointChangedListener = listener;
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
public void onBookmarksChanged()
{
updateCache();
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
public void onBookmarksLoadingStarted()
{
for (BookmarksLoadingListener listener : mListeners)
listener.onBookmarksLoadingStarted();
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
public void onBookmarksLoadingFinished()
{
updateCache();
mCurrentDataProvider = new CacheBookmarkCategoriesDataProvider();
for (BookmarksLoadingListener listener : mListeners)
listener.onBookmarksLoadingFinished();
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
public void onBookmarksSortingCompleted(@NonNull SortedBlock[] sortedBlocks, long timestamp)
{
for (BookmarksSortingListener listener : mSortingListeners)
listener.onBookmarksSortingCompleted(sortedBlocks, timestamp);
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
public void onBookmarksSortingCancelled(long timestamp)
{
for (BookmarksSortingListener listener : mSortingListeners)
listener.onBookmarksSortingCancelled(timestamp);
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
public void onBookmarksFileLoaded(boolean success, @NonNull String fileName, boolean isTemporaryFile)
{
// Android could create temporary file with bookmarks in some cases (KML/KMZ file is a blob
// in the intent, so we have to create a temporary file on the disk). Here we can delete it.
if (isTemporaryFile)
{
File tmpFile = new File(fileName);
tmpFile.delete();
}
if (success)
{
for (BookmarksLoadingListener listener : mListeners)
listener.onBookmarksFileImportSuccessful();
}
else
{
for (BookmarksLoadingListener listener : mListeners)
listener.onBookmarksFileImportFailed();
}
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
public void onPreparedFileForSharing(BookmarkSharingResult result)
{
for (BookmarksSharingListener listener : mSharingListeners)
listener.onPreparedFileForSharing(result);
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
public void onElevationCurrentPositionChanged()
{
if (mOnElevationCurrentPositionChangedListener != null)
mOnElevationCurrentPositionChangedListener.onCurrentPositionChanged();
}
public void setElevationCurrentPositionChangedListener(@Nullable OnElevationCurrentPositionChangedListener listener)
{
if (listener != null)
nativeSetElevationCurrentPositionChangedListener();
else
nativeRemoveElevationCurrentPositionChangedListener();
mOnElevationCurrentPositionChangedListener = listener;
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
public void onElevationActivePointChanged()
{
if (mOnElevationActivePointChangedListener != null)
mOnElevationActivePointChangedListener.onElevationActivePointChanged();
}
public boolean isVisible(long catId)
{
return nativeIsVisible(catId);
}
public void setVisibility(long catId, boolean visible)
{
nativeSetVisibility(catId, visible);
}
public void setCategoryName(long catId, @NonNull String name)
{
nativeSetCategoryName(catId, name);
}
public void setCategoryDescription(long id, @NonNull String categoryDesc)
{
nativeSetCategoryDescription(id, categoryDesc);
}
@Nullable
public Bookmark updateBookmarkPlacePage(long bmkId)
{
return nativeUpdateBookmarkPlacePage(bmkId);
}
@Nullable
public void updateTrackPlacePage()
{
nativeUpdateTrackPlacePage();
}
@Nullable
public BookmarkInfo getBookmarkInfo(long bmkId)
{
return nativeGetBookmarkInfo(bmkId);
}
public long getBookmarkIdByPosition(long catId, int positionInCategory)
{
return nativeGetBookmarkIdByPosition(catId, positionInCategory);
}
@NonNull
public Track getTrack(long trackId)
{
return nativeGetTrack(trackId, Track.class);
}
public long getTrackIdByPosition(long catId, int positionInCategory)
{
return nativeGetTrackIdByPosition(catId, positionInCategory);
}
public static void loadBookmarks()
{
nativeLoadBookmarks();
}
public void deleteCategory(long catId)
{
nativeDeleteCategory(catId);
}
public void deleteTrack(long trackId)
{
nativeDeleteTrack(trackId);
}
public void deleteBookmark(long bmkId)
{
nativeDeleteBookmark(bmkId);
}
public long createCategory(@NonNull String name)
{
return nativeCreateCategory(name);
}
public void showBookmarkOnMap(long bmkId)
{
nativeShowBookmarkOnMap(bmkId);
}
public void showBookmarkCategoryOnMap(long catId)
{
nativeShowBookmarkCategoryOnMap(catId);
}
@PredefinedColors.Color
public int getLastEditedColor()
{
return nativeGetLastEditedColor();
}
@MainThread
public void loadBookmarksFile(@NonNull String path, boolean isTemporaryFile)
{
Logger.d(TAG, "Loading bookmarks file from: " + path);
nativeLoadBookmarksFile(path, isTemporaryFile);
}
static @Nullable String getBookmarksFilenameFromUri(@NonNull ContentResolver resolver, @NonNull Uri uri)
{
String filename = null;
final String scheme = uri.getScheme();
if (scheme.equals("content"))
{
try (Cursor cursor = resolver.query(uri, null, null, null, null))
{
if (cursor != null && cursor.moveToFirst())
{
final int columnIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (columnIndex >= 0)
filename = cursor.getString(columnIndex);
}
}
}
if (filename == null)
{
filename = uri.getPath();
if (filename == null)
return null;
final int cut = filename.lastIndexOf('/');
if (cut != -1)
filename = filename.substring(cut + 1);
}
// See IsBadCharForPath()
filename = filename.replaceAll("[:/\\\\<>\"|?*]", "");
final String lowerCaseFilename = filename.toLowerCase(java.util.Locale.ROOT);
// Check that filename contains bookmarks extension.
for (String ext : BOOKMARKS_EXTENSIONS)
{
if (lowerCaseFilename.endsWith(ext))
return filename;
}
// Samsung browser adds .xml extension to downloaded gpx files.
// Duplicate files have " (1).xml", " (2).xml" suffixes added.
final String gpxExt = ".gpx";
final int gpxStart = lowerCaseFilename.lastIndexOf(gpxExt);
if (gpxStart != -1)
return filename.substring(0, gpxStart + gpxExt.length());
// Try get guess extension from the mime type.
final String mime = resolver.getType(uri);
if (mime != null)
{
final int i = mime.lastIndexOf('.');
if (i != -1)
{
final String type = mime.substring(i + 1);
if (type.equalsIgnoreCase("kmz"))
return filename + ".kmz";
else if (type.equalsIgnoreCase("kml+xml"))
return filename + ".kml";
}
if (mime.endsWith("gpx+xml") || mime.endsWith("gpx")) // match application/gpx, application/gpx+xml
return filename + ".gpx";
}
// WhatsApp doesn't provide correct mime type and extension for GPX files.
if (uri.getHost().contains("com.whatsapp.provider.media"))
return filename + ".gpx";
return null;
}
@WorkerThread
public boolean importBookmarksFile(@NonNull ContentResolver resolver, @NonNull Uri uri, @NonNull File tempDir)
{
Logger.w(TAG, "Importing bookmarks from " + uri);
try
{
String filename = getBookmarksFilenameFromUri(resolver, uri);
if (filename == null)
{
Logger.w(TAG, "Could not find a supported file type in " + uri);
UiThread.run(() -> {
for (BookmarksLoadingListener listener : mListeners)
listener.onBookmarksFileUnsupported(uri);
});
return false;
}
Logger.d(TAG, "Downloading bookmarks file from " + uri + " into " + filename);
final File tempFile = new File(tempDir, filename);
StorageUtils.copyFile(resolver, uri, tempFile);
Logger.d(TAG, "Downloaded bookmarks file from " + uri + " into " + filename);
UiThread.run(() -> loadBookmarksFile(tempFile.getAbsolutePath(), true));
return true;
}
catch (IOException | SecurityException e)
{
Logger.e(TAG, "Could not download bookmarks file from " + uri, e);
UiThread.run(() -> {
for (BookmarksLoadingListener listener : mListeners)
listener.onBookmarksFileDownloadFailed(uri, e.toString());
});
return false;
}
}
@WorkerThread
public void importBookmarksFiles(@NonNull ContentResolver resolver, @NonNull List<Uri> uris, @NonNull File tempDir)
{
for (Uri uri : uris)
importBookmarksFile(resolver, uri, tempDir);
}
public boolean isAsyncBookmarksLoadingInProgress()
{
return nativeIsAsyncBookmarksLoadingInProgress();
}
@NonNull
public List<BookmarkCategory> getCategories()
{
return mCurrentDataProvider.getCategories();
}
public int getCategoriesCount()
{
return mCurrentDataProvider.getCategoriesCount();
}
@NonNull
BookmarkCategoriesCache getBookmarkCategoriesCache()
{
return mBookmarkCategoriesCache;
}
private void updateCache()
{
getBookmarkCategoriesCache().update(mCategoriesCoreDataProvider.getCategories());
}
public void addCategoriesUpdatesListener(@NonNull DataChangedListener listener)
{
getBookmarkCategoriesCache().registerListener(listener);
}
public void removeCategoriesUpdatesListener(@NonNull DataChangedListener listener)
{
getBookmarkCategoriesCache().unregisterListener(listener);
}
@NonNull
public BookmarkCategory getCategoryById(long categoryId)
{
return mCurrentDataProvider.getCategoryById(categoryId);
}
public boolean isUsedCategoryName(@NonNull String name)
{
return nativeIsUsedCategoryName(name);
}
public void prepareForSearch(long catId)
{
nativePrepareForSearch(catId);
}
public boolean areAllCategoriesVisible()
{
return nativeAreAllCategoriesVisible();
}
public boolean areAllCategoriesInvisible()
{
return nativeAreAllCategoriesInvisible();
}
public void setAllCategoriesVisibility(boolean visible)
{
nativeSetAllCategoriesVisibility(visible);
}
public void setChildCategoriesVisibility(long catId, boolean visible)
{
nativeSetChildCategoriesVisibility(catId, visible);
}
public void prepareCategoriesForSharing(long[] catIds, KmlFileType kmlFileType)
{
nativePrepareFileForSharing(catIds, kmlFileType.ordinal());
}
public void prepareTrackForSharing(long trackId, KmlFileType kmlFileType)
{
nativePrepareTrackFileForSharing(trackId, kmlFileType.ordinal());
}
public void setNotificationsEnabled(boolean enabled)
{
nativeSetNotificationsEnabled(enabled);
}
public boolean hasLastSortingType(long catId)
{
return nativeHasLastSortingType(catId);
}
@SortingType
public int getLastSortingType(long catId)
{
return nativeGetLastSortingType(catId);
}
public void setLastSortingType(long catId, @SortingType int sortingType)
{
nativeSetLastSortingType(catId, sortingType);
}
public void resetLastSortingType(long catId)
{
nativeResetLastSortingType(catId);
}
@NonNull
@SortingType
public int[] getAvailableSortingTypes(long catId, boolean hasMyPosition)
{
return nativeGetAvailableSortingTypes(catId, hasMyPosition);
}
public void getSortedCategory(long catId, @SortingType int sortingType, boolean hasMyPosition, double lat, double lon,
long timestamp)
{
nativeGetSortedCategory(catId, sortingType, hasMyPosition, lat, lon, timestamp);
}
@NonNull
public List<BookmarkCategory> getChildrenCategories(long catId)
{
return mCurrentDataProvider.getChildrenCategories(catId);
}
@NonNull
native BookmarkCategory nativeGetBookmarkCategory(long catId);
@NonNull
native BookmarkCategory[] nativeGetBookmarkCategories();
native int nativeGetBookmarkCategoriesCount();
@NonNull
native BookmarkCategory[] nativeGetChildrenCategories(long catId);
@NonNull
public String getBookmarkName(@IntRange(from = 0) long bookmarkId)
{
return nativeGetBookmarkName(bookmarkId);
}
@NonNull
public String getBookmarkFeatureType(@IntRange(from = 0) long bookmarkId)
{
return nativeGetBookmarkFeatureType(bookmarkId);
}
@NonNull
public ParcelablePointD getBookmarkXY(@IntRange(from = 0) long bookmarkId)
{
return nativeGetBookmarkXY(bookmarkId);
}
@PredefinedColors.Color
public int getBookmarkColor(@IntRange(from = 0) long bookmarkId)
{
return nativeGetBookmarkColor(bookmarkId);
}
public int getBookmarkIcon(@IntRange(from = 0) long bookmarkId)
{
return nativeGetBookmarkIcon(bookmarkId);
}
@NonNull
public String getBookmarkDescription(@IntRange(from = 0) long bookmarkId)
{
return nativeGetBookmarkDescription(bookmarkId);
}
public String getTrackDescription(@IntRange(from = 0) long trackId)
{
return nativeGetTrackDescription(trackId);
}
public double getBookmarkScale(@IntRange(from = 0) long bookmarkId)
{
return nativeGetBookmarkScale(bookmarkId);
}
@NonNull
public String encode2Ge0Url(@IntRange(from = 0) long bookmarkId, boolean addName)
{
return nativeEncode2Ge0Url(bookmarkId, addName);
}
public void setBookmarkParams(@IntRange(from = 0) long bookmarkId, @NonNull String name,
@PredefinedColors.Color int color, @NonNull String descr)
{
nativeSetBookmarkParams(bookmarkId, name, color, descr);
}
public void setTrackParams(@IntRange(from = 0) long trackId, @NonNull String name, int color, @NonNull String descr)
{
nativeSetTrackParams(trackId, name, color, descr);
}
public void changeTrackColor(@IntRange(from = 0) long trackId, int color)
{
nativeChangeTrackColor(trackId, color);
}
public void changeBookmarkCategory(@IntRange(from = 0) long oldCatId, @IntRange(from = 0) long newCatId,
@IntRange(from = 0) long bookmarkId)
{
nativeChangeBookmarkCategory(oldCatId, newCatId, bookmarkId);
}
public void changeTrackCategory(@IntRange(from = 0) long oldCatId, @IntRange(from = 0) long newCatId,
@IntRange(from = 0) long trackId)
{
nativeChangeTrackCategory(oldCatId, newCatId, trackId);
}
@NonNull
public String getBookmarkAddress(@IntRange(from = 0) long bookmarkId)
{
return nativeGetBookmarkAddress(bookmarkId);
}
public void notifyCategoryChanging(@NonNull BookmarkInfo bookmarkInfo, @IntRange(from = 0) long catId)
{
if (catId == bookmarkInfo.getCategoryId())
return;
changeBookmarkCategory(bookmarkInfo.getCategoryId(), catId, bookmarkInfo.getBookmarkId());
}
public void notifyCategoryChanging(@NonNull Track track, @IntRange(from = 0) long catId)
{
if (catId == track.getCategoryId())
return;
changeTrackCategory(track.getCategoryId(), catId, track.getTrackId());
}
public void notifyCategoryChanging(@NonNull Bookmark bookmark, @IntRange(from = 0) long catId)
{
if (catId == bookmark.getCategoryId())
return;
changeBookmarkCategory(bookmark.getCategoryId(), catId, bookmark.getBookmarkId());
}
public void notifyParametersUpdating(@NonNull BookmarkInfo bookmarkInfo, @NonNull String name, @Nullable Icon icon,
@NonNull String description)
{
if (icon == null)
icon = bookmarkInfo.getIcon();
if (!name.equals(bookmarkInfo.getName()) || !icon.equals(bookmarkInfo.getIcon())
|| !description.equals(getBookmarkDescription(bookmarkInfo.getBookmarkId())))
{
setBookmarkParams(bookmarkInfo.getBookmarkId(), name, icon.getColor(), description);
}
}
public void notifyParametersUpdating(@NonNull Bookmark bookmark, @NonNull String name, @Nullable Icon icon,
@NonNull String description)
{
if (icon == null)
icon = bookmark.getIcon();
if (!name.equals(bookmark.getName()) || !icon.equals(bookmark.getIcon())
|| !description.equals(getBookmarkDescription(bookmark.getBookmarkId())))
{
setBookmarkParams(bookmark.getBookmarkId(), name, icon != null ? icon.getColor() : getLastEditedColor(),
description);
}
}
public void notifyParametersUpdating(@NonNull Track track, @NonNull String name, @Nullable int color,
@NonNull String description)
{
if (!name.equals(track.getName()) || !(color == track.getColor())
|| !description.equals(getTrackDescription(track.getTrackId())))
{
setTrackParams(track.getTrackId(), name, color, description);
}
}
public double getElevationCurPositionDistance(long trackId)
{
return nativeGetElevationCurPositionDistance(trackId);
}
public void setElevationActivePoint(long trackId, double distance, ElevationInfo.Point point)
{
nativeSetElevationActivePoint(trackId, distance, point.getLatitude(), point.getLongitude());
}
public double getElevationActivePointDistance(long trackId)
{
return nativeGetElevationActivePointDistance(trackId);
}
private static native ElevationInfo.Point nativeGetElevationActivePointCoordinates(long trackId);
@Nullable
private native Bookmark nativeUpdateBookmarkPlacePage(long bmkId);
@Nullable
private native void nativeUpdateTrackPlacePage();
@Nullable
private native BookmarkInfo nativeGetBookmarkInfo(long bmkId);
private native long nativeGetBookmarkIdByPosition(long catId, int position);
@NonNull
private native Track nativeGetTrack(long trackId, Class<Track> trackClazz);
private native long nativeGetTrackIdByPosition(long catId, int position);
private native boolean nativeIsVisible(long catId);
private native void nativeSetVisibility(long catId, boolean visible);
private native void nativeSetCategoryName(long catId, @NonNull String n);
private native void nativeSetCategoryDescription(long catId, @NonNull String desc);
private native void nativeSetCategoryTags(long catId, @NonNull String[] tagsIds);
private native void nativeSetCategoryAccessRules(long catId, int accessRules);
private native void nativeSetCategoryCustomProperty(long catId, String key, String value);
private static native void nativeLoadBookmarks();
private native boolean nativeDeleteCategory(long catId);
private native void nativeDeleteTrack(long trackId);
private native void nativeDeleteBookmark(long bmkId);
/**
* @return category Id
*/
private native long nativeCreateCategory(@NonNull String name);
private native void nativeShowBookmarkOnMap(long bmkId);
private native void nativeShowBookmarkCategoryOnMap(long catId);
@Nullable
private native Bookmark nativeAddBookmarkToLastEditedCategory(double lat, double lon);
@PredefinedColors.Color
private native int nativeGetLastEditedColor();
private static native void nativeLoadBookmarksFile(@NonNull String path, boolean isTemporaryFile);
private static native boolean nativeIsAsyncBookmarksLoadingInProgress();
private static native boolean nativeIsUsedCategoryName(@NonNull String name);
private static native void nativePrepareForSearch(long catId);
private static native boolean nativeAreAllCategoriesVisible();
private static native boolean nativeAreAllCategoriesInvisible();
private static native void nativeSetChildCategoriesVisibility(long catId, boolean visible);
private static native void nativeSetAllCategoriesVisibility(boolean visible);
private static native void nativePrepareFileForSharing(long[] catIds, int kmlFileType);
private static native void nativePrepareTrackFileForSharing(long trackId, int kmlFileType);
private static native boolean nativeIsCategoryEmpty(long catId);
private static native void nativeSetNotificationsEnabled(boolean enabled);
@NonNull
private static native String nativeGetCatalogDeeplink(long catId);
@NonNull
private static native String nativeGetCatalogPublicLink(long catId);
@NonNull
private static native String nativeGetWebEditorUrl(@NonNull String serverId);
@NonNull
private static native KeyValue[] nativeGetCatalogHeaders();
private static native void nativeRequestCatalogCustomProperties();
private native boolean nativeHasLastSortingType(long catId);
@SortingType
private native int nativeGetLastSortingType(long catId);
private native void nativeSetLastSortingType(long catId, @SortingType int sortingType);
private native void nativeResetLastSortingType(long catId);
@NonNull
@SortingType
private native int[] nativeGetAvailableSortingTypes(long catId, boolean hasMyPosition);
private native void nativeGetSortedCategory(long catId, @SortingType int sortingType, boolean hasMyPosition,
double lat, double lon, long timestamp);
@NonNull
private static native String nativeGetBookmarkName(@IntRange(from = 0) long bookmarkId);
@NonNull
private static native String nativeGetBookmarkFeatureType(@IntRange(from = 0) long bookmarkId);
@NonNull
private static native ParcelablePointD nativeGetBookmarkXY(@IntRange(from = 0) long bookmarkId);
@PredefinedColors.Color
private static native int nativeGetBookmarkColor(@IntRange(from = 0) long bookmarkId);
private static native int nativeGetBookmarkIcon(@IntRange(from = 0) long bookmarkId);
@NonNull
private static native String nativeGetBookmarkDescription(@IntRange(from = 0) long bookmarkId);
private static native String nativeGetTrackDescription(@IntRange(from = 0) long trackId);
private static native double nativeGetBookmarkScale(@IntRange(from = 0) long bookmarkId);
@NonNull
private static native String nativeEncode2Ge0Url(@IntRange(from = 0) long bookmarkId, boolean addName);
private static native void nativeSetBookmarkParams(@IntRange(from = 0) long bookmarkId, @NonNull String name,
@PredefinedColors.Color int color, @NonNull String descr);
private static native void nativeChangeTrackColor(@IntRange(from = 0) long trackId,
@PredefinedColors.Color int color);
private static native void nativeSetTrackParams(@IntRange(from = 0) long trackId, @NonNull String name,
@PredefinedColors.Color int color, @NonNull String descr);
private static native void nativeChangeBookmarkCategory(@IntRange(from = 0) long oldCatId,
@IntRange(from = 0) long newCatId,
@IntRange(from = 0) long bookmarkId);
private static native void nativeChangeTrackCategory(@IntRange(from = 0) long oldCatId,
@IntRange(from = 0) long newCatId,
@IntRange(from = 0) long trackId);
@NonNull
private static native String nativeGetBookmarkAddress(@IntRange(from = 0) long bookmarkId);
private static native double nativeGetElevationCurPositionDistance(long trackId);
private static native void nativeSetElevationCurrentPositionChangedListener();
public static native void nativeRemoveElevationCurrentPositionChangedListener();
private static native void nativeSetElevationActivePoint(long trackId, double distanceInMeters, double latitude,
double longitude);
private static native double nativeGetElevationActivePointDistance(long trackId);
public ElevationInfo.Point getElevationActivePointCoordinates(long trackId)
{
return nativeGetElevationActivePointCoordinates(trackId);
}
private static native void nativeSetElevationActiveChangedListener();
public static native void nativeRemoveElevationActiveChangedListener();
public static native ElevationInfo nativeGetTrackElevationInfo(long trackId);
public static native TrackStatistics nativeGetTrackStatistics(long trackId);
public interface BookmarksLoadingListener
{
default void onBookmarksLoadingStarted() {}
default void onBookmarksLoadingFinished() {}
default void onBookmarksFileUnsupported(@NonNull Uri uri) {}
default void onBookmarksFileDownloadFailed(@NonNull Uri uri, @NonNull String string) {}
default void onBookmarksFileImportSuccessful() {}
default void onBookmarksFileImportFailed() {}
}
public interface BookmarksSortingListener
{
void onBookmarksSortingCompleted(@NonNull SortedBlock[] sortedBlocks, long timestamp);
default void onBookmarksSortingCancelled(long timestamp) {}
}
public interface BookmarksSharingListener
{
void onPreparedFileForSharing(@NonNull BookmarkSharingResult result);
}
public interface OnElevationActivePointChangedListener
{
void onElevationActivePointChanged();
}
public interface OnElevationCurrentPositionChangedListener
{
void onCurrentPositionChanged();
}
static class BookmarkCategoriesCache
{
@NonNull
private final List<BookmarkCategory> mCategories = new ArrayList<>();
@NonNull
private final List<DataChangedListener> mListeners = new ArrayList<>();
void update(@NonNull List<BookmarkCategory> categories)
{
mCategories.clear();
mCategories.addAll(categories);
notifyChanged();
}
@NonNull
public List<BookmarkCategory> getCategories()
{
return Collections.unmodifiableList(mCategories);
}
public void registerListener(@NonNull DataChangedListener listener)
{
if (mListeners.contains(listener))
throw new IllegalStateException("Observer " + listener + " is already registered.");
mListeners.add(listener);
}
public void unregisterListener(@NonNull DataChangedListener listener)
{
int index = mListeners.indexOf(listener);
if (index == -1)
throw new IllegalStateException("Observer " + listener + " was not registered.");
mListeners.remove(index);
}
protected void notifyChanged()
{
for (DataChangedListener item : mListeners)
item.onChanged();
}
}
}

View File

@@ -0,0 +1,72 @@
package app.organicmaps.sdk.bookmarks.data;
import androidx.annotation.IntDef;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// Called from JNI.
@Keep
@SuppressWarnings("unused")
public class BookmarkSharingResult
{
@Retention(RetentionPolicy.SOURCE)
@IntDef({SUCCESS, EMPTY_CATEGORY, ARCHIVE_ERROR, FILE_ERROR})
public @interface Code
{}
public static final int SUCCESS = 0;
public static final int EMPTY_CATEGORY = 1;
public static final int ARCHIVE_ERROR = 2;
public static final int FILE_ERROR = 3;
private final long[] mCategoriesIds;
@Code
private final int mCode;
@NonNull
private final String mSharingPath;
@NonNull
@SuppressWarnings("unused")
private final String mErrorString;
@NonNull
@SuppressWarnings("unused")
private final String mMimeType;
public BookmarkSharingResult(long[] categoriesIds, @Code int code, @NonNull String sharingPath,
@NonNull String mimeType, @NonNull String errorString)
{
mCategoriesIds = categoriesIds;
mCode = code;
mSharingPath = sharingPath;
mErrorString = errorString;
mMimeType = mimeType;
}
public long[] getCategoriesIds()
{
return mCategoriesIds;
}
public int getCode()
{
return mCode;
}
@NonNull
public String getSharingPath()
{
return mSharingPath;
}
@NonNull
public String getMimeType()
{
return mMimeType;
}
@NonNull
public String getErrorString()
{
return mErrorString;
}
}

View File

@@ -0,0 +1,43 @@
package app.organicmaps.sdk.bookmarks.data;
import androidx.annotation.NonNull;
import java.util.Arrays;
import java.util.List;
class CacheBookmarkCategoriesDataProvider implements BookmarkCategoriesDataProvider
{
@NonNull
@Override
public BookmarkCategory getCategoryById(long categoryId)
{
BookmarkManager.BookmarkCategoriesCache cache = BookmarkManager.INSTANCE.getBookmarkCategoriesCache();
List<BookmarkCategory> categories = cache.getCategories();
for (BookmarkCategory category : categories)
if (category.getId() == categoryId)
return category;
return BookmarkManager.INSTANCE.nativeGetBookmarkCategory(categoryId);
}
@NonNull
@Override
public List<BookmarkCategory> getCategories()
{
return BookmarkManager.INSTANCE.getBookmarkCategoriesCache().getCategories();
}
@Override
public int getCategoriesCount()
{
return BookmarkManager.INSTANCE.nativeGetBookmarkCategoriesCount();
}
@NonNull
@Override
public List<BookmarkCategory> getChildrenCategories(long parentId)
{
BookmarkCategory[] categories = BookmarkManager.INSTANCE.nativeGetChildrenCategories(parentId);
return Arrays.asList(categories);
}
}

View File

@@ -0,0 +1,40 @@
package app.organicmaps.sdk.bookmarks.data;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.sdk.content.DataSource;
import java.util.List;
public class CategoryDataSource extends RecyclerView.AdapterDataObserver implements DataSource<BookmarkCategory>
{
@NonNull
private BookmarkCategory mCategory;
public CategoryDataSource(@NonNull BookmarkCategory category)
{
mCategory = category;
}
@NonNull
@Override
public BookmarkCategory getData()
{
return mCategory;
}
@Override
public void onChanged()
{
super.onChanged();
List<BookmarkCategory> categories = BookmarkManager.INSTANCE.getCategories();
int index = categories.indexOf(mCategory);
if (index >= 0)
mCategory = categories.get(index);
}
@Override
public void invalidate()
{
onChanged();
}
}

View File

@@ -0,0 +1,37 @@
package app.organicmaps.sdk.bookmarks.data;
import androidx.annotation.NonNull;
import java.util.Arrays;
import java.util.List;
class CoreBookmarkCategoriesDataProvider implements BookmarkCategoriesDataProvider
{
@NonNull
@Override
public BookmarkCategory getCategoryById(long categoryId)
{
return BookmarkManager.INSTANCE.nativeGetBookmarkCategory(categoryId);
}
@NonNull
@Override
public List<BookmarkCategory> getCategories()
{
BookmarkCategory[] categories = BookmarkManager.INSTANCE.nativeGetBookmarkCategories();
return Arrays.asList(categories);
}
@Override
public int getCategoriesCount()
{
return BookmarkManager.INSTANCE.nativeGetBookmarkCategoriesCount();
}
@NonNull
@Override
public List<BookmarkCategory> getChildrenCategories(long parentId)
{
BookmarkCategory[] categories = BookmarkManager.INSTANCE.nativeGetChildrenCategories(parentId);
return Arrays.asList(categories);
}
}

View File

@@ -0,0 +1,6 @@
package app.organicmaps.sdk.bookmarks.data;
public interface DataChangedListener
{
void onChanged();
}

View File

@@ -0,0 +1,29 @@
package app.organicmaps.sdk.bookmarks.data;
import androidx.annotation.Keep;
import app.organicmaps.sdk.util.Distance;
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public class DistanceAndAzimut
{
private final Distance mDistance;
private final double mAzimuth;
public Distance getDistance()
{
return mDistance;
}
public double getAzimuth()
{
return mAzimuth;
}
public DistanceAndAzimut(Distance distance, double azimuth)
{
mDistance = distance;
mAzimuth = azimuth;
}
}

View File

@@ -0,0 +1,155 @@
package app.organicmaps.sdk.bookmarks.data;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import app.organicmaps.sdk.widget.placepage.PlacePageData;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public class ElevationInfo implements PlacePageData
{
@NonNull
private final List<Point> mPoints;
private final int mDifficulty;
public ElevationInfo(@NonNull Point[] points, int difficulty)
{
mPoints = Arrays.asList(points);
mDifficulty = difficulty;
}
protected ElevationInfo(Parcel in)
{
mDifficulty = in.readInt();
mPoints = readPoints(in);
}
@NonNull
private static List<Point> readPoints(@NonNull Parcel in)
{
List<Point> points = new ArrayList<>();
in.readTypedList(points, Point.CREATOR);
return points;
}
@NonNull
public List<Point> getPoints()
{
return Collections.unmodifiableList(mPoints);
}
public int getDifficulty()
{
return mDifficulty;
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(mDifficulty);
// All collections are deserialized AFTER non-collection and primitive type objects,
// so collections must be always serialized at the end.
dest.writeTypedList(mPoints);
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
public static class Point implements Parcelable
{
private final double mDistance;
private final int mAltitude;
private final double mLatitude;
private final double mLongitude;
public Point(double distance, int altitude, double latitude, double longitude)
{
mDistance = distance;
mAltitude = altitude;
mLatitude = latitude;
mLongitude = longitude;
}
protected Point(Parcel in)
{
mDistance = in.readDouble();
mAltitude = in.readInt();
mLatitude = in.readDouble();
mLongitude = in.readDouble();
}
public static final Creator<Point> CREATOR = new Creator<>() {
@Override
public Point createFromParcel(Parcel in)
{
return new Point(in);
}
@Override
public Point[] newArray(int size)
{
return new Point[size];
}
};
public double getDistance()
{
return mDistance;
}
public int getAltitude()
{
return mAltitude;
}
public double getLatitude()
{
return mLatitude;
}
public double getLongitude()
{
return mLongitude;
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeDouble(mDistance);
dest.writeInt(mAltitude);
}
}
public static final Creator<ElevationInfo> CREATOR = new Creator<>() {
@Override
public ElevationInfo createFromParcel(Parcel in)
{
return new ElevationInfo(in);
}
@Override
public ElevationInfo[] newArray(int size)
{
return new ElevationInfo[size];
}
};
}

View File

@@ -0,0 +1,64 @@
package app.organicmaps.sdk.bookmarks.data;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.Nullable;
import java.net.HttpURLConnection;
public class Error implements Parcelable
{
private final int mHttpCode;
@Nullable
private final String mMessage;
public Error(int httpCode, @Nullable String message)
{
mHttpCode = httpCode;
mMessage = message;
}
public Error(@Nullable String message)
{
this(HttpURLConnection.HTTP_UNAVAILABLE, message);
}
protected Error(Parcel in)
{
mHttpCode = in.readInt();
mMessage = in.readString();
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(mHttpCode);
dest.writeString(mMessage);
}
@Override
public String toString()
{
return "Error{"
+ "mHttpCode=" + mHttpCode + ", mMessage='" + mMessage + '\'' + '}';
}
public static final Creator<Error> CREATOR = new Creator<>() {
@Override
public Error createFromParcel(Parcel in)
{
return new Error(in);
}
@Override
public Error[] newArray(int size)
{
return new Error[size];
}
};
}

View File

@@ -0,0 +1,131 @@
package app.organicmaps.sdk.bookmarks.data;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
// Used by JNI.
@Keep
/// @todo Review using of this class, because seems like it has no any useful purpose.
/// Just creating in JNI and assigning ..
public class FeatureId implements Parcelable
{
public static final Creator<FeatureId> CREATOR = new Creator<>() {
@Override
public FeatureId createFromParcel(Parcel in)
{
return new FeatureId(in);
}
@Override
public FeatureId[] newArray(int size)
{
return new FeatureId[size];
}
};
@NonNull
public static final FeatureId EMPTY = new FeatureId("", -1L, 0);
@NonNull
private final String mMwmName;
private final long mMwmVersion;
private final int mFeatureIndex;
@NonNull
public static FeatureId fromFeatureIdString(@NonNull String id)
{
if (TextUtils.isEmpty(id))
throw new AssertionError("Feature id string is empty");
String[] parts = id.split(":");
if (parts.length != 3)
throw new AssertionError("Wrong feature id string format");
return new FeatureId(parts[1], Long.parseLong(parts[0]), Integer.parseInt(parts[2]));
}
public FeatureId(@NonNull String mwmName, long mwmVersion, int featureIndex)
{
mMwmName = mwmName;
mMwmVersion = mwmVersion;
mFeatureIndex = featureIndex;
}
private FeatureId(Parcel in)
{
mMwmName = in.readString();
mMwmVersion = in.readLong();
mFeatureIndex = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeString(mMwmName);
dest.writeLong(mMwmVersion);
dest.writeInt(mFeatureIndex);
}
@Override
public int describeContents()
{
return 0;
}
@NonNull
public String getMwmName()
{
return mMwmName;
}
public long getMwmVersion()
{
return mMwmVersion;
}
public int getFeatureIndex()
{
return mFeatureIndex;
}
public boolean isRealId()
{
return !TextUtils.isEmpty(mMwmName) && mMwmVersion >= 0 && mFeatureIndex > 0;
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
FeatureId featureId = (FeatureId) o;
if (mMwmVersion != featureId.mMwmVersion)
return false;
if (mFeatureIndex != featureId.mFeatureIndex)
return false;
return mMwmName.equals(featureId.mMwmName);
}
@Override
public int hashCode()
{
int result = mMwmName.hashCode();
result = 31 * result + (int) (mMwmVersion ^ (mMwmVersion >>> 32));
result = 31 * result + mFeatureIndex;
return result;
}
@Override
public String toString()
{
return "FeatureId{"
+ "mMwmName='" + mMwmName + '\'' + ", mMwmVersion=" + mMwmVersion + ", mFeatureIndex=" + mFeatureIndex + '}';
}
}

View File

@@ -0,0 +1,129 @@
package app.organicmaps.sdk.bookmarks.data;
import android.content.res.Resources;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import app.organicmaps.sdk.BuildConfig;
import app.organicmaps.sdk.R;
import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.log.Logger;
import dalvik.annotation.optimization.FastNative;
import java.util.Arrays;
public class Icon implements Parcelable
{
private static final String TAG = Icon.class.getSimpleName();
@DrawableRes
private static int[] sTypeIcons = null;
@PredefinedColors.Color
private final int mColor;
private final int mType;
public Icon(@PredefinedColors.Color int color, int type)
{
mColor = color;
mType = type;
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(mColor);
dest.writeInt(mType);
}
private Icon(Parcel in)
{
mColor = in.readInt();
mType = in.readInt();
}
@PredefinedColors.Color
public int getColor()
{
return mColor;
}
@ColorInt
public int argb()
{
return PredefinedColors.getColor(mColor);
}
@DrawableRes
public int getResId()
{
// loadDefaultIcons should be called
assert (sTypeIcons != null);
return sTypeIcons[mType];
}
public int getType()
{
return mType;
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o instanceof Icon comparedIcon)
return mColor == comparedIcon.mColor && mType == comparedIcon.mType;
return false;
}
@Override
public int hashCode()
{
return Arrays.hashCode(new int[] {mColor, mType});
}
public static final Parcelable.Creator<Icon> CREATOR = new Parcelable.Creator<>() {
public Icon createFromParcel(Parcel in)
{
return new Icon(in);
}
public Icon[] newArray(int size)
{
return new Icon[size];
}
};
static public void loadDefaultIcons(@NonNull Resources resources, @NonNull String packageName)
{
final String[] names = nativeGetBookmarkIconNames();
int[] icons = new int[names.length];
for (int i = 0; i < names.length; i++)
{
final String name = StringUtils.toSnakeCase(names[i]);
icons[i] = resources.getIdentifier("ic_bookmark_" + name, "drawable", packageName);
if (icons[i] == 0)
{
Logger.e(TAG, "Error getting icon for " + name);
// Force devs to add an icon for each bookmark type.
if (BuildConfig.DEBUG)
throw new RuntimeException("Error getting icon for " + name);
icons[i] = R.drawable.ic_bookmark_none; // Fallback icon
}
}
sTypeIcons = icons;
}
@FastNative
@NonNull
private static native String[] nativeGetBookmarkIconNames();
}

View File

@@ -0,0 +1,8 @@
package app.organicmaps.sdk.bookmarks.data;
import com.google.android.material.imageview.ShapeableImageView;
public interface IconClickListener
{
void onItemClick(ShapeableImageView v, int position);
}

View File

@@ -0,0 +1,9 @@
package app.organicmaps.sdk.bookmarks.data;
// Need to be in sync with KmlFileType (map/bookmark_helpers.hpp)
public enum KmlFileType
{
Text,
Binary,
Gpx
}

View File

@@ -0,0 +1,414 @@
package app.organicmaps.sdk.bookmarks.data;
import android.net.Uri;
import android.os.Parcel;
import android.text.TextUtils;
import androidx.annotation.IntDef;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.os.ParcelCompat;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.sdk.search.Popularity;
import app.organicmaps.sdk.widget.placepage.PlacePageData;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
// TODO(yunikkk): Refactor. Displayed information is different from edited information, and it's better to
// separate them. Simple getters from jni place_page::Info and osm::EditableFeature should be enough.
// Used from JNI.
@Keep
public class MapObject implements PlacePageData
{
@Retention(RetentionPolicy.SOURCE)
@IntDef({POI, API_POINT, BOOKMARK, MY_POSITION, SEARCH, TRACK})
public @interface MapObjectType
{}
public static final int POI = 0;
public static final int API_POINT = 1;
public static final int BOOKMARK = 2;
public static final int MY_POSITION = 3;
public static final int SEARCH = 4;
public static final int TRACK = 5;
@Retention(RetentionPolicy.SOURCE)
@IntDef({OPENING_MODE_PREVIEW, OPENING_MODE_PREVIEW_PLUS, OPENING_MODE_DETAILS, OPENING_MODE_FULL})
public @interface OpeningMode
{}
public static final int OPENING_MODE_PREVIEW = 0;
public static final int OPENING_MODE_PREVIEW_PLUS = 1;
public static final int OPENING_MODE_DETAILS = 2;
public static final int OPENING_MODE_FULL = 3;
private static final String kHttp = "http://";
private static final String kHttps = "https://";
@NonNull
private final FeatureId mFeatureId;
@MapObjectType
private final int mMapObjectType;
private String mTitle;
@Nullable
private final String mSecondaryTitle;
private final String mSubtitle;
private double mLat;
private double mLon;
private final String mAddress;
@NonNull
private final Metadata mMetadata;
private final String mApiId;
private final RoutePointInfo mRoutePointInfo;
@OpeningMode
private final int mOpeningMode;
// @NonNull
// private final Popularity mPopularity;
@NonNull
private final RoadWarningMarkType mRoadWarningMarkType;
@NonNull
private String mDescription;
@Nullable
private List<String> mRawTypes;
public MapObject(@NonNull FeatureId featureId, @MapObjectType int mapObjectType, String title,
@Nullable String secondaryTitle, String subtitle, String address, double lat, double lon,
String apiId, @Nullable RoutePointInfo routePointInfo, @OpeningMode int openingMode,
Popularity popularity, @NonNull String description, int roadWarningType, @Nullable String[] rawTypes)
{
this(featureId, mapObjectType, title, secondaryTitle, subtitle, address, lat, lon, new Metadata(), apiId,
routePointInfo, openingMode, popularity, description, roadWarningType, rawTypes);
}
public MapObject(@NonNull FeatureId featureId, @MapObjectType int mapObjectType, String title,
@Nullable String secondaryTitle, String subtitle, String address, double lat, double lon,
Metadata metadata, String apiId, @Nullable RoutePointInfo routePointInfo,
@OpeningMode int openingMode, Popularity popularity, @NonNull String description,
int roadWarningType, @Nullable String[] rawTypes)
{
mFeatureId = featureId;
mMapObjectType = mapObjectType;
mTitle = title;
mSecondaryTitle = secondaryTitle;
mSubtitle = subtitle;
mAddress = address;
mLat = lat;
mLon = lon;
mMetadata = metadata != null ? metadata : new Metadata();
mApiId = apiId;
mRoutePointInfo = routePointInfo;
mOpeningMode = openingMode;
// mPopularity = popularity;
mDescription = description;
mRoadWarningMarkType = RoadWarningMarkType.values()[roadWarningType];
if (rawTypes != null)
mRawTypes = new ArrayList<>(Arrays.asList(rawTypes));
}
protected MapObject(@MapObjectType int type, Parcel source)
{
this(Objects.requireNonNull(
ParcelCompat.readParcelable(source, FeatureId.class.getClassLoader(), FeatureId.class)), // FeatureId
type, // MapObjectType
source.readString(), // Title
source.readString(), // SecondaryTitle
source.readString(), // Subtitle
source.readString(), // Address
source.readDouble(), // Lat
source.readDouble(), // Lon
ParcelCompat.readParcelable(source, Metadata.class.getClassLoader(), Metadata.class),
source.readString(), // ApiId;
ParcelCompat.readParcelable(source, RoutePointInfo.class.getClassLoader(),
RoutePointInfo.class), // RoutePointInfo
source.readInt(), // mOpeningMode
Objects.requireNonNull(
ParcelCompat.readParcelable(source, Popularity.class.getClassLoader(), Popularity.class)),
Objects.requireNonNull(source.readString()), source.readInt(),
null // mRawTypes
);
mRawTypes = readRawTypes(source);
}
@NonNull
public static MapObject createMapObject(@NonNull FeatureId featureId, @MapObjectType int mapObjectType,
@NonNull String title, @NonNull String subtitle, double lat, double lon)
{
return new MapObject(featureId, mapObjectType, title, "", subtitle, "", lat, lon, null, "", null,
OPENING_MODE_PREVIEW, Popularity.defaultInstance(), "", RoadWarningMarkType.UNKNOWN.ordinal(),
new String[0]);
}
@NonNull
private static List<String> readRawTypes(@NonNull Parcel source)
{
List<String> types = new ArrayList<>();
source.readStringList(types);
return types;
}
/**
* If you override {@link #equals(Object)} it is also required to override {@link #hashCode()}.
* MapObject does not participate in any sets or other collections that need {@code hashCode()}.
* So {@code sameAs()} serves as {@code equals()} but does not break the equals+hashCode contract.
*/
public boolean sameAs(@Nullable MapObject other)
{
if (other == null)
return false;
if (this == other)
return true;
// noinspection SimplifiableIfStatement
if (getClass() != other.getClass())
return false;
if (mFeatureId.isRealId() && other.getFeatureId().isRealId())
return mFeatureId.equals(other.getFeatureId());
return Double.doubleToLongBits(mLon) == Double.doubleToLongBits(other.mLon)
&& Double.doubleToLongBits(mLat) == Double.doubleToLongBits(other.mLat);
}
public static boolean same(@Nullable MapObject one, @Nullable MapObject another)
{
// noinspection SimplifiableIfStatement
if (one == null && another == null)
return true;
return (one != null && one.sameAs(another));
}
public double getScale()
{
return 0;
}
@NonNull
public String getTitle()
{
return mTitle;
}
public void setTitle(@NonNull String title)
{
mTitle = title;
}
@NonNull
public String getName()
{
return getTitle();
}
@Nullable
public String getSecondaryTitle()
{
return mSecondaryTitle;
}
@NonNull
public String getSubtitle()
{
return mSubtitle;
}
public double getLat()
{
return mLat;
}
public double getLon()
{
return mLon;
}
@NonNull
public String getAddress()
{
return mAddress;
}
@NonNull
public String getDescription()
{
return mDescription;
}
public void setDescription(@NonNull String description)
{
mDescription = description;
}
@NonNull
public RoadWarningMarkType getRoadWarningMarkType()
{
return mRoadWarningMarkType;
}
@NonNull
public String getMetadata(Metadata.MetadataType type)
{
final String res = mMetadata.getMetadata(type);
return res == null ? "" : res;
}
@NonNull
public String getWebsiteUrl(boolean strip, @NonNull Metadata.MetadataType type)
{
final String website = Uri.decode(getMetadata(type));
final int len = website.length();
if (strip && len > 1)
{
final int start = website.startsWith(kHttps) ? kHttps.length() : (website.startsWith(kHttp) ? kHttp.length() : 0);
final int end = website.endsWith("/") ? len - 1 : len;
return website.substring(start, end);
}
return website;
}
public String getApiId()
{
return mApiId;
}
public void setLat(double lat)
{
mLat = lat;
}
public void setLon(double lon)
{
mLon = lon;
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
public void addMetadata(int type, String value)
{
mMetadata.addMetadata(type, value);
}
public boolean hasPhoneNumber()
{
return !TextUtils.isEmpty(getMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER));
}
public boolean hasAtm()
{
return mRawTypes.contains("amenity-atm");
}
public final boolean isMyPosition()
{
return mMapObjectType == MY_POSITION;
}
public final boolean isBookmark()
{
return mMapObjectType == BOOKMARK;
}
public final boolean isTrack()
{
return mMapObjectType == TRACK;
}
@Nullable
public RoutePointInfo getRoutePointInfo()
{
return mRoutePointInfo;
}
@OpeningMode
public int getOpeningMode()
{
return mOpeningMode;
}
@NonNull
public FeatureId getFeatureId()
{
return mFeatureId;
}
private static MapObject readFromParcel(Parcel source)
{
@MapObjectType
int type = source.readInt();
if (type == BOOKMARK)
return new Bookmark(type, source);
return new MapObject(type, source);
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
// A map object type must be written first, since it's used in readParcel method to distinguish
// what type of object should be read from the parcel.
dest.writeInt(mMapObjectType);
dest.writeParcelable(mFeatureId, 0);
dest.writeString(mTitle);
dest.writeString(mSecondaryTitle);
dest.writeString(mSubtitle);
dest.writeString(mAddress);
dest.writeDouble(mLat);
dest.writeDouble(mLon);
dest.writeParcelable(mMetadata, 0);
dest.writeString(mApiId);
dest.writeParcelable(mRoutePointInfo, 0);
dest.writeInt(mOpeningMode);
// dest.writeParcelable(mPopularity, 0);
dest.writeString(mDescription);
dest.writeInt(getRoadWarningMarkType().ordinal());
// All collections are deserialized AFTER non-collection and primitive type objects,
// so collections must be always serialized at the end.
dest.writeStringList(mRawTypes);
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
MapObject mapObject = (MapObject) o;
return mFeatureId.equals(mapObject.mFeatureId);
}
@Override
public int hashCode()
{
return mFeatureId.hashCode();
}
public static final Creator<MapObject> CREATOR = new Creator<>() {
@Override
public MapObject createFromParcel(Parcel source)
{
return readFromParcel(source);
}
@Override
public MapObject[] newArray(int size)
{
return new MapObject[size];
}
};
}

View File

@@ -0,0 +1,150 @@
package app.organicmaps.sdk.bookmarks.data;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
public class Metadata implements Parcelable
{
// Values must correspond to the Metadata definition from indexer/feature_meta.hpp.
public enum MetadataType
{
// Defined by classifier types now.
FMD_CUISINE(1),
FMD_OPEN_HOURS(2),
FMD_PHONE_NUMBER(3),
FMD_FAX_NUMBER(4),
FMD_STARS(5),
FMD_OPERATOR(6),
// Removed and is not used in the core. Use FMD_WEBSITE instead.
// FMD_URL(7),
FMD_WEBSITE(8),
FMD_INTERNET(9),
FMD_ELE(10),
FMD_TURN_LANES(11),
FMD_TURN_LANES_FORWARD(12),
FMD_TURN_LANES_BACKWARD(13),
FMD_EMAIL(14),
FMD_POSTCODE(15),
// TODO: It is hacked in jni and returns full Wikipedia url. Should use separate getter instead.
FMD_WIKIPEDIA(16),
// TODO: Skipped now.
FMD_DESCRIPTION(17),
FMD_FLATS(18),
FMD_HEIGHT(19),
FMD_MIN_HEIGHT(20),
FMD_DENOMINATION(21),
FMD_BUILDING_LEVELS(22),
FWD_TEST_ID(23),
FMD_CUSTOM_IDS(24),
FMD_PRICE_RATES(25),
FMD_RATINGS(26),
FMD_EXTERNAL_URI(27),
FMD_LEVEL(28),
FMD_AIRPORT_IATA(29),
FMD_BRAND(30),
FMD_DURATION(31),
FMD_CONTACT_FACEBOOK(32),
FMD_CONTACT_INSTAGRAM(33),
FMD_CONTACT_TWITTER(34),
FMD_CONTACT_VK(35),
FMD_CONTACT_LINE(36),
FMD_DESTINATION(37),
FMD_DESTINATION_REF(38),
FMD_JUNCTION_REF(39),
FMD_BUILDING_MIN_LEVEL(40),
FMD_WIKIMEDIA_COMMONS(41),
FMD_CAPACITY(42),
FMD_WHEELCHAIR(43),
FMD_LOCAL_REF(44),
FMD_DRIVE_THROUGH(45),
FMD_WEBSITE_MENU(46),
FMD_SELF_SERVICE(47),
FMD_OUTDOOR_SEATING(48),
FMD_NETWORK(49),
FMD_CONTACT_FEDIVERSE(50),
FMD_CONTACT_BLUESKY(51),
FMD_PANORAMAX(52),
FMD_CHECK_DATE(53),
FMD_CHECK_DATE_OPEN_HOURS(54);
private final int mMetaType;
MetadataType(int metadataType)
{
mMetaType = metadataType;
}
@NonNull
public static MetadataType fromInt(@IntRange(from = 1, to = 49) int metaType)
{
for (MetadataType type : values())
if (type.mMetaType == metaType)
return type;
throw new IllegalArgumentException("Illegal metaType: " + metaType);
}
public int toInt()
{
return mMetaType;
}
}
private final Map<MetadataType, String> mMetadataMap = new HashMap<>();
public void addMetadata(int metaType, String metaValue)
{
final MetadataType type = MetadataType.fromInt(metaType);
mMetadataMap.put(type, metaValue);
}
@Nullable
String getMetadata(MetadataType type)
{
return mMetadataMap.get(type);
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(mMetadataMap.size());
for (Map.Entry<MetadataType, String> metaEntry : mMetadataMap.entrySet())
{
dest.writeInt(metaEntry.getKey().mMetaType);
dest.writeString(metaEntry.getValue());
}
}
public static Metadata readFromParcel(Parcel source)
{
final Metadata metadata = new Metadata();
final int size = source.readInt();
for (int i = 0; i < size; i++)
metadata.addMetadata(source.readInt(), source.readString());
return metadata;
}
public static final Creator<Metadata> CREATOR = new Creator<>() {
@Override
public Metadata createFromParcel(Parcel source)
{
return readFromParcel(source);
}
@Override
public Metadata[] newArray(int size)
{
return new Metadata[size];
}
};
}

Some files were not shown because too many files have changed in this diff Show More