That fuck shit the fascists are using
1package org.tm.archive.util;
2
3import android.os.SystemClock;
4
5import androidx.annotation.MainThread;
6import androidx.annotation.NonNull;
7import androidx.annotation.Nullable;
8
9import java.util.HashMap;
10import java.util.Map;
11import java.util.concurrent.atomic.AtomicInteger;
12import java.util.concurrent.TimeUnit;
13
14/**
15 * A nice interface for {@link LocalMetrics} that gives us a place to define string constants and nicer method names.
16 */
17public final class SignalLocalMetrics {
18
19 private SignalLocalMetrics() {}
20
21 public static final class ColdStart {
22 private static final String NAME_CONVERSATION_LIST = "cold-start-conversation-list";
23 private static final String NAME_OTHER = "cold-start-other";
24
25 private static final String SPLIT_APPLICATION_CREATE = "application-create";
26 private static final String SPLIT_ACTIVITY_CREATE = "start-activity";
27 private static final String SPLIT_DATA_LOADED = "data-loaded";
28 private static final String SPLIT_RENDER = "render";
29
30 private static String conversationListId;
31 private static String otherId;
32
33 private static boolean isConversationList;
34
35 @MainThread
36 public static void start() {
37 conversationListId = NAME_CONVERSATION_LIST + "-" + System.currentTimeMillis();
38 otherId = NAME_OTHER + "-" + System.currentTimeMillis();
39
40 LocalMetrics.getInstance().start(conversationListId, NAME_CONVERSATION_LIST);
41 LocalMetrics.getInstance().start(otherId, NAME_OTHER);
42 }
43
44 @MainThread
45 public static void onApplicationCreateFinished() {
46 LocalMetrics.getInstance().split(conversationListId, SPLIT_APPLICATION_CREATE);
47 LocalMetrics.getInstance().split(otherId, SPLIT_APPLICATION_CREATE);
48 }
49
50 @MainThread
51 public static void onRenderStart() {
52 LocalMetrics.getInstance().split(conversationListId, SPLIT_ACTIVITY_CREATE);
53 LocalMetrics.getInstance().split(otherId, SPLIT_ACTIVITY_CREATE);
54 }
55
56 @MainThread
57 public static void onConversationListDataLoaded() {
58 isConversationList = true;
59 LocalMetrics.getInstance().split(conversationListId, SPLIT_DATA_LOADED);
60 }
61
62 @MainThread
63 public static void onRenderFinished() {
64 if (isConversationList) {
65 LocalMetrics.getInstance().split(conversationListId, SPLIT_RENDER);
66 LocalMetrics.getInstance().end(conversationListId);
67 LocalMetrics.getInstance().cancel(otherId);
68 } else {
69 LocalMetrics.getInstance().split(otherId, SPLIT_RENDER);
70 LocalMetrics.getInstance().end(otherId);
71 LocalMetrics.getInstance().cancel(conversationListId);
72 }
73 }
74 }
75
76 public static final class ConversationOpen {
77 private static final String NAME = "conversation-open";
78
79 private static final String SPLIT_VIEWMODEL_INIT = "viewmodel-init";
80 private static final String SPLIT_METADATA_LOADED = "metadata-loaded";
81 private static final String SPLIT_DATA_LOADED = "data-loaded";
82 private static final String SPLIT_DATA_POSTED = "data-posted";
83 private static final String SPLIT_RENDER = "render";
84
85 private static String id;
86
87 public static void start() {
88 SignalTrace.beginSection("6-ConversationOpen");
89 id = NAME + "-" + System.currentTimeMillis();
90 LocalMetrics.getInstance().start(id, NAME);
91 SignalTrace.beginSection("1-ConversationOpen-ViewModel-Init");
92 }
93
94 public static void onMetadataLoadStarted() {
95 SignalTrace.endSection();
96 LocalMetrics.getInstance().split(id, SPLIT_VIEWMODEL_INIT);
97 SignalTrace.beginSection("2-ConversationOpen-Metadata-Loaded");
98 }
99
100 public static void onMetadataLoaded() {
101 SignalTrace.endSection();
102 LocalMetrics.getInstance().split(id, SPLIT_METADATA_LOADED);
103 SignalTrace.beginSection("3-ConversationOpen-Data-Loaded");
104 }
105
106 public static void onDataLoaded() {
107 SignalTrace.endSection();
108 LocalMetrics.getInstance().split(id, SPLIT_DATA_LOADED);
109 SignalTrace.beginSection("4-ConversationOpen-Data-Posted");
110 }
111
112 public static void onDataPostedToMain() {
113 SignalTrace.endSection();
114 LocalMetrics.getInstance().split(id, SPLIT_DATA_POSTED);
115 SignalTrace.beginSection("5-ConversationOpen-Render");
116 }
117
118 public static void onRenderFinished() {
119 SignalTrace.endSection();
120 LocalMetrics.getInstance().split(id, SPLIT_RENDER);
121 LocalMetrics.getInstance().end(id);
122 SignalTrace.endSection();
123 }
124 }
125
126 public static final class IndividualMessageSend {
127 private static final String NAME = "individual-message-send";
128
129 private static final String SPLIT_DB_INSERT = "db-insert";
130 private static final String SPLIT_JOB_ENQUEUE = "job-enqueue";
131 private static final String SPLIT_JOB_PRE_NETWORK = "job-pre-network";
132 private static final String SPLIT_ENCRYPT = "encrypt";
133 private static final String SPLIT_NETWORK_MAIN = "network-main";
134 private static final String SPLIT_NETWORK_SYNC = "network-sync";
135 private static final String SPLIT_JOB_POST_NETWORK = "job-post-network";
136 private static final String SPLIT_UI_UPDATE = "ui-update";
137
138 private static final Map<Long, String> ID_MAP = new HashMap<>();
139
140 public static @NonNull String start() {
141 String id = NAME + System.currentTimeMillis();
142 LocalMetrics.getInstance().start(id, NAME);
143 return id;
144 }
145
146 public static void onInsertedIntoDatabase(long messageId, String id) {
147 if (id != null) {
148 ID_MAP.put(messageId, id);
149 split(messageId, SPLIT_DB_INSERT);
150 }
151 }
152
153 public static void onJobStarted(long messageId) {
154 split(messageId, SPLIT_JOB_ENQUEUE);
155 }
156
157 public static void onDeliveryStarted(long messageId) {
158 split(messageId, SPLIT_JOB_PRE_NETWORK);
159 }
160
161 public static void onMessageEncrypted(long messageId) {
162 split(messageId, SPLIT_ENCRYPT);
163 }
164
165 public static void onMessageSent(long messageId) {
166 split(messageId, SPLIT_NETWORK_MAIN);
167 }
168
169 public static void onSyncMessageSent(long messageId) {
170 split(messageId, SPLIT_NETWORK_SYNC);
171 }
172
173 public static void onJobFinished(long messageId) {
174 split(messageId, SPLIT_JOB_POST_NETWORK);
175 }
176
177 public static void onUiUpdated(long messageId) {
178 split(messageId, SPLIT_UI_UPDATE);
179 end(messageId);
180
181 ID_MAP.remove(messageId);
182 }
183
184 public static void cancel(long messageId) {
185 String splitId = ID_MAP.get(messageId);
186 if (splitId != null) {
187 LocalMetrics.getInstance().cancel(splitId);
188 }
189
190 ID_MAP.remove(messageId);
191 }
192
193 private static void split(long messageId, @NonNull String event) {
194 String splitId = ID_MAP.get(messageId);
195 if (splitId != null) {
196 LocalMetrics.getInstance().split(splitId, event);
197 }
198 }
199
200 private static void end(long messageId) {
201 String splitId = ID_MAP.get(messageId);
202 if (splitId != null) {
203 LocalMetrics.getInstance().end(splitId);
204 }
205 }
206 }
207
208 public static final class MessageLatency {
209 public static final String NAME_HIGH = "message-latency-high-priority";
210 public static final String NAME_LOW = "message-latency-low-priority";
211
212 private static final String SPLIT_LATENCY = "latency";
213
214 public static void onMessageReceived(long serverReceiveTimestamp, long serverDeliverTimestamp, boolean highPriority) {
215 String name = highPriority ? NAME_HIGH : NAME_LOW;
216 long latency = serverDeliverTimestamp - serverReceiveTimestamp;
217
218 if (latency > SystemClock.elapsedRealtime()) {
219 // Ignore messages with latency that would be before device boot time
220 return;
221 }
222
223 String id = name + System.currentTimeMillis();
224 LocalMetrics.getInstance().start(id, name);
225 LocalMetrics.getInstance().splitWithDuration(id, SPLIT_LATENCY, latency);
226 LocalMetrics.getInstance().end(id);
227 }
228 }
229
230 public static final class FcmServiceStartFailure {
231 public static final String NAME = "fcm-service-start-failure";
232
233 private static final String SPLIT_EVENT = "event";
234
235 public static void onFcmFailedToStart() {
236 String id = NAME + System.currentTimeMillis();
237 LocalMetrics.getInstance().start(id, NAME);
238 LocalMetrics.getInstance().splitWithDuration(id, SPLIT_EVENT, 1);
239 LocalMetrics.getInstance().end(id);
240 }
241
242 }
243
244 public static final class FcmServiceStartSuccess {
245 public static final String NAME = "fcm-service-start-success";
246
247 private static final String SPLIT_EVENT = "event";
248
249 public static void onFcmStarted() {
250 String id = NAME + System.currentTimeMillis();
251 LocalMetrics.getInstance().start(id, NAME);
252 LocalMetrics.getInstance().splitWithDuration(id, SPLIT_EVENT, 1);
253 LocalMetrics.getInstance().end(id);
254 }
255
256 }
257 public static final class PushWebsocketFetch {
258 public static final String SUCCESS_EVENT = "push-websocket-fetch";
259 public static final String TIMEOUT_EVENT = "timed-out-fetch";
260
261 private static final String SPLIT_BATCH_PROCESSED = "batches-processed";
262 private static final String SPLIT_PROCESS_TIME = "fetch-time";
263 private static final String SPLIT_TIMED_OUT = "timeout";
264
265 private static final AtomicInteger processedBatches = new AtomicInteger(0);
266
267 public static @NonNull String startFetch() {
268 String baseId = System.currentTimeMillis() + "";
269
270 String timeoutId = TIMEOUT_EVENT + baseId;
271 String successId = SUCCESS_EVENT + baseId;
272
273 LocalMetrics.getInstance().start(successId, SUCCESS_EVENT);
274 LocalMetrics.getInstance().start(timeoutId, TIMEOUT_EVENT);
275 processedBatches.set(0);
276
277 return baseId;
278 }
279
280 public static void onProcessedBatch() {
281 processedBatches.incrementAndGet();
282 }
283
284 public static void onTimedOut(String metricId) {
285 LocalMetrics.getInstance().cancel(SUCCESS_EVENT + metricId);
286
287 String timeoutId = TIMEOUT_EVENT + metricId;
288
289 LocalMetrics.getInstance().split(timeoutId, SPLIT_TIMED_OUT);
290 LocalMetrics.getInstance().end(timeoutId);
291 }
292
293 public static void onDrained(String metricId) {
294 LocalMetrics.getInstance().cancel(TIMEOUT_EVENT + metricId);
295
296 String successId = SUCCESS_EVENT + metricId;
297
298 LocalMetrics.getInstance().split(successId, SPLIT_PROCESS_TIME);
299 LocalMetrics.getInstance().splitWithDuration(successId, SPLIT_BATCH_PROCESSED, processedBatches.get());
300 LocalMetrics.getInstance().end(successId);
301 }
302
303 }
304
305 public static final class GroupMessageSend {
306 private static final String NAME = "group-message-send";
307
308 private static final String SPLIT_DB_INSERT = "db-insert";
309 private static final String SPLIT_JOB_ENQUEUE = "job-enqueue";
310 private static final String SPLIT_JOB_PRE_NETWORK = "job-pre-network";
311 private static final String SPLIT_SENDER_KEY_SHARED = "sk-shared";
312 private static final String SPLIT_ENCRYPTION = "encryption";
313 private static final String SPLIT_NETWORK_SENDER_KEY = "network-sk";
314 private static final String SPLIT_NETWORK_SENDER_KEY_SYNC = "network-sk-sync";
315 private static final String SPLIT_MSL_SENDER_KEY = "msl-sk";
316 private static final String SPLIT_NETWORK_LEGACY = "network-legacy";
317 private static final String SPLIT_NETWORK_LEGACY_SYNC = "network-legacy-sync";
318 private static final String SPLIT_JOB_POST_NETWORK = "job-post-network";
319 private static final String SPLIT_UI_UPDATE = "ui-update";
320
321 private static final Map<Long, String> ID_MAP = new HashMap<>();
322
323 public static @NonNull String start() {
324 String id = NAME + System.currentTimeMillis();
325 LocalMetrics.getInstance().start(id, NAME);
326 return id;
327 }
328
329 public static void onInsertedIntoDatabase(long messageId, String id) {
330 if (id != null) {
331 ID_MAP.put(messageId, id);
332 split(messageId, SPLIT_DB_INSERT);
333 }
334 }
335
336 public static void onJobStarted(long messageId) {
337 split(messageId, SPLIT_JOB_ENQUEUE);
338 }
339
340 public static void onSenderKeyStarted(long messageId) {
341 split(messageId, SPLIT_JOB_PRE_NETWORK);
342 }
343
344 public static void onSenderKeyShared(long messageId) {
345 split(messageId, SPLIT_SENDER_KEY_SHARED);
346 }
347
348 public static void onSenderKeyEncrypted(long messageId) {
349 split(messageId, SPLIT_ENCRYPTION);
350 }
351
352 public static void onSenderKeyMessageSent(long messageId) {
353 split(messageId, SPLIT_NETWORK_SENDER_KEY);
354 }
355
356 public static void onSenderKeySyncSent(long messageId) {
357 split(messageId, SPLIT_NETWORK_SENDER_KEY_SYNC);
358 }
359
360 public static void onSenderKeyMslInserted(long messageId) {
361 split(messageId, SPLIT_MSL_SENDER_KEY);
362 }
363
364 public static void onLegacyMessageSent(long messageId) {
365 split(messageId, SPLIT_NETWORK_LEGACY);
366 }
367
368 public static void onLegacySyncFinished(long messageId) {
369 split(messageId, SPLIT_NETWORK_LEGACY_SYNC);
370 }
371
372 public static void onJobFinished(long messageId) {
373 split(messageId, SPLIT_JOB_POST_NETWORK);
374 }
375
376 public static void onUiUpdated(long messageId) {
377 split(messageId, SPLIT_UI_UPDATE);
378 end(messageId);
379
380 ID_MAP.remove(messageId);
381 }
382
383 public static void cancel(@Nullable String id) {
384 if (id != null) {
385 LocalMetrics.getInstance().cancel(id);
386 }
387 }
388
389 public static void cancel(long messageId) {
390 String splitId = ID_MAP.get(messageId);
391 if (splitId != null) {
392 LocalMetrics.getInstance().cancel(splitId);
393 }
394
395 ID_MAP.remove(messageId);
396 }
397
398 private static void split(long messageId, @NonNull String event) {
399 String splitId = ID_MAP.get(messageId);
400 if (splitId != null) {
401 LocalMetrics.getInstance().split(splitId, event);
402 }
403 }
404
405 private static void end(long messageId) {
406 String splitId = ID_MAP.get(messageId);
407 if (splitId != null) {
408 LocalMetrics.getInstance().end(splitId);
409 }
410 }
411 }
412
413 public static final class MessageReceive {
414 private static final String NAME_GROUP = "group-message-receive";
415 private static final String NAME_INDIVIDUAL = "individual-message-receive";
416
417 private static final String SPLIT_DECRYPTION = "decryption";
418 private static final String SPLIT_PRE_PROCESS = "pre-process";
419 private static final String SPLIT_GROUPS_PROCESSING = "groups-v2";
420 private static final String SPLIT_DB_INSERT_MEDIA = "media-insert";
421 private static final String SPLIT_DB_INSERT_TEXT = "text-insert";
422 private static final String SPLIT_POST_PROCESS = "post-process";
423 private boolean insertedToDb = false;
424
425 private final String individualMetricId;
426 private final String groupMetricId;
427
428 public static MessageReceive start() {
429 return new MessageReceive();
430 }
431
432 private MessageReceive() {
433 long time = System.currentTimeMillis();
434 individualMetricId = NAME_INDIVIDUAL + time;
435 groupMetricId = NAME_GROUP + time;
436
437 LocalMetrics.getInstance().start(individualMetricId, NAME_INDIVIDUAL, TimeUnit.MICROSECONDS);
438 LocalMetrics.getInstance().start(groupMetricId, NAME_GROUP, TimeUnit.MICROSECONDS);
439 }
440
441 public void onEnvelopeDecrypted() {
442 split(SPLIT_DECRYPTION);
443 }
444
445 public void onPreProcessComplete() {
446 split(SPLIT_PRE_PROCESS);
447 }
448
449 public void onInsertedMediaMessage() {
450 split(SPLIT_DB_INSERT_MEDIA);
451 insertedToDb = true;
452 }
453
454 public void onInsertedTextMessage() {
455 split(SPLIT_DB_INSERT_TEXT);
456 insertedToDb = true;
457 }
458
459 public void onPostProcessComplete() {
460 split(SPLIT_POST_PROCESS);
461 }
462
463 public void onGv2Processed() {
464 split(SPLIT_GROUPS_PROCESSING);
465 }
466
467 private void split(String name) {
468 LocalMetrics.getInstance().split(groupMetricId, name);
469 LocalMetrics.getInstance().split(individualMetricId, name);
470 }
471
472 public void complete(boolean isGroup) {
473 if (!insertedToDb) {
474 LocalMetrics.getInstance().cancel(groupMetricId);
475 LocalMetrics.getInstance().cancel(individualMetricId);
476 return;
477 }
478
479 if (isGroup) {
480 LocalMetrics.getInstance().cancel(individualMetricId);
481 LocalMetrics.getInstance().end(groupMetricId);
482 } else {
483 LocalMetrics.getInstance().cancel(groupMetricId);
484 LocalMetrics.getInstance().end(individualMetricId);
485 }
486 }
487 }
488}