DittoAndroidTools are diagnostic tools for Ditto. You can view connected peers, export debug logs, browse collections/documents and see Ditto's disk usage/ export this data.
These tools are available via Maven Central.
For support, please contact Ditto Support ([email protected]).
- Android 8.0+
- Jetpack Compose
Ditto tools are released via Maven Central. Be sure to include it in your list of repositories.
repositories {
mavenCentral()
}
Include the tools repository:
dependencies {
implementation 'live.ditto:ditto-tools-android:LIBRARY_VERSION'
}
You can find the list of versions and release notes in the Releases tab.
Note: The tools used to be released as individual Maven artefacts but have now been moved into a single module, and are released as such.
All tools require an initialized instance of Ditto to work. For example, with the Online Playground identity:
val androidDependencies = DefaultAndroidDittoDependencies(applicationContext)
val identity = DittoIdentity.OnlinePlayground(androidDependencies, appId = "YOUR_APPID", token = "YOUR_TOKEN", enableDittoCloudSync = true)
ditto = Ditto(androidDependencies, identity)
DittoLogger.minimumLogLevel = DittoLogLevel.DEBUG
ditto.startSync()
Tools viewer is the easiest way to integrate all the tools currently available. It provides a single entry point to interact with all other tools, and includes them as a dependency.
It is available as a Composable element that requires a Ditto instance. Optional parameters include:
modifier
: If you need to adjust the layoutonExitTools
: Lambda function that will be called when the "Exit Tools" button is tapped. Use this to do any back navigation or dismissal of the tools composable if you need to.
Example code:
import live.ditto.tools.DittoToolsViewer
// minimum code required to get started
DittoToolsViewer(
ditto = YOUR_DITTO_INSTANCE
)
To integrate it in a Views-based app - see instructions here: https://developer.android.com/develop/ui/compose/migrate/interoperability-apis/compose-in-views
The Presence Viewer displays a mesh graph that allows you to see all connected peers within the mesh and the transport that each peer is using to make a connection.
Within a Composable, you pass ditto to the constructor:
DittoPresenceViewer(ditto = ditto)
The Ditto Data Browser allows you to view all your collections, documents within each collection and the propeties/values of a document. With the Data Browser, you can observe any changes that are made to your collections and documents in real time.
Within a Composable function, you pass ditto to the constructor:
DittoDataBrowser(ditto = ditto)
Standalone App
If you are using the Data Browser as a standalone app, there is a button, Start Subscriptions, you must press in order to start syncing data. If you are embedding the Data Browser into another application then you do not need to press Start Subscriptions as you should already have your subscriptions running.
Export Logs allows you to export logs from your application into a file.
Include ExportLogs()
in your Composable function. You can pass in a lambda function to be called when the dialog is dismissed.
ExportLogs(onDismiss: () -> Unit)
Disk Usage allows you to see Ditto's file space usage.
Export Data allows you to export the Ditto directory.
DittoDiskUsage(ditto = ditto)
Health allows you to see the status of Ditto's services.
Example: WiFi/Bluetooth state/permissions, device capabilities
The default implementation is a Composable that displays all facets of information.
HealthScreen()
This Composable also takes in an optional list of enum
's if you need to show/hide certain groups of information. Current valid enums are:
TRANSPORT_HEALTH -- shows WiFi/Bluetooth status (enabled/disabled, permissions state)
WIFI_AWARE_STATE -- displays whether the device supports WiFi Aware
The Ditto Heartbeat tool allows you to monitor, locally or remotely, the peers in your mesh.
Configure Heartbeat
These are the values you need to provide to the Heartbeat:
id
- Unique value that identifies the devicesecondsInterval
- The frequency at which the Heartbeat will scrape the datametaData
- Optional - any metadata you wish to add to the HeartbeathealthMetricProviders
List of HealthMetricProviderspublishToDittoCollection
- Optional - set to false to prevent from publishing the heartbeat to Ditto collection. Default true.
Available healthMetricProviders
:
- HealthViewModel() - health metrics for Permissions Health Tool
- DiskUsageViewModel() - health metrics for Ditto disk usage.
isHealthy
is determined by the size of theditto_store
andditto_replication
folders. The default isHealthy size is 2GB, but this can be configured.
There is a DittoHeartbeatConfig
data class you can use to construct your configuration.
// Provided with the Heartbeat tool
data class DittoHeartbeatConfig(
val id: String,
val secondsInterval: Int,
val metaData: Map<String, Any>? = null,
val healthMetricProviders: List<HealthMetricProvider>?,
val publishToDittoCollection: Boolean = true // Toggle to avoid publishing
)
// Example:
// User defines the values here
// Passed into Heartbeat tool
var healthMetricProviders: MutableList<HealthMetricProvider> = mutableListOf()
val diskUsageViewModel = DiskUsageViewModel()
diskUsageViewModel.isHealthyMBSizeLimit = 2048 //2GB worth of data
healthMetricProviders.add(diskUsageViewModel)
val config = DittoHeartbeatConfig(
id = <unique device id>,
secondsInterval = 30, //seconds
metaData = mapOf(
"deviceType" to "KDS"
),
healthMetricProviders = healthMetricProviders,
publishToDittoCollection = true
)
// Provide the config and your Ditto instance to startHearbeat()
startHeartbeat(ditto, config).collect { heartbeatInfo = it }
User Interface
You will need to provide your own UI. You can see an example here.
There are two ways you can access the data:
- The Ditto collection you provided
- startHeartBeat() provides a callback with the data
Ditto Collection:
This is the model of the data and what you can use for reference
{
_id: <ditto peerKeyString>,
_schema: String,
secondsInterval: String,
presenceSnapshotDirectlyConnectedPeersCount: Int,
lastUpdated: String (ISO-8601),
sdk: String,
presenceSnapshotDirectlyConnectedPeers: {
<peerKeyString>: {
deviceName: String,
sdk: String,
isConnectedToDittoCloud: Bool,
bluetooth: Int,
p2pWifi: Int,
lan: Int,
},
<peerKeyString>…,
…
},
metaData: {},
healthMetrics: {},
}
Callback:
You will receive a HeartbeatInfo
data class back
data class DittoHeartbeatInfo(
val id: String,
val schema: String,
val lastUpdated: String,
val metaData: Map<String, Any>?,
val secondsInterval: Int,
val presenceSnapshotDirectlyConnectedPeersCount: Int,
val presenceSnapshotDirectlyConnectedPeers: Map<String, Any>,
val sdk: String,
var healthMetrics: MutableMap<String, HealthMetric> = mutableMapOf()
)
Tracks the status of your mesh, allowing to define the minimum of required peers that needs to be connected. Exposes an API to notify when the condition of minimum required peers is not met.
PresenceDegradationReporterScreen(ditto = ditto)
ditto.presenceDegradationReporterFlow().collect { state: PresenceDegradationReporterApiState ->
// state.settings
// state.localPeer
// state.remotePeers
}
If you are not using all the tools, you can use the built-in R8 shrinker to remove unused code. This will reduce the size of the app. You will need to configure Proguard to ensure the underlying Ditto SDK is not removed.
# proguard-rules.pro
# --- Ditto SDK rules ---
# Selective package definition will allow shrinking of all code in live.ditto.tools and its subpackages.
-keepnames class com.fasterxml.jackson.** { *; }
-keep class live.ditto.* { *; }
-keep class live.ditto.transports.** { *; }
-keep class live.ditto.internal.** { *; }
# --- End Ditto SDK rules ---
# --- Ditto Tools names ---
# The following can be removed to obfuscate tools code further.
-keepnames class live.ditto.tools.** { *; }
# --- End Ditto Tools names ---
There are two ways you can test things locally. Either in the demo app, or in an external project.
To run the demo app locally, get valid playground Ditto instance credentials and store them in local.properties
file. You can find both the app ID and token in the Ditto Portal
ditto.onlinePlayground.appId="YOUR_APPID"
ditto.onlinePlayground.token="YOUR_TOKEN"
To test your changes to a module in the demo app, make sure to import the local module in app/build.gradle
dependencies section:
add: implementation(project(":AndroidDittoTools"))
remove/comment out: implementation libs.live.ditto.ditto-tools-android
- Run
./gradlew publishToMavenLocal
- In your external project add the
mavenLocal()
entry to your list of repository sources - When importing a tool, the version will be
SNAPSHOT
MIT