-
Notifications
You must be signed in to change notification settings - Fork 70
Expand file tree
/
Copy pathMParticleOptions.java
More file actions
1138 lines (1035 loc) · 41.4 KB
/
Copy pathMParticleOptions.java
File metadata and controls
1138 lines (1035 loc) · 41.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package com.mparticle;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.mparticle.identity.BaseIdentityTask;
import com.mparticle.identity.IdentityApiRequest;
import com.mparticle.identity.IdentityStateListener;
import com.mparticle.internal.ConfigManager;
import com.mparticle.internal.Logger;
import com.mparticle.internal.MPUtility;
import com.mparticle.internal.PushRegistrationHelper;
import com.mparticle.internal.SideloadedKit;
import com.mparticle.networking.NetworkOptions;
import com.mparticle.networking.NetworkOptionsManager;
import com.mparticle.rokt.RoktOptions;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* class used for passing optional settings to the SDK when it is started.
*/
public class MParticleOptions {
private BaseIdentityTask mIdentityTask;
private Context mContext;
private MParticle.InstallType mInstallType = MParticle.InstallType.AutoDetect;
private MParticle.Environment mEnvironment = MParticle.Environment.AutoDetect;
private String mApiKey;
private String mApiSecret;
private IdentityApiRequest mIdentifyRequest;
private Boolean mDevicePerformanceMetricsDisabled = false;
private Boolean mDeviceBasedConsentEnabled = false;
private Boolean mAndroidIdEnabled = false;
private Integer mUploadInterval = ConfigManager.DEFAULT_UPLOAD_INTERVAL; //seconds
private Integer mSessionTimeout = ConfigManager.DEFAULT_SESSION_TIMEOUT_SECONDS; //seconds
private Integer mConfigMaxAge = null;
private Integer mPersistenceMaxAgeSeconds = null;
private Boolean mUnCaughtExceptionLogging = false;
private MParticle.LogLevel mLogLevel = MParticle.LogLevel.DEBUG;
private AttributionListener mAttributionListener;
private BatchCreationListener batchCreationListener = null;
private LocationTracking mLocationTracking;
private PushRegistrationHelper.PushRegistration mPushRegistration;
private Integer mIdentityConnectionTimeout = ConfigManager.DEFAULT_CONNECTION_TIMEOUT_SECONDS;
private NetworkOptions mNetworkOptions;
private String mDataplanId;
private Integer mDataplanVersion;
private RoktOptions mRoktOptions;
private MParticle.OperatingSystem mOperatingSystem = MParticle.OperatingSystem.ANDROID;
private DataplanOptions mDataplanOptions;
private Map<Class, List<Configuration>> mConfigurations = new HashMap();
private List<SideloadedKit> sideloadedKits = new ArrayList<>();
private List<Integer> disabledKits = new ArrayList<>();
private MParticleOptions() {
}
public MParticleOptions(@NonNull Builder builder) {
this.mContext = builder.context;
if (builder.apiKey != null) {
this.mApiKey = builder.apiKey;
}
if (builder.apiSecret != null) {
this.mApiSecret = builder.apiSecret;
}
if (builder.installType != null) {
this.mInstallType = builder.installType;
}
if (builder.environment != null) {
this.mEnvironment = builder.environment;
}
if (mEnvironment == null || mEnvironment == MParticle.Environment.AutoDetect) {
if (builder.isAppDebuggable) {
this.mEnvironment = MParticle.Environment.Development;
} else {
this.mEnvironment = MParticle.Environment.Production;
}
}
if (builder.identifyRequest != null) {
this.mIdentifyRequest = builder.identifyRequest;
}
if (builder.identityTask != null) {
this.mIdentityTask = builder.identityTask;
}
if (builder.devicePerformanceMetricsDisabled != null) {
this.mDevicePerformanceMetricsDisabled = builder.devicePerformanceMetricsDisabled;
}
if (builder.deviceBasedConsentEnabled != null) {
this.mDeviceBasedConsentEnabled = builder.deviceBasedConsentEnabled;
}
if (builder.androidIdEnabled != null) {
this.mAndroidIdEnabled = builder.androidIdEnabled;
}
Logger.info(String.format("ANDROID_ID will%s be collected based on %s settings", mAndroidIdEnabled ? "" : " not", builder.androidIdEnabled != null ? "MParticleOptions" : "default"));
if (builder.uploadInterval != null) {
if (builder.uploadInterval <= 0) {
Logger.warning("Upload Interval must be a positive number, disregarding value.");
} else {
this.mUploadInterval = builder.uploadInterval;
}
}
if (builder.sessionTimeout != null) {
if (builder.sessionTimeout <= 0) {
Logger.warning("Session Timeout must be a positive number, disregarding value.");
} else {
this.mSessionTimeout = builder.sessionTimeout;
}
}
if (builder.configMaxAge != null) {
if (builder.configMaxAge < 0) {
Logger.warning("Config Max Age must be a positive number, disregarding value.");
} else {
this.mConfigMaxAge = builder.configMaxAge;
}
}
if (builder.persistenceMaxAgeSeconds != null) {
if (builder.persistenceMaxAgeSeconds <= 0) {
Logger.warning("Persistence Max Age must be a positive number, disregarding value.");
} else {
this.mPersistenceMaxAgeSeconds = builder.persistenceMaxAgeSeconds;
}
}
if (builder.unCaughtExceptionLogging != null) {
this.mUnCaughtExceptionLogging = builder.unCaughtExceptionLogging;
}
if (builder.logLevel != null) {
this.mLogLevel = builder.logLevel;
}
if (builder.attributionListener != null) {
this.mAttributionListener = builder.attributionListener;
}
if (builder.batchCreationListener != null) {
this.batchCreationListener = builder.batchCreationListener;
}
if (builder.locationTracking != null) {
this.mLocationTracking = builder.locationTracking;
}
if (builder.pushRegistration != null) {
this.mPushRegistration = builder.pushRegistration;
}
if (builder.identityConnectionTimeout != null && builder.identityConnectionTimeout >= ConfigManager.MINIMUM_CONNECTION_TIMEOUT_SECONDS) {
this.mIdentityConnectionTimeout = builder.identityConnectionTimeout;
} else if (builder.identityConnectionTimeout != null) {
Logger.warning(String.format("Connection Timeout milliseconds must be a positive number, greater than %s second. Defaulting to %s seconds", String.valueOf(ConfigManager.MINIMUM_CONNECTION_TIMEOUT_SECONDS), String.valueOf(ConfigManager.DEFAULT_CONNECTION_TIMEOUT_SECONDS)));
}
if (builder.operatingSystem != null) {
this.mOperatingSystem = builder.operatingSystem;
}
this.mNetworkOptions = NetworkOptionsManager.validateAndResolve(builder.networkOptions);
this.mRoktOptions = builder.roktOptions;
this.mDataplanId = builder.dataplanId;
this.mDataplanVersion = builder.dataplanVersion;
this.mDataplanOptions = builder.dataplanOptions;
this.mConfigurations = builder.configurations;
this.sideloadedKits = builder.sideloadedKits;
this.disabledKits = builder.disabledKits;
}
/**
* @param context
* @return
*/
@NonNull
public static MParticleOptions.Builder builder(@NonNull Context context) {
return new Builder(context);
}
@NonNull
public Context getContext() {
return mContext;
}
/**
* Query the InstallType.
*/
@NonNull
public MParticle.InstallType getInstallType() {
return mInstallType;
}
/**
* Query the Environment.
*
* @return
*/
@NonNull
public MParticle.Environment getEnvironment() {
return mEnvironment;
}
/**
* Get list of sideloadedKits kits
*
* @return
*/
@NonNull
public List<SideloadedKit> getSideloadedKits() {
return sideloadedKits;
}
/**
* Get list of disabled kits
*
* @return
* */
@NonNull
public List<Integer> getDisabledKits() {
return disabledKits;
}
/**
* Query the API Key.
*
* @return
*/
@NonNull
public String getApiKey() {
return mApiKey;
}
/**
* Query the API Secret.
*
* @return
*/
@NonNull
public String getApiSecret() {
return mApiSecret;
}
/**
* Query the Identify Request.
*
* @return
*/
@Nullable
public IdentityApiRequest getIdentifyRequest() {
return mIdentifyRequest;
}
/**
* Query whether device performance metrics are enabled or disabled.
*
* @return true if the are disabled, false if they are enabled
*/
@NonNull
public Boolean isDevicePerformanceMetricsDisabled() {
return mDevicePerformanceMetricsDisabled;
}
/**
* Query whether device-based consent is enabled.
* <p>
* When enabled, {@link com.mparticle.identity.MParticleUser#setConsentState(ConsentState)}
* will persist consent at the device level in addition to the current MPID. Device-level
* consent overrides MPID-based consent when applying consent forwarding rules and uploading events.
*
* @return true if device-based consent is enabled
*/
@NonNull
public Boolean isDeviceBasedConsentEnabled() {
return mDeviceBasedConsentEnabled;
}
/**
* @return true if collection is disabled, false if it is enabled
* @deprecated This method has been replaced as the behavior has been inverted - Android ID collection is now disabled by default.
* <p> Use {@link MParticle#isAndroidIdEnabled()} instead.
* <p>
* Query whether Android Id collection is enabled or disabled.
*/
@NonNull
@Deprecated
public Boolean isAndroidIdDisabled() {
return !mAndroidIdEnabled;
}
/**
* Query whether Android Id collection is enabled or disabled.
*
* @return true if collection is enabled, false if it is disabled
*/
@NonNull
public Boolean isAndroidIdEnabled() {
return mAndroidIdEnabled;
}
/**
* Query the uploadInterval.
*
* @return the upload interval, in seconds
* @return the upload interval, in seconds
*/
@NonNull
public Integer getUploadInterval() {
return mUploadInterval;
}
@NonNull
public Integer getSessionTimeout() {
return mSessionTimeout;
}
@NonNull
public Integer getConfigMaxAge() {
return mConfigMaxAge;
}
/**
* The maximum threshold (in seconds) for locally persisted events, batches, and sessions.
* <p>
* When {@code null} (the default), records are retained for 90 days before being deleted.
* Values less than or equal to zero are rejected at build time and result in the default
* being used.
*
* @return the configured maximum persistence age in seconds, or {@code null} when the default
* (90 days) applies
* @see Builder#persistenceMaxAgeSeconds(int)
*/
@Nullable
public Integer getPersistenceMaxAgeSeconds() {
return mPersistenceMaxAgeSeconds;
}
@NonNull
public Boolean isUncaughtExceptionLoggingEnabled() {
return mUnCaughtExceptionLogging;
}
@NonNull
public MParticle.LogLevel getLogLevel() {
return mLogLevel;
}
@Nullable
public BaseIdentityTask getIdentityTask() {
return mIdentityTask;
}
@Nullable
public AttributionListener getAttributionListener() {
return mAttributionListener;
}
@Nullable
public BatchCreationListener getBatchCreationListener() {
return batchCreationListener;
}
public boolean hasLocationTracking() {
return mLocationTracking != null;
}
@Nullable
public LocationTracking getLocationTracking() {
return mLocationTracking;
}
@Nullable
public PushRegistrationHelper.PushRegistration getPushRegistration() {
return mPushRegistration;
}
public int getConnectionTimeout() {
return mIdentityConnectionTimeout;
}
@NonNull
public NetworkOptions getNetworkOptions() {
return mNetworkOptions;
}
@NonNull
public RoktOptions getRoktOptions() {
return mRoktOptions;
}
@Nullable
public String getDataplanId() {
return mDataplanId;
}
@Nullable
public Integer getDataplanVersion() {
return mDataplanVersion;
}
@NonNull
public MParticle.OperatingSystem getOperatingSystem() {
return mOperatingSystem;
}
@Nullable
public DataplanOptions getDataplanOptions() {
return mDataplanOptions;
}
@NonNull
public List<Configuration> getConfigurations() {
return new ArrayList(mConfigurations.values());
}
@Nullable
public <T extends Configuration> T getConfiguration(Class<T> clazz) {
for (List<? extends Configuration> configurations : mConfigurations.values()) {
for (Configuration configuration : configurations) {
if (configuration.getClass() == clazz) {
return (T) configuration;
}
}
}
return null;
}
@NonNull
public <T> List<Configuration<T>> getConfigurationsForTarget(Class<T> clazz) {
List list = mConfigurations.get(clazz);
if (list == null) {
return new ArrayList<Configuration<T>>();
} else {
return new ArrayList<Configuration<T>>(list);
}
}
public static class Builder {
private Context context;
String apiKey;
String apiSecret;
private MParticle.InstallType installType;
private MParticle.Environment environment;
private IdentityApiRequest identifyRequest;
private Boolean devicePerformanceMetricsDisabled = null;
private Boolean deviceBasedConsentEnabled = null;
private Boolean androidIdEnabled = null;
private Integer uploadInterval = null;
private Integer sessionTimeout = null;
private Integer configMaxAge = null;
private Integer persistenceMaxAgeSeconds = null;
private Boolean unCaughtExceptionLogging = null;
MParticle.LogLevel logLevel = null;
BaseIdentityTask identityTask;
private AttributionListener attributionListener;
private BatchCreationListener batchCreationListener;
private ConfigManager configManager;
private LocationTracking locationTracking;
private PushRegistrationHelper.PushRegistration pushRegistration;
private Integer identityConnectionTimeout = null;
private NetworkOptions networkOptions;
private String dataplanId;
private Integer dataplanVersion;
private MParticle.OperatingSystem operatingSystem;
private DataplanOptions dataplanOptions;
private RoktOptions roktOptions;
private Map<Class, List<Configuration>> configurations = new HashMap();
private boolean isAppDebuggable;
private List<SideloadedKit> sideloadedKits = new ArrayList<>();
private List<Integer> disabledKits = new ArrayList<>();
private Builder(Context context) {
this.context = context;
}
/**
* Register an Api Key and Secret to be used for the SDK. This is a required field, and your
* app will not function properly if you do not provide a valid Key and Secret.
*
* @param apiKey the Api Key
* @param apiSecret the Api Secret
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder credentials(@NonNull String apiKey, @NonNull String apiSecret) {
this.apiKey = apiKey;
this.apiSecret = apiSecret;
return this;
}
/**
* Indicate a known {@link com.mparticle.MParticle.InstallType}. If this method is not used,
* a default type of MParticle.InstallType.AutoDetect will be used.
*
* @param installType
* @return the instance of the builder, for chaining calls
* @see com.mparticle.MParticle.InstallType
*/
@NonNull
public Builder installType(@NonNull MParticle.InstallType installType) {
this.installType = installType;
return this;
}
/**
* Add sideloaded kits
*
* @param kits
* @return
*/
@NonNull
public Builder sideloadedKits(@NonNull List<SideloadedKit> kits) {
List<SideloadedKit> _kits = new ArrayList<>();
for (SideloadedKit kit : kits) {
if (kit.kitId() < 1000000) {
Logger.error("Sideloaded kit " + kit.getName() + " must have a kitId greater or equal than 1000000, current one is " + kit.kitId() + " and will not be included.");
} else {
_kits.add(kit);
}
}
this.sideloadedKits = _kits;
return this;
}
/**
* Indicate a known {@link com.mparticle.MParticle.Environment} the Application will be running in. If this method is not used.
* a default Environment of MParticle.Environment.AutoDetect will be used.
*
* @param environment
* @return
*/
@NonNull
public Builder environment(@NonNull MParticle.Environment environment) {
this.environment = environment;
return this;
}
/**
* Add disable kits option
*
* @param kits
* @return
*/
@NonNull
public Builder disabledKits(@NonNull List<Integer> kits) {
disabledKits.addAll(kits);
return this;
}
/**
* Register an IdentityApiRequest which will be passed to an {@link com.mparticle.identity.IdentityApi#identify(IdentityApiRequest)}
* request when the SDK starts in order to interact with the results of this call, without registering
* a global listener in {@link com.mparticle.identity.IdentityApi#addIdentityStateListener(IdentityStateListener)}, register
* a BaseIdentityTask with {@link #identifyTask(BaseIdentityTask)}. If this method is not called,
* an Identify request using the most recent current user will be used, or if this is a first-run,
* and empty request will be used.
*
* @param identifyRequest
* @return the instance of the builder, for chaining calls
* @see IdentityApiRequest
*/
@NonNull
public Builder identify(@NonNull IdentityApiRequest identifyRequest) {
this.identifyRequest = identifyRequest;
return this;
}
/**
* Register an BaseIdentityTask, which can be used to interact with the asynchronous results
* of an {@link #identify(IdentityApiRequest)} request.
*
* @param task
* @return the instance of the builder, for chaining calls
* @see BaseIdentityTask
*/
@NonNull
public Builder identifyTask(@NonNull BaseIdentityTask task) {
this.identityTask = task;
return this;
}
/**
* Disable CPU and memory usage collection.
*
* @param disabled
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder devicePerformanceMetricsDisabled(boolean disabled) {
this.devicePerformanceMetricsDisabled = disabled;
return this;
}
/**
* Enable device-based consent.
* <p>
* When enabled, consent set via {@link com.mparticle.identity.MParticleUser#setConsentState(ConsentState)}
* is stored at the device level and overrides MPID-based consent when applying consent forwarding
* rules and uploading events. This is useful when consent is collected before the user's MPID is known
* or when the MPID changes during a flow such as checkout.
*
* @param enabled true to enable device-based consent
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder deviceBasedConsentEnabled(boolean enabled) {
this.deviceBasedConsentEnabled = enabled;
return this;
}
/**
* @param disabled false to enable collection (true by default)
* @return the instance of the builder, for chaining calls
* @deprecated This method has been replaced as the behavior has been inverted - Android ID collection is now disabled by default.
* <p> Use {@link androidIdEnabled(boolean)} instead.
* <p>
* <p>
* By default, the SDK will NOT collect <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID">Android Id</a> for the purpose
* of anonymous analytics. If you're not using an mParticle integration that consumes Android ID and you would like to collect it, use this API to enable collection.
*/
@NonNull
@Deprecated
public Builder androidIdDisabled(boolean disabled) {
this.androidIdEnabled = !disabled;
return this;
}
/**
* By default, the SDK will NOT collect <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID">Android Id</a> for the purpose
* of anonymous analytics. If you're not using an mParticle integration that consumes Android ID and you would like to collect it, use this API to enable collection
*
* @param enabled true to enable collection (false by default)
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder androidIdEnabled(boolean enabled) {
this.androidIdEnabled = enabled;
return this;
}
/**
* Set the upload interval period to control how frequently uploads occur.
*
* @param uploadInterval the number of seconds between uploads
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder uploadInterval(int uploadInterval) {
this.uploadInterval = uploadInterval;
return this;
}
/**
* Set the user session timeout interval.
* <p></p>
* A session has ended once the application has been in the background for more than this timeout.
*
* @param sessionTimeout Session timeout in seconds
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder sessionTimeout(int sessionTimeout) {
this.sessionTimeout = sessionTimeout;
return this;
}
/**
* Set a maximum threshold for stored configuration age.
* <p>
* When the SDK starts, before we attempt to fetch a fresh config from the server, we
* will load the most recent previous config from disk. when configMaxAge is set, we will
* check the timestamp on that config and, if it's age is greater than the threshold, instead
* of loading it we will delete it and wait for the fresh config to arrive.
* <p>
* This field is especially useful if your application often updates the kit/forwarding logic and
* has a portion of user's who experience prolonged network interruptions. In these cases, a reasonable
* configMaxAge will prevent those users from potentially using very forwarding logic
*
* @param configMaxAge the upper limit for config age, in seconds
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder configMaxAgeSeconds(int configMaxAge) {
this.configMaxAge = configMaxAge;
return this;
}
/**
* Set a maximum threshold for locally persisted events, batches, and sessions, in seconds.
* <p>
* By default, data is persisted for 90 days before being deleted to minimize data loss;
* however, this can lead to excessive storage usage on some users' devices. This is
* exacerbated if your app logs a large number of events, or events carrying a lot of data
* (attributes, etc.).
* <p>
* Set a lower value (for example, 48 hours or 1 week) if you have storage usage concerns.
* Alternatively, if you have data loss concerns, set a longer value than the default.
* <p>
* This is the Android equivalent of the iOS SDK's
* {@code MParticleOptions.persistenceMaxAgeSeconds} option.
*
* @param persistenceMaxAgeSeconds the upper limit, in seconds, for how long persisted
* data may live on disk. Must be greater than zero;
* non-positive values are rejected and the default
* (90 days) is used instead
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder persistenceMaxAgeSeconds(int persistenceMaxAgeSeconds) {
this.persistenceMaxAgeSeconds = persistenceMaxAgeSeconds;
return this;
}
/**
* Enable or disable mParticle exception handling to automatically log events on uncaught exceptions.
*
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder enableUncaughtExceptionLogging(boolean enable) {
this.unCaughtExceptionLogging = enable;
return this;
}
/**
* Set the minimum log level for the SDK. The log level
* is used to moderate the amount of messages that are printed by the SDK
* to the console. Note that while the SDK is in the Production,
* <i>log messages at or above this level will be printed</i>.
*
* @param logLevel the preferred level of logging
* @return the instance of the builder, for chaining calls
* @see MParticle.LogLevel
*/
@NonNull
public Builder logLevel(@NonNull MParticle.LogLevel logLevel) {
this.logLevel = logLevel;
return this;
}
/**
* Register a callback for when an attribution is received.
*
* @param attributionListener an instance of the AttributionListener callback
* @return the instance of the builder, for chaining calls
* @see AttributionListener
*/
@NonNull
public Builder attributionListener(@Nullable AttributionListener attributionListener) {
this.attributionListener = attributionListener;
return this;
}
@NonNull
public Builder batchCreationListener(@Nullable BatchCreationListener batchCreationListener) {
this.batchCreationListener = batchCreationListener;
return this;
}
/**
* Disables Location tracking.
*
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder locationTrackingDisabled() {
this.locationTracking = new LocationTracking(false);
return this;
}
/**
* Enables location tracking given a provider and update frequency criteria. The provider must
* be available and the correct permissions must have been requested within your application's manifest XML file.
*
* @param provider the provider key
* @param minTime the minimum time (in milliseconds) to trigger an update
* @param minDistance the minimum distance (in meters) to trigger an update
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder locationTrackingEnabled(@NonNull String provider, long minTime, long minDistance) {
this.locationTracking = new LocationTracking(provider, minTime, minDistance);
return this;
}
/**
* Manually log a push registration.
*
* @param instanceId the Instance Id of the push token
* @param senderId the Sender Id of the push token
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder pushRegistration(@NonNull String instanceId, @NonNull String senderId) {
this.pushRegistration = new PushRegistrationHelper.PushRegistration(instanceId, senderId);
return this;
}
/**
* Set the user connection timeout interval.
* <p></p>
* A connection to the server closes after this timeout expires, for each call.
*
* @param identityConnectionTimeout the connection timeout for Identity server calls, in seconds
* @return the instance of the builder, for chaining calls
*/
@NonNull
public Builder identityConnectionTimeout(int identityConnectionTimeout) {
this.identityConnectionTimeout = identityConnectionTimeout;
return this;
}
@NonNull
public Builder networkOptions(@Nullable NetworkOptions networkOptions) {
this.networkOptions = networkOptions;
return this;
}
@NonNull
public Builder dataplan(@Nullable String dataplanId, @Nullable Integer dataplanVersion) {
this.dataplanId = dataplanId;
this.dataplanVersion = dataplanVersion;
return this;
}
/**
* Set the Operating System. Defaults to {@link MParticle.OperatingSystem#ANDROID}
*
* @param operatingSystem
* @return
*/
@NonNull
public Builder operatingSystem(MParticle.OperatingSystem operatingSystem) {
this.operatingSystem = operatingSystem;
return this;
}
/**
* Set the {@link com.mparticle.MParticleOptions.DataplanOptions}. This object is used to
* load a dataplan for the purpose of blocking unplanned attributes and/or events from being forwarded to kit integrations.
* When set, this will override any block settings that have been configured in the mParticle dashboard.
*
* @param dataplanOptions
* @return
*/
@NonNull
public Builder dataplanOptions(DataplanOptions dataplanOptions) {
this.dataplanOptions = dataplanOptions;
return this;
}
@NonNull
public Builder roktOptions(@NonNull RoktOptions roktOptions) {
this.roktOptions = roktOptions;
return this;
}
/**
* Register a {@link com.mparticle.Configuration}n. Various implementations of Configuration can modify the behavior of
* the SDK at runtime.
*
* @param configuration
*/
public Builder configuration(Configuration configuration) {
List<Configuration> configurationList = this.configurations.get(configuration.configures());
if (configurationList == null) {
configurationList = new ArrayList<Configuration>();
}
configurationList.add(configuration);
this.configurations.put(configuration.configures(), configurationList);
return this;
}
/**
* Builds this Builder into an MParticleOptions object which can be used to start the SDK.
*
* @return MParticleOptions instance
*/
@NonNull
public MParticleOptions build() {
String message;
if (context == null) {
throw new IllegalArgumentException("mParticle failed to start: context is required.");
}
isAppDebuggable = MPUtility.isAppDebuggable(context);
boolean devMode = MParticle.Environment.Development.equals(environment) || isAppDebuggable;
if (MPUtility.isEmpty(apiKey)) {
message = "Configuration issue: No API key passed to start()!";
if (devMode) {
throw new IllegalArgumentException(message);
} else {
Logger.error(message);
}
}
if (MPUtility.isEmpty(apiSecret)) {
message = "Configuration issue: No API secret passed to start()!";
if (devMode) {
throw new IllegalArgumentException(message);
} else {
Logger.error(message);
}
}
return new MParticleOptions(this);
}
MParticleOptions buildForInternalRestart() {
return new MParticleOptions(this);
}
}
static class LocationTracking {
boolean enabled = true;
String provider;
long minTime;
long minDistance;
protected LocationTracking(boolean enabled) {
this.enabled = enabled;
}
protected LocationTracking(String provider, long minTime, long minDistance) {
this.provider = provider;
this.minTime = minTime;
this.minDistance = minDistance;
}
}
public static class DataplanOptions {
private JSONObject dataplan;
private boolean blockUserAttributes;
private boolean blockUserIdentities;
private boolean blockEventAttributes;
private boolean blockEvents;
private DataplanOptions(@NonNull Builder builder) {
dataplan = builder.dataplanVersion;
blockUserAttributes = builder.blockUserAttributes;
blockUserIdentities = builder.blockUserIdentities;
blockEventAttributes = builder.blockEventAttributes;
blockEvents = builder.blockEvents;
}
/**
* Query the dataplan version document
*
* @return the dataplan version as a JSONObject
*/
@NonNull
public JSONObject getDataplan() {
return dataplan;
}
/**
* Query whether unplanned user attributes should be blocked
*
* @return boolean where true indicates blocking should occur
*/
public boolean isBlockUserAttributes() {
return blockUserAttributes;
}
/**
* Query whether unplanned user identities should be blocked
*
* @return boolean where true indicates blocking should occur
*/
public boolean isBlockUserIdentities() {
return blockUserIdentities;
}
/**
* Query whether unplanned event attributes should be blocked
*
* @return boolean where true indicates blocking should occur
*/
public boolean isBlockEventAttributes() {
return blockEventAttributes;
}
/**
* Query whether unplanned events should be blocked
*
* @return boolean where true indicates blocking should occur
*/
public boolean isBlockEvents() {
return blockEvents;
}
@Override
public String toString() {
String dataplanString = null;
try {
dataplanString = dataplan.toString(4);
} catch (JSONException e) {
dataplanString = "Unable to print Dataplan";
}
return "DataplanOptions {" +
"\n\tblockUserAttributes=" + blockUserAttributes +
", \n\tblockUserIdentities=" + blockUserIdentities +
", \n\tblockEventAttributes=" + blockEventAttributes +
", \n\tblockEvents=" + blockEvents +