Skip to content

Commit

Permalink
Release 1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
d3ce1t committed Jan 18, 2023
1 parent 8323661 commit eb0defe
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 34 deletions.
31 changes: 18 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ Please request your ```TrackingplanId``` at <a href='https://www.trackingplan.co

## Add Trackingplan to your Android app

The recommended way to install Trackingplan for Android is by using Android Studio. Please, make sure your project targets API level 24 (Nougat) or later.
The recommended way to install Trackingplan for Android is by using Android Studio. Please, make sure your project targets API level 24 (Lollipop) or later.

First, add the Trackingplan dependency using Android Studio, like so:

In Android Studio, expand the `Gradle Scripts` section

![image](https://user-images.githubusercontent.com/3706385/126515536-1d2e2775-d3ae-4d80-be15-3127328db89e.png)

Select the `project-level build.gradle` file and add `com.trackingplan.client:adapter:1.3.0` as a classpath dependency to the dependencies section:
Select the `project-level build.gradle` file and add `com.trackingplan.client:adapter:1.4.0` as a classpath dependency to the dependencies section:

```gradle
dependencies {
// ...
classpath "com.trackingplan.client:adapter:1.3.0"
classpath "com.trackingplan.client:adapter:1.4.0"
// ...
}
```
Expand All @@ -54,11 +54,11 @@ plugins {
}
```

- Add `implementation 'com.trackingplan.client:sdk:1.3.0'` to the dependencies section.
- Add `implementation 'com.trackingplan.client:sdk:1.4.0'` to the dependencies section.
```gradle
dependencies {
// ...
implementation 'com.trackingplan.client:sdk:1.3.0'
implementation 'com.trackingplan.client:sdk:1.4.0'
// ...
}
```
Expand All @@ -84,21 +84,26 @@ Trackingplan for Android supports the following `advanced options` during its in

| Parameter | Description | Default |
| ----------|-------------|---------------|
| `environment(value)` | Allows to isolate the data between production and testing environments. | `PRODUCTION` |
| `sourceAlias(value)` | Allows to differentiate between sources. | `android` |
| `customDomains(map)` | Allows to extend the list of monitored domains. Any request made to these domains will also be forwarded to Trackingplan. The `map argument` must be a `key-value` with the domain to be looked for and the alias you want to use for that analytics domain. | `empty map` |
| `enableDebug()` | Enables debug mode. Prints debug information in the console. | `disabled` |
| `environment(value)` | Allows to isolate the data between production and testing environments. | `PRODUCTION` |
| `dryRun()` | Enables dry run mode. Do not send intercepted requests to Trackingplan. | `disabled` |
| `customDomains(map)` | Allows to extend the list of monitored domains. Any request made to these domains will also be forwarded to Trackingplan. The `map argument` must be a `key-value` with the domain to be looked for and the alias you want to use for that analytics domain. | `empty map` |
| `sourceAlias(value)` | Allows to differentiate between sources. | `android` |
| `tags(map)` | Allows to tag the data sent to Trackingplan. The `map argument` must be a `key-value` with the tag name and the tag value. | `empty map`


### Example

```java
Trackingplan.init("YOUR_TP_ID")
.environment("development")
.sourceAlias("my_application")
.customDomains(new HashMap<>(){{
put("my.domain.com", "myanalytics");
}})
// .tags(new HashMap<>(){{
// put("tag1", "value1");
// }})
// .customDomains(new HashMap<>(){{
// put("my.domain.com", "myanalytics");
// }})
// .enableDebug()
// .dryRun()
.start(this)
Expand Down Expand Up @@ -154,12 +159,12 @@ buildTypes {

Trackingplan for Android supports running as part of your instrumented tests. This way, existing tests can be used to catch analytics data problems before they get into production. In order to do so, follow the steps below:

1. Add `com.trackingplan.client:junit-tools:1.3.0` as a `androidTestImplementation` dependency to the dependencies section of your module-level `build.gradle` file:
1. Add `com.trackingplan.client:junit-tools:1.4.0` as a `androidTestImplementation` dependency to the dependencies section of your module-level `build.gradle` file:

```gradle
dependencies {
// ...
androidTestImplementation "com.trackingplan.client:junit-tools:1.3.0"
androidTestImplementation "com.trackingplan.client:junit-tools:1.4.0"
// ...
}
```
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {

ext {
groupId = 'com.trackingplan.client'
TrackingplanVersion = "1.2.0-SNAPSHOT"
TrackingplanVersion = "1.4.0-SNAPSHOT"
}

task clean(type: Delete) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ protected void onCreate(Bundle savedInstanceState) {
Trackingplan.init("YOUR_TP_ID")
// .environment("PRODUCTION")
// .sourceAlias("Android Example")
// .customDomains(customDomains)
// .tags(YOUR_TAGS)
// .customDomains(YOUR_CUSTOM_DOMAINS)
.enableDebug()
.dryRun()
.start(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ public ConfigInitializer customDomains(@NonNull Map<String, String> customDomain
return this;
}

@SuppressWarnings("unused")
public ConfigInitializer tags(@NonNull Map<String, String> tags) {
configBuilder.tags(tags);
return this;
}

@SuppressWarnings("unused")
public ConfigInitializer tracksEndPoint(@NonNull String endPoint) {
configBuilder.tracksEndPoint(endPoint);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) 2021 Trackingplan
package com.trackingplan.client.sdk;

import android.content.Context;

import androidx.annotation.NonNull;

import com.trackingplan.client.sdk.delivery.TrackBuilder;
Expand Down Expand Up @@ -32,9 +34,9 @@ final public class TrackingplanClient {
private final TrackingplanConfig config;
private final TrackBuilder builder;

public TrackingplanClient(@NonNull TrackingplanConfig config) {
public TrackingplanClient(@NonNull TrackingplanConfig config, @NonNull final Context context) {
this.config = config;
this.builder = new TrackBuilder(config);
this.builder = new TrackBuilder(config, context);
}

public float getSamplingRate() throws IOException, JSONException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ final public class TrackingplanConfig {
private String environment;
private String sourceAlias;
private final Map<String, String> customDomains = new HashMap<>();
private final Map<String, String> tags = new HashMap<>();

private boolean ignoreContext;
private boolean debug;
Expand Down Expand Up @@ -78,6 +79,11 @@ public Map<String, String> customDomains() {
return Collections.unmodifiableMap(customDomains);
}

@NonNull
public Map<String, String> tags() {
return Collections.unmodifiableMap(tags);
}

@NonNull
public String getTracksEndPoint() {
return tracksEndPoint;
Expand Down Expand Up @@ -106,18 +112,22 @@ public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TrackingplanConfig that = (TrackingplanConfig) o;
return ignoreContext == that.ignoreContext
return configEndPoint.equals(that.configEndPoint)
&& customDomains.equals(that.customDomains)
&& debug == that.debug
&& dryRun == that.dryRun
&& tpId.equals(that.tpId)
&& environment.equals(that.environment)
&& sourceAlias.equals(that.sourceAlias)
&& customDomains.equals(that.customDomains);
&& ignoreContext == that.ignoreContext
&& tags.equals(that.tags)
&& tpId.equals(that.tpId)
&& tracksEndPoint.equals(that.tracksEndPoint)
&& sourceAlias.equals(that.sourceAlias);
}

@Override
public int hashCode() {
return Objects.hash(tpId, environment, sourceAlias, customDomains, ignoreContext, debug, dryRun);
return Objects.hash(configEndPoint, customDomains, debug, dryRun, environment, ignoreContext,
tags, tpId, tracksEndPoint, sourceAlias);
}

static class Builder {
Expand Down Expand Up @@ -156,6 +166,11 @@ public void customDomains(@NonNull Map<String, String> customDomains) {
config.customDomains.putAll(customDomains);
}

public void tags(@NonNull Map<String, String> tags) {
config.tags.clear();
config.tags.putAll(tags);
}

public void tracksEndPoint(@NonNull String tracksEndPoint) {
config.tracksEndPoint = endPointInput(tracksEndPoint);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ void setConfig(@NonNull TrackingplanConfig config) {

taskRunner = new TaskRunner(this.handler);

client = new TrackingplanClient(config);
client = new TrackingplanClient(config, context);

SessionData sessionData = SessionDataStorage.load(config.getTpId(), context);
if (!SessionDataStorage.hasExpired(sessionData)) {
Expand Down Expand Up @@ -283,7 +283,7 @@ private void flushQueue(long timeout) {
requestQueue.processQueue(currentSessionData.getSamplingRate(), true, lock::countDown);
});
try {
if (Thread.currentThread() != handlerThread) {
if (Thread.currentThread() != handlerThread && timeout > 0) {
var counterReachedZero = lock.await(timeout, TimeUnit.MILLISECONDS);
if (!counterReachedZero) {
logger.debug("Queue flushing took longer than 10 seconds (timeout)");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright (c) 2021 Trackingplan
package com.trackingplan.client.sdk.delivery;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Base64;

Expand Down Expand Up @@ -29,9 +32,11 @@ final public class TrackBuilder {
private static final AndroidLogger logger = AndroidLogger.getInstance();

private final TrackingplanConfig config;
private final String appVersion;

public TrackBuilder(@NonNull TrackingplanConfig config) {
public TrackBuilder(@NonNull TrackingplanConfig config, @NonNull final Context context) {
this.config = config;
this.appVersion = getAppVersion(context);
}

public JSONArray createJsonPayload(List<HttpRequest> requests, float samplingRate) throws JSONException {
Expand All @@ -43,7 +48,7 @@ public JSONArray createJsonPayload(List<HttpRequest> requests, float samplingRat
payload.put(createRawTrack(request, samplingRate));
} catch (JSONException e) {
logger.warn("Cannot convert request to raw track: " + e.getMessage());
logger.info("Request information: " + request.toString());
logger.info("Request information: " + request);
}
}

Expand All @@ -59,33 +64,37 @@ private JSONObject createRawTrack(HttpRequest request, float samplingRate) throw
String device = Build.MANUFACTURER + " " + Build.MODEL;
String platform = "Android " + Build.VERSION.RELEASE + " (API " + Build.VERSION.SDK_INT + ")";

JSONObject rawTrack = new JSONObject();
var rawTrack = new JSONObject();

rawTrack.put("provider", request.getProvider());

JSONObject requestJson = new JSONObject();
if (config.tags().size() > 0) {
rawTrack.put("tags", getTagsAsJson(config.tags()));
}

var requestJson = new JSONObject();
rawTrack.put("request", requestJson);
requestJson.put("endpoint", request.getUrl());
requestJson.put("method", request.getMethod());
parsePayload(request, requestJson);

requestJson.put("response_code", request.getResponseCode());

JSONObject context = new JSONObject();
var context = new JSONObject();
rawTrack.put("context", context);

// Always include app_version in the context even when context should be ignored as
// core features rely on this field.
context.put("app_version", appVersion);

if (!config.ignoreContext()) {
// TODO: App name
// TODO: App version
// TODO: App instance id
context.put("device", device);
context.put("platform", platform);
for (Map.Entry<String, String> entry : request.getContext().entrySet()) {
context.put(entry.getKey(), entry.getValue());
}
}

rawTrack.put("context", context);

rawTrack.put("tp_id", config.getTpId());
rawTrack.put("source_alias", config.getSourceAlias());
rawTrack.put("environment", config.getEnvironment());
Expand All @@ -97,6 +106,25 @@ private JSONObject createRawTrack(HttpRequest request, float samplingRate) throw
return rawTrack;
}

private static JSONObject getTagsAsJson(Map<String, String> tags) throws JSONException {
var tagsJson = new JSONObject();

for (var tag : tags.entrySet()) {
tagsJson.put(tag.getKey(), tag.getValue());
}

return tagsJson;
}

private @NonNull String getAppVersion(Context context) {
try {
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
return "Unknown";
}
}

private void parsePayload(HttpRequest request, JSONObject requestJson) throws JSONException {

byte[] payload = request.getPayloadData();
Expand Down

0 comments on commit eb0defe

Please sign in to comment.