@@ -53,24 +53,17 @@ class HeartBeatInfoStorage {
53
53
// As soon as you hit the limit of heartbeats. The number of stored heartbeats is halved.
54
54
private static final int HEART_BEAT_COUNT_LIMIT = 30 ;
55
55
56
- private static final SimpleDateFormat FORMATTER = new SimpleDateFormat ("dd/MM/yyyy z" );
57
-
58
- private SharedPreferences sharedPreferences ;
59
- private SharedPreferences firebaseSharedPreferences ;
56
+ private final SharedPreferences firebaseSharedPreferences ;
60
57
61
58
public HeartBeatInfoStorage (Context applicationContext , String persistenceKey ) {
62
- this .sharedPreferences =
63
- applicationContext .getSharedPreferences (
64
- PREFERENCES_NAME + persistenceKey , Context .MODE_PRIVATE );
65
59
this .firebaseSharedPreferences =
66
60
applicationContext .getSharedPreferences (
67
61
HEARTBEAT_PREFERENCES_NAME + persistenceKey , Context .MODE_PRIVATE );
68
62
}
69
63
70
64
@ VisibleForTesting
71
65
@ RestrictTo (RestrictTo .Scope .TESTS )
72
- HeartBeatInfoStorage (SharedPreferences preferences , SharedPreferences firebaseSharedPreferences ) {
73
- this .sharedPreferences = preferences ;
66
+ HeartBeatInfoStorage (SharedPreferences firebaseSharedPreferences ) {
74
67
this .firebaseSharedPreferences = firebaseSharedPreferences ;
75
68
}
76
69
@@ -81,7 +74,14 @@ int getHeartBeatCount() {
81
74
}
82
75
83
76
synchronized void deleteAllHeartBeats () {
84
- firebaseSharedPreferences .edit ().clear ().apply ();
77
+ SharedPreferences .Editor editor = firebaseSharedPreferences .edit ();
78
+ for (Map .Entry <String , ?> entry : this .firebaseSharedPreferences .getAll ().entrySet ()) {
79
+ if (entry .getValue () instanceof Set ) {
80
+ editor .remove (entry .getKey ());
81
+ }
82
+ }
83
+ editor .remove (HEART_BEAT_COUNT_TAG );
84
+ editor .commit ();
85
85
}
86
86
87
87
synchronized List <HeartBeatResult > getAllHeartBeats () {
@@ -93,10 +93,48 @@ synchronized List<HeartBeatResult> getAllHeartBeats() {
93
93
entry .getKey (), new ArrayList <String >((Set <String >) entry .getValue ())));
94
94
}
95
95
}
96
+ updateGlobalHeartBeat (System .currentTimeMillis ());
96
97
return heartBeatResults ;
97
98
}
98
99
99
- synchronized String getFormattedDate (long millis ) {
100
+ private synchronized String getStoredUserAgentString (String dateString ) {
101
+ for (Map .Entry <String , ?> entry : firebaseSharedPreferences .getAll ().entrySet ()) {
102
+ if (entry .getValue () instanceof Set ) {
103
+ Set <String > dateSet = (Set <String >) entry .getValue ();
104
+ for (String date : dateSet ) {
105
+ if (dateString .equals (date )) {
106
+ return entry .getKey ();
107
+ }
108
+ }
109
+ }
110
+ }
111
+ return null ;
112
+ }
113
+
114
+ private synchronized void removeStoredDate (String dateString ) {
115
+ // Find stored heartbeat and clear it.
116
+ String userAgentString = getStoredUserAgentString (dateString );
117
+ if (userAgentString == null ) {
118
+ return ;
119
+ }
120
+ Set <String > userAgentDateSet =
121
+ new HashSet <String >(
122
+ firebaseSharedPreferences .getStringSet (userAgentString , new HashSet <String >()));
123
+ userAgentDateSet .remove (dateString );
124
+ if (userAgentDateSet .isEmpty ()) {
125
+ firebaseSharedPreferences .edit ().remove (userAgentString ).commit ();
126
+ } else {
127
+ firebaseSharedPreferences .edit ().putStringSet (userAgentString , userAgentDateSet ).commit ();
128
+ }
129
+ }
130
+
131
+ synchronized void postHeartBeatCleanUp () {
132
+ String dateString = getFormattedDate (System .currentTimeMillis ());
133
+ firebaseSharedPreferences .edit ().putString (LAST_STORED_DATE , dateString ).commit ();
134
+ removeStoredDate (dateString );
135
+ }
136
+
137
+ private synchronized String getFormattedDate (long millis ) {
100
138
if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
101
139
Instant instant = new Date (millis ).toInstant ();
102
140
LocalDateTime ldt = instant .atOffset (ZoneOffset .UTC ).toLocalDateTime ();
@@ -127,7 +165,7 @@ synchronized void storeHeartBeat(long millis, String userAgentString) {
127
165
.putStringSet (userAgentString , userAgentDateSet )
128
166
.putLong (HEART_BEAT_COUNT_TAG , heartBeatCount )
129
167
.putString (LAST_STORED_DATE , dateString )
130
- .apply ();
168
+ .commit ();
131
169
}
132
170
133
171
private synchronized void cleanUpStoredHeartBeats () {
@@ -153,21 +191,19 @@ private synchronized void cleanUpStoredHeartBeats() {
153
191
.edit ()
154
192
.putStringSet (userAgentString , userAgentDateSet )
155
193
.putLong (HEART_BEAT_COUNT_TAG , heartBeatCount - 1 )
156
- .apply ();
194
+ .commit ();
157
195
}
158
196
159
197
synchronized long getLastGlobalHeartBeat () {
160
- return sharedPreferences .getLong (GLOBAL , -1 );
198
+ return firebaseSharedPreferences .getLong (GLOBAL , -1 );
161
199
}
162
200
163
201
synchronized void updateGlobalHeartBeat (long millis ) {
164
- sharedPreferences .edit ().putLong (GLOBAL , millis ).apply ();
202
+ firebaseSharedPreferences .edit ().putLong (GLOBAL , millis ).commit ();
165
203
}
166
204
167
- static boolean isSameDateUtc (long base , long target ) {
168
- Date baseDate = new Date (base );
169
- Date targetDate = new Date (target );
170
- return !(FORMATTER .format (baseDate ).equals (FORMATTER .format (targetDate )));
205
+ synchronized boolean isSameDateUtc (long base , long target ) {
206
+ return getFormattedDate (base ).equals (getFormattedDate (target ));
171
207
}
172
208
173
209
/*
@@ -176,14 +212,14 @@ static boolean isSameDateUtc(long base, long target) {
176
212
when the last heartbeat send for the sdk was later than a day before.
177
213
*/
178
214
synchronized boolean shouldSendSdkHeartBeat (String heartBeatTag , long millis ) {
179
- if (sharedPreferences .contains (heartBeatTag )) {
180
- if (isSameDateUtc (sharedPreferences .getLong (heartBeatTag , -1 ), millis )) {
181
- sharedPreferences .edit ().putLong (heartBeatTag , millis ).apply ();
215
+ if (firebaseSharedPreferences .contains (heartBeatTag )) {
216
+ if (! this . isSameDateUtc (firebaseSharedPreferences .getLong (heartBeatTag , -1 ), millis )) {
217
+ firebaseSharedPreferences .edit ().putLong (heartBeatTag , millis ).commit ();
182
218
return true ;
183
219
}
184
220
return false ;
185
221
} else {
186
- sharedPreferences .edit ().putLong (heartBeatTag , millis ).apply ();
222
+ firebaseSharedPreferences .edit ().putLong (heartBeatTag , millis ).commit ();
187
223
return true ;
188
224
}
189
225
}
0 commit comments