1 //
2 //  PackageBuilder.java
3 //  Adjust
4 //
5 //  Created by Christian Wellenbrock on 2013-06-25.
6 //  Copyright (c) 2013 adjust GmbH. All rights reserved.
7 //  See the file MIT-LICENSE for copying permission.
8 //
9 
10 package com.adjust.sdk;
11 
12 import android.text.TextUtils;
13 
14 import org.json.JSONObject;
15 
16 import java.util.HashMap;
17 import java.util.Locale;
18 import java.util.Map;
19 
20 class PackageBuilder {
21     private AdjustConfig adjustConfig;
22     private DeviceInfo deviceInfo;
23     private ActivityState activityState;
24     private long createdAt;
25 
26     // reattributions
27     Map<String, String> extraParameters;
28     AdjustAttribution attribution;
29     String reftag;
30 
31     private static ILogger logger = AdjustFactory.getLogger();
32 
PackageBuilder(AdjustConfig adjustConfig, DeviceInfo deviceInfo, ActivityState activityState, long createdAt)33     public PackageBuilder(AdjustConfig adjustConfig,
34                           DeviceInfo deviceInfo,
35                           ActivityState activityState,
36                           long createdAt) {
37         this.adjustConfig = adjustConfig;
38         this.deviceInfo = deviceInfo;
39         this.activityState = activityState.clone();
40         this.createdAt = createdAt;
41     }
42 
buildSessionPackage()43     public ActivityPackage buildSessionPackage() {
44         Map<String, String> parameters = getDefaultParameters();
45         addDuration(parameters, "last_interval", activityState.lastInterval);
46         addString(parameters, "default_tracker", adjustConfig.defaultTracker);
47 
48         ActivityPackage sessionPackage = getDefaultActivityPackage();
49         sessionPackage.setPath("/session");
50         sessionPackage.setActivityKind(ActivityKind.SESSION);
51         sessionPackage.setSuffix("");
52         sessionPackage.setParameters(parameters);
53 
54         return sessionPackage;
55     }
56 
buildEventPackage(AdjustEvent event)57     public ActivityPackage buildEventPackage(AdjustEvent event) {
58         Map<String, String> parameters = getDefaultParameters();
59         addInt(parameters, "event_count", activityState.eventCount);
60         addString(parameters, "event_token", event.eventToken);
61         addDouble(parameters, "revenue", event.revenue);
62         addString(parameters, "currency", event.currency);
63         addMapJson(parameters, "callback_params", event.callbackParameters);
64         addMapJson(parameters, "partner_params", event.partnerParameters);
65 
66         ActivityPackage eventPackage = getDefaultActivityPackage();
67         eventPackage.setPath("/event");
68         eventPackage.setActivityKind(ActivityKind.EVENT);
69         eventPackage.setSuffix(getEventSuffix(event));
70         eventPackage.setParameters(parameters);
71 
72         return eventPackage;
73     }
74 
buildClickPackage(String source, long clickTime)75     public ActivityPackage buildClickPackage(String source, long clickTime) {
76         Map<String, String> parameters = getDefaultParameters();
77 
78         addString(parameters, "source", source);
79         addDate(parameters, "click_time", clickTime);
80         addString(parameters, "reftag", reftag);
81         addMapJson(parameters, "params", extraParameters);
82         injectAttribution(parameters);
83 
84         ActivityPackage clickPackage = getDefaultActivityPackage();
85         clickPackage.setPath("/sdk_click");
86         clickPackage.setActivityKind(ActivityKind.CLICK);
87         clickPackage.setSuffix("");
88         clickPackage.setParameters(parameters);
89 
90         return clickPackage;
91     }
92 
buildAttributionPackage()93     public ActivityPackage buildAttributionPackage() {
94         Map<String, String> parameters = getIdsParameters();
95 
96         ActivityPackage attributionPackage = getDefaultActivityPackage();
97         attributionPackage.setPath("attribution"); // does not contain '/' because of Uri.Builder.appendPath
98         attributionPackage.setActivityKind(ActivityKind.ATTRIBUTION);
99         attributionPackage.setSuffix("");
100         attributionPackage.setParameters(parameters);
101 
102         return attributionPackage;
103     }
104 
getDefaultActivityPackage()105     private ActivityPackage getDefaultActivityPackage() {
106         ActivityPackage activityPackage = new ActivityPackage();
107         activityPackage.setClientSdk(deviceInfo.clientSdk);
108         return activityPackage;
109     }
110 
getDefaultParameters()111     private Map<String, String> getDefaultParameters() {
112         Map<String, String> parameters = new HashMap<String, String>();
113 
114         injectDeviceInfo(parameters);
115         injectConfig(parameters);
116         injectActivityState(parameters);
117         addDate(parameters, "created_at", createdAt);
118 
119         // general
120         checkDeviceIds(parameters);
121 
122         return parameters;
123     }
124 
getIdsParameters()125     private Map<String, String> getIdsParameters() {
126         Map<String, String> parameters = new HashMap<String, String>();
127 
128         injectDeviceInfoIds(parameters);
129         injectConfig(parameters);
130         injectActivityStateIds(parameters);
131 
132         checkDeviceIds(parameters);
133 
134         return parameters;
135     }
136 
injectDeviceInfo(Map<String, String> parameters)137     private void injectDeviceInfo(Map<String, String> parameters) {
138         injectDeviceInfoIds(parameters);
139         addString(parameters, "fb_id", deviceInfo.fbAttributionId);
140         addString(parameters, "package_name", deviceInfo.packageName);
141         addString(parameters, "app_version", deviceInfo.appVersion);
142         addString(parameters, "device_type", deviceInfo.deviceType);
143         addString(parameters, "device_name", deviceInfo.deviceName);
144         addString(parameters, "device_manufacturer", deviceInfo.deviceManufacturer);
145         addString(parameters, "os_name", deviceInfo.osName);
146         addString(parameters, "os_version", deviceInfo.osVersion);
147         addString(parameters, "language", deviceInfo.language);
148         addString(parameters, "country", deviceInfo.country);
149         addString(parameters, "screen_size", deviceInfo.screenSize);
150         addString(parameters, "screen_format", deviceInfo.screenFormat);
151         addString(parameters, "screen_density", deviceInfo.screenDensity);
152         addString(parameters, "display_width", deviceInfo.displayWidth);
153         addString(parameters, "display_height", deviceInfo.displayHeight);
154         fillPluginKeys(parameters);
155     }
156 
injectDeviceInfoIds(Map<String, String> parameters)157     private void injectDeviceInfoIds(Map<String, String> parameters) {
158         addString(parameters, "mac_sha1", deviceInfo.macSha1);
159         addString(parameters, "mac_md5", deviceInfo.macShortMd5);
160         addString(parameters, "android_id", deviceInfo.androidId);
161     }
162 
injectConfig(Map<String, String> parameters)163     private void injectConfig(Map<String, String> parameters) {
164         addString(parameters, "app_token", adjustConfig.appToken);
165         addString(parameters, "environment", adjustConfig.environment);
166         addBoolean(parameters, "device_known", adjustConfig.knownDevice);
167         addBoolean(parameters, "needs_attribution_data", adjustConfig.hasListener());
168 
169         String playAdId = Util.getPlayAdId(adjustConfig.context);
170         addString(parameters, "gps_adid", playAdId);
171         Boolean isTrackingEnabled = Util.isPlayTrackingEnabled(adjustConfig.context);
172         addBoolean(parameters, "tracking_enabled", isTrackingEnabled);
173     }
174 
injectActivityState(Map<String, String> parameters)175     private void injectActivityState(Map<String, String> parameters) {
176         injectActivityStateIds(parameters);
177         addInt(parameters, "session_count", activityState.sessionCount);
178         addInt(parameters, "subsession_count", activityState.subsessionCount);
179         addDuration(parameters, "session_length", activityState.sessionLength);
180         addDuration(parameters, "time_spent", activityState.timeSpent);
181     }
182 
injectActivityStateIds(Map<String, String> parameters)183     private void injectActivityStateIds(Map<String, String> parameters) {
184         addString(parameters, "android_uuid", activityState.uuid);
185     }
186 
injectAttribution(Map<String, String> parameters)187     private void injectAttribution(Map<String, String> parameters) {
188         if (attribution == null) {
189             return;
190         }
191         addString(parameters, "tracker", attribution.trackerName);
192         addString(parameters, "campaign", attribution.campaign);
193         addString(parameters, "adgroup", attribution.adgroup);
194         addString(parameters, "creative", attribution.creative);
195     }
196 
checkDeviceIds(Map<String, String> parameters)197     private void checkDeviceIds(Map<String, String> parameters) {
198         if (!parameters.containsKey("mac_sha1")
199                 && !parameters.containsKey("mac_md5")
200                 && !parameters.containsKey("android_id")
201                 && !parameters.containsKey("gps_adid")) {
202             logger.error("Missing device id's. Please check if Proguard is correctly set with Adjust SDK");
203         }
204     }
205 
fillPluginKeys(Map<String, String> parameters)206     private void fillPluginKeys(Map<String, String> parameters) {
207         if (deviceInfo.pluginKeys == null) {
208             return;
209         }
210 
211         for (Map.Entry<String, String> entry : deviceInfo.pluginKeys.entrySet()) {
212             addString(parameters, entry.getKey(), entry.getValue());
213         }
214     }
215 
getEventSuffix(AdjustEvent event)216     private String getEventSuffix(AdjustEvent event) {
217         if (event.revenue == null) {
218             return String.format(" '%s'", event.eventToken);
219         } else {
220             return String.format(Locale.US, " (%.4f %s, '%s')", event.revenue, event.currency, event.eventToken);
221         }
222     }
223 
addString(Map<String, String> parameters, String key, String value)224     private void addString(Map<String, String> parameters, String key, String value) {
225         if (TextUtils.isEmpty(value)) {
226             return;
227         }
228 
229         parameters.put(key, value);
230     }
231 
addInt(Map<String, String> parameters, String key, long value)232     private void addInt(Map<String, String> parameters, String key, long value) {
233         if (value < 0) {
234             return;
235         }
236 
237         String valueString = Long.toString(value);
238         addString(parameters, key, valueString);
239     }
240 
addDate(Map<String, String> parameters, String key, long value)241     private void addDate(Map<String, String> parameters, String key, long value) {
242         if (value < 0) {
243             return;
244         }
245 
246         String dateString = Util.dateFormat(value);
247         addString(parameters, key, dateString);
248     }
249 
addDuration(Map<String, String> parameters, String key, long durationInMilliSeconds)250     private void addDuration(Map<String, String> parameters, String key, long durationInMilliSeconds) {
251         if (durationInMilliSeconds < 0) {
252             return;
253         }
254 
255         long durationInSeconds = (durationInMilliSeconds + 500) / 1000;
256         addInt(parameters, key, durationInSeconds);
257     }
258 
addMapJson(Map<String, String> parameters, String key, Map<String, String> map)259     private void addMapJson(Map<String, String> parameters, String key, Map<String, String> map) {
260         if (map == null) {
261             return;
262         }
263 
264         if (map.size() == 0) {
265             return;
266         }
267 
268         JSONObject jsonObject = new JSONObject(map);
269         String jsonString = jsonObject.toString();
270 
271         addString(parameters, key, jsonString);
272     }
273 
addBoolean(Map<String, String> parameters, String key, Boolean value)274     private void addBoolean(Map<String, String> parameters, String key, Boolean value) {
275         if (value == null) {
276             return;
277         }
278 
279         int intValue = value ? 1 : 0;
280 
281         addInt(parameters, key, intValue);
282     }
283 
addDouble(Map<String, String> parameters, String key, Double value)284     private void addDouble(Map<String, String> parameters, String key, Double value) {
285         if (value == null) return;
286 
287         String doubleString = String.format("%.5f", value);
288 
289         addString(parameters, key, doubleString);
290     }
291 }
292