Add action journal (#3409)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bart Louwers <bart@emeel.net>
This commit is contained in:
Adrian Cojocaru
2025-05-27 16:15:56 +03:00
committed by GitHub
parent 5ec8430fa3
commit 08eb760acd
66 changed files with 2773 additions and 75 deletions

View File

@@ -897,6 +897,49 @@ public final class MapLibreMap {
nativeMapView.setDebug(debugActive);
}
/**
* <p>
* Get the list of action journal log files from oldest to newest.
* </p>
*/
public String[] getActionJournalLogFiles() {
return nativeMapView.getActionJournalLogFiles();
}
/**
* <p>
* Get the action journal events from oldest to newest.
* </p>
* Each element contains a serialized json object with the event data.
* Example
* `{
* "name" : "onTileAction",
* "time" : "2025-04-17T13:13:13.974Z",
* "styleName" : "Streets",
* "styleURL" : "maptiler://maps/streets",
* "event" : {
* "action" : "RequestedFromNetwork",
* "tileX" : 0,
* "tileY" : 0,
* "tileZ" : 0,
* "overscaledZ" : 0,
* "sourceID" : "openmaptiles"
* }
* }`
*/
public String[] getActionJournalLog() {
return nativeMapView.getActionJournalLog();
}
/**
* <p>
* Clear stored action journal events.
* </p>
*/
public void clearActionJournalLog() {
nativeMapView.clearActionJournalLog();
}
//
// API endpoint config
//

View File

@@ -94,6 +94,11 @@ public class MapLibreMapOptions implements Parcelable {
private boolean crossSourceCollisions = true;
private boolean actionJournalEnabled = false;
private String actionJournalPath = "";
private long actionJournalLogFileSize = 1024 * 1024;
private long actionJournalLogFileCount = 5;
/**
* Creates a new MapLibreMapOptions object.
*
@@ -151,6 +156,11 @@ public class MapLibreMapOptions implements Parcelable {
pixelRatio = in.readFloat();
foregroundLoadColor = in.readInt();
crossSourceCollisions = in.readByte() != 0;
actionJournalEnabled = in.readByte() != 0;
actionJournalPath = in.readString();
actionJournalLogFileSize = in.readLong();
actionJournalLogFileCount = in.readLong();
}
/**
@@ -182,6 +192,8 @@ public class MapLibreMapOptions implements Parcelable {
@NonNull Context context,
@Nullable TypedArray typedArray) {
float pxlRatio = context.getResources().getDisplayMetrics().density;
maplibreMapOptions.actionJournalPath(context.getFilesDir().getAbsolutePath());
try {
maplibreMapOptions.camera(new CameraPosition.Builder(typedArray).build());
@@ -305,6 +317,16 @@ public class MapLibreMapOptions implements Parcelable {
maplibreMapOptions.crossSourceCollisions(
typedArray.getBoolean(R.styleable.maplibre_MapView_maplibre_cross_source_collisions, true)
);
maplibreMapOptions.actionJournalEnabled(
typedArray.getBoolean(R.styleable.maplibre_MapView_maplibre_actionJournalEnabled, false)
);
maplibreMapOptions.actionJournalLogFileSize(
typedArray.getInteger(R.styleable.maplibre_MapView_maplibre_actionJournalLogFileSize, 1024 * 1024)
);
maplibreMapOptions.actionJournalLogFileCount(
typedArray.getInteger(R.styleable.maplibre_MapView_maplibre_actionJournalLogFileCount, 5)
);
} finally {
typedArray.recycle();
}
@@ -730,6 +752,65 @@ public class MapLibreMapOptions implements Parcelable {
return this;
}
/**
* Enable action journal event logging, defaults to false.
* <p>
* If set to true, enables map event file logging (obtainable via MapView#getActionJournalLog)
* </p>
*
* @param actionJournalEnabled true to enable, false to disable
* @return This
*/
@NonNull
public MapLibreMapOptions actionJournalEnabled(boolean actionJournalEnabled) {
this.actionJournalEnabled = actionJournalEnabled;
return this;
}
/**
* Set the action journal log path.
*
* @param actionJournalPath Path to be used
* @return This
*/
@NonNull
public MapLibreMapOptions actionJournalPath(@NonNull String actionJournalPath) {
this.actionJournalPath = actionJournalPath;
return this;
}
/**
* Set the action journal log file size.
* <p>
* The action journal uses a rolling log with multiple files.
* Total log size is equal to `actionJournalLogFileSize * actionJournalLogFileCount`.
* </p>
*
* @param actionJournalLogFileSize maximum log file size
* @return This
*/
@NonNull
public MapLibreMapOptions actionJournalLogFileSize(long actionJournalLogFileSize) {
this.actionJournalLogFileSize = actionJournalLogFileSize;
return this;
}
/**
* Set the action journal log file count.
* <p>
* The action journal uses a rolling log with multiple files.
* Total log size is equal to `actionJournalLogFileSize * actionJournalLogFileCount`.
* </p>
*
* @param actionJournalLogFileCount maximum number of log files
* @return This
*/
@NonNull
public MapLibreMapOptions actionJournalLogFileCount(long actionJournalLogFileCount) {
this.actionJournalLogFileCount = actionJournalLogFileCount;
return this;
}
/**
* Enable local ideograph font family, defaults to true.
*
@@ -821,6 +902,44 @@ public class MapLibreMapOptions implements Parcelable {
return crossSourceCollisions;
}
/**
* Check whether action journal logging is enabled.
*
* @return true if enabled
*/
public boolean getActionJournalEnabled() {
return actionJournalEnabled;
}
/**
* Get the current configured action journal log path.
*
* @return log file path
*/
public String getActionJournalPath() {
return actionJournalPath;
}
/**
* Get the current configured action journal log file size.
* Total log size is equal to `actionJournalLogFileSize * actionJournalLogFileCount`.
*
* @return maximum file size
*/
public long getActionJournalLogFileSize() {
return actionJournalLogFileSize;
}
/**
* Get the current configured action journal log file count.
* Total log size is equal to `actionJournalLogFileSize * actionJournalLogFileCount`.
*
* @return maximum log files used
*/
public long getActionJournalLogFileCount() {
return actionJournalLogFileCount;
}
/**
* Set the flag to render the map surface on top of another surface.
*
@@ -1205,6 +1324,11 @@ public class MapLibreMapOptions implements Parcelable {
dest.writeFloat(pixelRatio);
dest.writeInt(foregroundLoadColor);
dest.writeByte((byte) (crossSourceCollisions ? 1 : 0));
dest.writeByte((byte) (actionJournalEnabled ? 1 : 0));
dest.writeString(actionJournalPath);
dest.writeLong(actionJournalLogFileSize);
dest.writeLong(actionJournalLogFileCount);
}
@Override
@@ -1325,6 +1449,22 @@ public class MapLibreMapOptions implements Parcelable {
return false;
}
if (actionJournalEnabled != options.actionJournalEnabled) {
return false;
}
if (actionJournalPath.equals(options.actionJournalPath)) {
return false;
}
if (actionJournalLogFileSize != options.actionJournalLogFileSize) {
return false;
}
if (actionJournalLogFileCount != options.actionJournalLogFileCount) {
return false;
}
return false;
}
@@ -1372,6 +1512,10 @@ public class MapLibreMapOptions implements Parcelable {
result = 31 * result + Arrays.hashCode(localIdeographFontFamilies);
result = 31 * result + (int) pixelRatio;
result = 31 * result + (crossSourceCollisions ? 1 : 0);
result = 31 * result + (actionJournalEnabled ? 1 : 0);
result = 31 * result + (actionJournalPath != null ? actionJournalPath.hashCode() : 0);
result = 31 * result + (int) actionJournalLogFileSize;
result = 31 * result + (int) actionJournalLogFileCount;
return result;
}
}

View File

@@ -306,15 +306,13 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback {
}
private void initializeDrawingSurface(MapLibreMapOptions options) {
mapRenderer = MapRenderer.create(options, getContext(), () -> MapView.this.onSurfaceCreated());
mapRenderer = MapRenderer.create(options, getContext(), MapView.this::onSurfaceCreated);
renderView = mapRenderer.getView();
addView(renderView, 0);
boolean crossSourceCollisions = options.getCrossSourceCollisions();
nativeMapView = new NativeMapView(
getContext(), getPixelRatio(), crossSourceCollisions, this, mapChangeReceiver, mapRenderer
);
options.pixelRatio(getPixelRatio());
nativeMapView = new NativeMapView(getContext(), options, this, mapChangeReceiver, mapRenderer);
}
private void onSurfaceCreated() {

View File

@@ -221,6 +221,12 @@ interface NativeMap {
boolean getDebug();
String[] getActionJournalLogFiles();
String[] getActionJournalLog();
void clearActionJournalLog();
void setReachability(boolean status);
void setApiBaseUrl(String baseUrl);

View File

@@ -0,0 +1,56 @@
package org.maplibre.android.maps;
public class NativeMapOptions {
private final float pixelRatio;
private final boolean crossSourceCollisions;
private final boolean actionJournalEnabled;
private final String actionJournalPath;
private final long actionJournalLogFileSize;
private final long actionJournalLogFileCount;
public NativeMapOptions(MapLibreMapOptions options) {
pixelRatio = options.getPixelRatio();
crossSourceCollisions = options.getCrossSourceCollisions();
actionJournalEnabled = options.getActionJournalEnabled();
actionJournalPath = options.getActionJournalPath();
actionJournalLogFileSize = options.getActionJournalLogFileSize();
actionJournalLogFileCount = options.getActionJournalLogFileCount();
}
public NativeMapOptions(float pixelRatio, boolean crossSourceCollisions) {
this.pixelRatio = pixelRatio;
this.crossSourceCollisions = crossSourceCollisions;
actionJournalEnabled = false;
actionJournalPath = "";
actionJournalLogFileSize = 0;
actionJournalLogFileCount = 0;
}
public float pixelRatio() {
return pixelRatio;
}
public boolean crossSourceCollisions() {
return crossSourceCollisions;
}
public boolean actionJournalEnabled() {
return actionJournalEnabled;
}
public String actionJournalPath() {
return actionJournalPath;
}
public long actionJournalLogFileSize() {
return actionJournalLogFileSize;
}
public long actionJournalLogFileCount() {
return actionJournalLogFileCount;
}
}

View File

@@ -91,23 +91,29 @@ final class NativeMapView implements NativeMap {
// Constructors
//
public NativeMapView(@NonNull final Context context, final boolean crossSourceCollisions,
public NativeMapView(@NonNull final Context context,
final ViewCallback viewCallback, final StateCallback stateCallback,
final MapRenderer mapRenderer) {
this(context, context.getResources().getDisplayMetrics().density, crossSourceCollisions, viewCallback,
stateCallback, mapRenderer);
this(context, new NativeMapOptions(context.getResources().getDisplayMetrics().density, false),
viewCallback, stateCallback, mapRenderer);
}
public NativeMapView(final Context context, final float pixelRatio, final boolean crossSourceCollisions,
public NativeMapView(@NonNull final Context context, final MapLibreMapOptions options,
final ViewCallback viewCallback, final StateCallback stateCallback,
final MapRenderer mapRenderer) {
this(context, new NativeMapOptions(options), viewCallback, stateCallback, mapRenderer);
}
public NativeMapView(@NonNull final Context context, final NativeMapOptions nativeOptions,
final ViewCallback viewCallback, final StateCallback stateCallback,
final MapRenderer mapRenderer) {
this.mapRenderer = mapRenderer;
this.viewCallback = viewCallback;
this.fileSource = FileSource.getInstance(context);
this.pixelRatio = pixelRatio;
this.pixelRatio = nativeOptions.pixelRatio();
this.thread = Thread.currentThread();
this.stateCallback = stateCallback;
nativeInitialize(this, fileSource, mapRenderer, pixelRatio, crossSourceCollisions);
nativeInitialize(this, fileSource, mapRenderer, nativeOptions);
}
//
@@ -646,6 +652,30 @@ final class NativeMapView implements NativeMap {
return nativeGetDebug();
}
@Override
public String[] getActionJournalLogFiles() {
if (checkState("getActionJournalLogFiles")) {
return null;
}
return nativeGetActionJournalLogFiles();
}
@Override
public String[] getActionJournalLog() {
if (checkState("getActionJournalLog")) {
return null;
}
return nativeGetActionJournalLog();
}
@Override
public void clearActionJournalLog() {
if (checkState("clearActionJournalLog")) {
return;
}
nativeClearActionJournalLog();
}
@Override
public boolean isFullyLoaded() {
if (checkState("isFullyLoaded")) {
@@ -1275,8 +1305,7 @@ final class NativeMapView implements NativeMap {
private native void nativeInitialize(NativeMapView nativeMap,
FileSource fileSource,
MapRenderer mapRenderer,
float pixelRatio,
boolean crossSourceCollisions);
NativeMapOptions nativeOptions);
@Keep
private native void nativeDestroy();
@@ -1429,6 +1458,15 @@ final class NativeMapView implements NativeMap {
@Keep
private native boolean nativeGetDebug();
@Keep
private native String[] nativeGetActionJournalLogFiles();
@Keep
private native String[] nativeGetActionJournalLog();
@Keep
private native void nativeClearActionJournalLog();
@Keep
private native boolean nativeIsFullyLoaded();