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:
@@ -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
|
||||
//
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -221,6 +221,12 @@ interface NativeMap {
|
||||
|
||||
boolean getDebug();
|
||||
|
||||
String[] getActionJournalLogFiles();
|
||||
|
||||
String[] getActionJournalLog();
|
||||
|
||||
void clearActionJournalLog();
|
||||
|
||||
void setReachability(boolean status);
|
||||
|
||||
void setApiBaseUrl(String baseUrl);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user