kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add the ability to trace methods in internal builds.
Currently only for internal builds. Use the @Trace annotation to trace methods for viewing in Perfetto.fork-5.53.8
rodzic
c3b5323010
commit
0b77b33902
|
@ -22,7 +22,7 @@ jobs:
|
|||
java-version: 1.8
|
||||
|
||||
- name: Install NDK
|
||||
run: echo "y" | sudo /usr/local/lib/android/sdk/tools/bin/sdkmanager --install "ndk;20.0.5594570" --sdk_root=${ANDROID_SDK_ROOT}
|
||||
run: echo "y" | sudo /usr/local/lib/android/sdk/tools/bin/sdkmanager --install "ndk;21.0.6113669" --sdk_root=${ANDROID_SDK_ROOT}
|
||||
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
|
|
|
@ -11,13 +11,15 @@ buildscript {
|
|||
jcenter {
|
||||
content {
|
||||
includeVersion 'org.jetbrains.trove4j', 'trove4j', '20160824'
|
||||
includeGroupByRegex "com\\.archinamon.*"
|
||||
}
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
classpath 'com.android.tools.build:gradle:4.0.2'
|
||||
classpath 'androidx.navigation:navigation-safe-args-gradle-plugin:2.1.0'
|
||||
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.10'
|
||||
classpath 'com.archinamon:android-gradle-aspectj:4.2.0'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,9 +27,22 @@ apply plugin: 'com.android.application'
|
|||
apply plugin: 'com.google.protobuf'
|
||||
apply plugin: 'androidx.navigation.safeargs'
|
||||
apply plugin: 'witness'
|
||||
apply plugin: 'com.archinamon.aspectj-ext'
|
||||
apply from: 'translations.gradle'
|
||||
apply from: 'witness-verifications.gradle'
|
||||
|
||||
if (getGradle().getStartParameter().getTaskRequests().toString().contains("Internal")) {
|
||||
aspectj {
|
||||
includeJar 'sqlcipher'
|
||||
includeAspectsFromJar 'Signal-Android'
|
||||
java = JavaVersion.VERSION_1_8
|
||||
}
|
||||
} else if (getGradle().getStartParameter().getTaskRequests().toString().contains("Test")) {
|
||||
aspectj {
|
||||
compileTests = false
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url "https://raw.github.com/signalapp/maven/master/photoview/releases/"
|
||||
|
@ -144,6 +159,7 @@ android {
|
|||
buildConfigField "String", "ZKGROUP_SERVER_PUBLIC_PARAMS", "\"AMhf5ywVwITZMsff/eCyudZx9JDmkkkbV6PInzG4p8x3VqVJSFiMvnvlEKWuRob/1eaIetR31IYeAbm0NdOuHH8Qi+Rexi1wLlpzIo1gstHWBfZzy1+qHRV5A4TqPp15YzBPm0WSggW6PbSn+F4lf57VCnHF7p8SvzAA2ZZJPYJURt8X7bbg+H3i+PEjH9DXItNEqs2sNcug37xZQDLm7X0=\""
|
||||
buildConfigField "String[]", "LANGUAGES", "new String[]{\"" + autoResConfig().collect { s -> s.replace('-r', '_') }.join('", "') + '"}'
|
||||
buildConfigField "int", "CANONICAL_VERSION_CODE", "$canonicalVersionCode"
|
||||
buildConfigField "int", "TRACE_EVENT_MAX", "2000"
|
||||
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||
|
@ -243,6 +259,7 @@ android {
|
|||
ext.websiteUpdateUrl = "null"
|
||||
buildConfigField "boolean", "PLAY_STORE_DISABLED", "false"
|
||||
buildConfigField "String", "NOPLAY_UPDATE_URL", "$ext.websiteUpdateUrl"
|
||||
buildConfigField "int", "TRACE_EVENT_MAX", "30_000"
|
||||
}
|
||||
|
||||
prod {
|
||||
|
@ -425,7 +442,6 @@ dependencyVerification {
|
|||
configuration = '(play|website)(Prod|Staging)(Debug|Release)RuntimeClasspath'
|
||||
}
|
||||
|
||||
|
||||
def assembleWebsiteDescriptor = { variant, file ->
|
||||
if (file.exists()) {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
package org.thoughtcrime.securesms.tracing;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
/**
|
||||
* Uses AspectJ to augment relevant methods to be traced with the {@link TracerImpl}.
|
||||
*/
|
||||
@Aspect
|
||||
public class TraceAspect {
|
||||
|
||||
@Pointcut("within(@org.thoughtcrime.securesms.tracing.Trace *)")
|
||||
public void withinAnnotatedClass() {}
|
||||
|
||||
@Pointcut("execution(!synthetic * *(..)) && withinAnnotatedClass()")
|
||||
public void methodInsideAnnotatedType() {}
|
||||
|
||||
@Pointcut("execution(!synthetic *.new(..)) && withinAnnotatedClass()")
|
||||
public void constructorInsideAnnotatedType() {}
|
||||
|
||||
@Pointcut("execution(@org.thoughtcrime.securesms.tracing.Trace * *(..)) || methodInsideAnnotatedType()")
|
||||
public void annotatedMethod() {}
|
||||
|
||||
@Pointcut("execution(@org.thoughtcrime.securesms.tracing.Trace *.new(..)) || constructorInsideAnnotatedType()")
|
||||
public void annotatedConstructor() {}
|
||||
|
||||
@Pointcut("execution(* *(..)) && within(net.sqlcipher.database.*)")
|
||||
public void sqlcipher() {}
|
||||
|
||||
@Pointcut("execution(* net.sqlcipher.database.SQLiteDatabase.rawQuery(..)) || " +
|
||||
"execution(* net.sqlcipher.database.SQLiteDatabase.query(..)) || " +
|
||||
"execution(* net.sqlcipher.database.SQLiteDatabase.insert(..)) || " +
|
||||
"execution(* net.sqlcipher.database.SQLiteDatabase.insertOrThrow(..)) || " +
|
||||
"execution(* net.sqlcipher.database.SQLiteDatabase.insertWithOnConflict(..)) || " +
|
||||
"execution(* net.sqlcipher.database.SQLiteDatabase.delete(..)) || " +
|
||||
"execution(* net.sqlcipher.database.SQLiteDatabase.update(..))")
|
||||
public void sqlcipherQuery() {}
|
||||
|
||||
@Around("annotatedMethod() || annotatedConstructor() || (sqlcipher() && !sqlcipherQuery())")
|
||||
public @NonNull Object profile(@NonNull ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
String methodName = joinPoint.getSignature().toShortString();
|
||||
|
||||
Tracer.getInstance().start(methodName);
|
||||
Object result = joinPoint.proceed();
|
||||
Tracer.getInstance().end(methodName);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Around("sqlcipherQuery()")
|
||||
public @NonNull Object profileQuery(@NonNull ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
String table;
|
||||
String query;
|
||||
|
||||
if (joinPoint.getSignature().getName().equals("query")) {
|
||||
if (joinPoint.getArgs().length == 9) {
|
||||
table = (String) joinPoint.getArgs()[1];
|
||||
query = (String) joinPoint.getArgs()[3];
|
||||
} else if (joinPoint.getArgs().length == 7 || joinPoint.getArgs().length == 8) {
|
||||
table = (String) joinPoint.getArgs()[0];
|
||||
query = (String) joinPoint.getArgs()[2];
|
||||
} else {
|
||||
table = "N/A";
|
||||
query = "N/A";
|
||||
}
|
||||
} else if (joinPoint.getSignature().getName().equals("rawQuery")) {
|
||||
table = "";
|
||||
query = (String) joinPoint.getArgs()[0];
|
||||
} else if (joinPoint.getSignature().getName().equals("insert")) {
|
||||
table = (String) joinPoint.getArgs()[0];
|
||||
query = "";
|
||||
} else if (joinPoint.getSignature().getName().equals("insertOrThrow")) {
|
||||
table = (String) joinPoint.getArgs()[0];
|
||||
query = "";
|
||||
} else if (joinPoint.getSignature().getName().equals("insertWithOnConflict")) {
|
||||
table = (String) joinPoint.getArgs()[0];
|
||||
query = "";
|
||||
} else if (joinPoint.getSignature().getName().equals("delete")) {
|
||||
table = (String) joinPoint.getArgs()[0];
|
||||
query = (String) joinPoint.getArgs()[1];
|
||||
} else if (joinPoint.getSignature().getName().equals("update")) {
|
||||
table = (String) joinPoint.getArgs()[0];
|
||||
query = (String) joinPoint.getArgs()[2];
|
||||
} else {
|
||||
table = "N/A";
|
||||
query = "N/A";
|
||||
}
|
||||
|
||||
query = query == null ? "null" : query;
|
||||
query = "[" + table + "] " + query;
|
||||
|
||||
String methodName = joinPoint.getSignature().toShortString();
|
||||
|
||||
Tracer.getInstance().start(methodName, "query", query);
|
||||
Object result = joinPoint.proceed();
|
||||
Tracer.getInstance().end(methodName);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
package org.thoughtcrime.securesms.tracing;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.trace.TraceProtos;
|
||||
import org.thoughtcrime.securesms.trace.TraceProtos.Trace;
|
||||
import org.thoughtcrime.securesms.trace.TraceProtos.TracePacket;
|
||||
import org.thoughtcrime.securesms.trace.TraceProtos.TrackDescriptor;
|
||||
import org.thoughtcrime.securesms.trace.TraceProtos.TrackEvent;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* A class to create Perfetto-compatible traces. Currently keeps the entire trace in memory to
|
||||
* avoid weirdness with synchronizing to disk.
|
||||
*
|
||||
* Some general info on how the Perfetto format works:
|
||||
* - The file format is just a Trace proto (see Trace.proto)
|
||||
* - The Trace proto is just a series of TracePackets
|
||||
* - TracePackets can describe:
|
||||
* - Threads
|
||||
* - Start of a method
|
||||
* - End of a method
|
||||
* - (And a bunch of other stuff that's not relevant to use at this point)
|
||||
*
|
||||
* We keep a circular buffer of TracePackets for method calls, and we keep a separate list of
|
||||
* TracePackets for threads so we don't lose any of those.
|
||||
*
|
||||
* Serializing is just a matter of throwing all the TracePackets we have into a proto.
|
||||
*
|
||||
* Note: This class aims to be largely-thread-safe, but prioritizes speed and memory efficiency
|
||||
* above all else. These methods are going to be called very quickly from every thread imaginable,
|
||||
* and we want to create as little overhead as possible. The idea being that it's ok if we don't,
|
||||
* for example, keep a perfect circular buffer size if it allows us to reduce overhead. The only
|
||||
* cost of screwing up would be dropping a trace packet or something, which, while sad, won't affect
|
||||
* how the app functions.
|
||||
*/
|
||||
public final class TracerImpl implements Tracer {
|
||||
|
||||
private static final int TRUSTED_SEQUENCE_ID = 1;
|
||||
private static final byte[] SYNCHRONIZATION_MARKER = UuidUtil.toByteArray(UUID.fromString("82477a76-b28d-42ba-81dc-33326d57a079"));
|
||||
|
||||
private final Clock clock;
|
||||
private final Map<Long, TracePacket> threadPackets;
|
||||
private final Queue<TracePacket> eventPackets;
|
||||
private final AtomicInteger eventCount;
|
||||
|
||||
TracerImpl() {
|
||||
this.clock = SystemClock::elapsedRealtimeNanos;
|
||||
this.threadPackets = new ConcurrentHashMap<>();
|
||||
this.eventPackets = new ConcurrentLinkedQueue<>();
|
||||
this.eventCount = new AtomicInteger(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NonNull String methodName) {
|
||||
long time = clock.getTimeNanos();
|
||||
Thread currentThread = Thread.currentThread();
|
||||
|
||||
if (!threadPackets.containsKey(currentThread.getId())) {
|
||||
threadPackets.put(currentThread.getId(), forThread(currentThread));
|
||||
}
|
||||
|
||||
addPacket(forMethodStart(methodName, time, currentThread.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NonNull String methodName, @NonNull String key, @NonNull String value) {
|
||||
long time = clock.getTimeNanos();
|
||||
Thread currentThread = Thread.currentThread();
|
||||
|
||||
if (!threadPackets.containsKey(currentThread.getId())) {
|
||||
threadPackets.put(currentThread.getId(), forThread(currentThread));
|
||||
}
|
||||
|
||||
addPacket(forMethodStart(methodName, time, currentThread.getId(), key, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(@NonNull String methodName) {
|
||||
addPacket(forMethodEnd(methodName, clock.getTimeNanos(), Thread.currentThread().getId()));
|
||||
}
|
||||
|
||||
public @NonNull byte[] serialize() {
|
||||
Trace.Builder trace = Trace.newBuilder();
|
||||
|
||||
for (TracePacket thread : threadPackets.values()) {
|
||||
trace.addPacket(thread);
|
||||
}
|
||||
|
||||
for (TracePacket event : eventPackets) {
|
||||
trace.addPacket(event);
|
||||
}
|
||||
|
||||
trace.addPacket(forSynchronization(clock.getTimeNanos()));
|
||||
|
||||
return trace.build().toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to add a packet to our list while keeping the size of our circular buffer in-check.
|
||||
* The tracking of the event count is not perfectly thread-safe, but doing it in a thread-safe
|
||||
* way would likely involve adding a lock, which we really don't want to do, since it'll add
|
||||
* unnecessary overhead.
|
||||
*
|
||||
* Note that we keep track of the event count separately because
|
||||
* {@link ConcurrentLinkedQueue#size()} is NOT a constant-time operation.
|
||||
*/
|
||||
private void addPacket(@NonNull TracePacket packet) {
|
||||
eventPackets.add(packet);
|
||||
|
||||
int size = eventCount.incrementAndGet();
|
||||
|
||||
for (int i = size; i > BuildConfig.TRACE_EVENT_MAX; i--) {
|
||||
eventPackets.poll();
|
||||
eventCount.decrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
private static TracePacket forThread(@NonNull Thread thread) {
|
||||
return TracePacket.newBuilder()
|
||||
.setTrustedPacketSequenceId(TRUSTED_SEQUENCE_ID)
|
||||
.setTrackDescriptor(TrackDescriptor.newBuilder()
|
||||
.setUuid(thread.getId())
|
||||
.setName(thread.getName()))
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
private static TracePacket forMethodStart(@NonNull String name, long time, long threadId) {
|
||||
return TracePacket.newBuilder()
|
||||
.setTrustedPacketSequenceId(TRUSTED_SEQUENCE_ID)
|
||||
.setTimestamp(time)
|
||||
.setTrackEvent(TrackEvent.newBuilder()
|
||||
.setTrackUuid(threadId)
|
||||
.setName(name)
|
||||
.setType(TrackEvent.Type.TYPE_SLICE_BEGIN))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static TracePacket forMethodStart(@NonNull String name, long time, long threadId, @NonNull String key, @NonNull String value) {
|
||||
return TracePacket.newBuilder()
|
||||
.setTrustedPacketSequenceId(TRUSTED_SEQUENCE_ID)
|
||||
.setTimestamp(time)
|
||||
.setTrackEvent(TrackEvent.newBuilder()
|
||||
.setTrackUuid(threadId)
|
||||
.setName(name)
|
||||
.setType(TrackEvent.Type.TYPE_SLICE_BEGIN)
|
||||
.addDebugAnnotations(TraceProtos.DebugAnnotation.newBuilder()
|
||||
.setName(key)
|
||||
.setStringValue(value)
|
||||
.build()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static TracePacket forMethodEnd(@NonNull String name, long time, long threadId) {
|
||||
return TracePacket.newBuilder()
|
||||
.setTrustedPacketSequenceId(TRUSTED_SEQUENCE_ID)
|
||||
.setTimestamp(time)
|
||||
.setTrackEvent(TrackEvent.newBuilder()
|
||||
.setTrackUuid(threadId)
|
||||
.setName(name)
|
||||
.setType(TrackEvent.Type.TYPE_SLICE_END))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static TracePacket forSynchronization(long time) {
|
||||
return TracePacket.newBuilder()
|
||||
.setTrustedPacketSequenceId(TRUSTED_SEQUENCE_ID)
|
||||
.setTimestamp(time)
|
||||
.setSynchronizationMarker(ByteString.copyFrom(SYNCHRONIZATION_MARKER))
|
||||
.build();
|
||||
}
|
||||
|
||||
private interface Clock {
|
||||
long getTimeNanos();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package signal;
|
||||
|
||||
option java_package = "org.thoughtcrime.securesms.trace";
|
||||
option java_outer_classname = "TraceProtos";
|
||||
|
||||
/*
|
||||
* Minimal interface needed to work with Perfetto.
|
||||
*
|
||||
* https://cs.android.com/android/platform/superproject/+/master:external/perfetto/protos/perfetto/trace/trace.proto
|
||||
*/
|
||||
message Trace {
|
||||
repeated TracePacket packet = 1;
|
||||
}
|
||||
|
||||
message TracePacket {
|
||||
optional uint64 timestamp = 8;
|
||||
optional uint32 timestamp_clock_id = 58;
|
||||
|
||||
oneof data {
|
||||
TrackEvent track_event = 11;
|
||||
TrackDescriptor track_descriptor = 60;
|
||||
bytes synchronization_marker = 36;
|
||||
}
|
||||
|
||||
oneof optional_trusted_packet_sequence_id {
|
||||
uint32 trusted_packet_sequence_id = 10;
|
||||
}
|
||||
}
|
||||
|
||||
message TrackEvent {
|
||||
repeated uint64 category_iids = 3;
|
||||
repeated string categories = 22;
|
||||
|
||||
repeated DebugAnnotation debug_annotations = 4;
|
||||
|
||||
oneof name_field {
|
||||
uint64 name_iid = 10;
|
||||
string name = 23;
|
||||
}
|
||||
|
||||
enum Type {
|
||||
TYPE_UNSPECIFIED = 0;
|
||||
TYPE_SLICE_BEGIN = 1;
|
||||
TYPE_SLICE_END = 2;
|
||||
TYPE_INSTANT = 3;
|
||||
TYPE_COUNTER = 4;
|
||||
}
|
||||
|
||||
optional Type type = 9;
|
||||
optional uint64 track_uuid = 11;
|
||||
optional int64 counter_value = 30;
|
||||
|
||||
oneof timestamp {
|
||||
int64 timestamp_delta_us = 1;
|
||||
int64 timestamp_absolute_us = 16;
|
||||
}
|
||||
|
||||
oneof thread_time {
|
||||
int64 thread_time_delta_us = 2;
|
||||
int64 thread_time_absolute_us = 17;
|
||||
}
|
||||
}
|
||||
|
||||
message TrackDescriptor {
|
||||
optional uint64 uuid = 1;
|
||||
optional uint64 parent_uuid = 5;
|
||||
optional string name = 2;
|
||||
optional ThreadDescriptor thread = 4;
|
||||
optional CounterDescriptor counter = 8;
|
||||
}
|
||||
|
||||
|
||||
message ThreadDescriptor {
|
||||
optional int32 pid = 1;
|
||||
optional int32 tid = 2;
|
||||
|
||||
optional string thread_name = 5;
|
||||
}
|
||||
|
||||
message CounterDescriptor {
|
||||
enum BuiltinCounterType {
|
||||
COUNTER_UNSPECIFIED = 0;
|
||||
COUNTER_THREAD_TIME_NS = 1;
|
||||
COUNTER_THREAD_INSTRUCTION_COUNT = 2;
|
||||
}
|
||||
|
||||
enum Unit {
|
||||
UNIT_UNSPECIFIED = 0;
|
||||
UNIT_TIME_NS = 1;
|
||||
UNIT_COUNT = 2;
|
||||
UNIT_SIZE_BYTES = 3;
|
||||
}
|
||||
optional BuiltinCounterType type = 1;
|
||||
repeated string categories = 2;
|
||||
optional Unit unit = 3;
|
||||
optional int64 unit_multiplier = 4;
|
||||
optional bool is_incremental = 5;
|
||||
}
|
||||
|
||||
message DebugAnnotation {
|
||||
message NestedValue {
|
||||
enum NestedType {
|
||||
UNSPECIFIED = 0;
|
||||
DICT = 1;
|
||||
ARRAY = 2;
|
||||
}
|
||||
|
||||
optional NestedType nested_type = 1;
|
||||
repeated string dict_keys = 2;
|
||||
repeated NestedValue dict_values = 3;
|
||||
repeated NestedValue array_values = 4;
|
||||
optional int64 int_value = 5;
|
||||
optional double double_value = 6;
|
||||
optional bool bool_value = 7;
|
||||
optional string string_value = 8;
|
||||
}
|
||||
|
||||
oneof name_field {
|
||||
uint64 name_iid = 1;
|
||||
string name = 10;
|
||||
}
|
||||
|
||||
oneof value {
|
||||
bool bool_value = 2;
|
||||
uint64 uint_value = 3;
|
||||
int64 int_value = 4;
|
||||
double double_value = 5;
|
||||
string string_value = 6;
|
||||
uint64 pointer_value = 7;
|
||||
NestedValue nested_value = 8;
|
||||
}
|
||||
}
|
|
@ -71,6 +71,7 @@ import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
|
|||
import org.thoughtcrime.securesms.service.UpdateApkRefreshListener;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
@ -93,6 +94,7 @@ import java.util.concurrent.TimeUnit;
|
|||
*
|
||||
* @author Moxie Marlinspike
|
||||
*/
|
||||
@Trace
|
||||
public class ApplicationContext extends MultiDexApplication implements DefaultLifecycleObserver {
|
||||
|
||||
private static final String TAG = ApplicationContext.class.getSimpleName();
|
||||
|
|
|
@ -6,10 +6,12 @@ import android.os.Bundle;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
@Trace
|
||||
public class MainActivity extends PassphraseRequiredActivity {
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
|||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.sms.IncomingJoinedMessage;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.ProfileUtil;
|
||||
import org.thoughtcrime.securesms.util.SetUtil;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
|
@ -72,6 +73,7 @@ import java.util.concurrent.TimeoutException;
|
|||
/**
|
||||
* Manages all the stuff around determining if a user is registered or not.
|
||||
*/
|
||||
@Trace
|
||||
public class DirectoryHelper {
|
||||
|
||||
private static final String TAG = Log.tag(DirectoryHelper.class);
|
||||
|
|
|
@ -234,6 +234,7 @@ import org.thoughtcrime.securesms.stickers.StickerLocator;
|
|||
import org.thoughtcrime.securesms.stickers.StickerManagementActivity;
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent;
|
||||
import org.thoughtcrime.securesms.stickers.StickerSearchRepository;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.AsynchronousCallback;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
|
@ -290,6 +291,7 @@ import static org.whispersystems.libsignal.SessionCipher.SESSION_LOCK;
|
|||
* @author Moxie Marlinspike
|
||||
*
|
||||
*/
|
||||
@Trace
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public class ConversationActivity extends PassphraseRequiredActivity
|
||||
implements ConversationFragment.ConversationFragmentListener,
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
|||
import org.thoughtcrime.securesms.database.model.Mention;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.util.paging.Invalidator;
|
||||
import org.thoughtcrime.securesms.util.paging.SizeFixResult;
|
||||
|
@ -32,6 +33,7 @@ import java.util.concurrent.Executor;
|
|||
/**
|
||||
* Core data source for loading an individual conversation.
|
||||
*/
|
||||
@Trace
|
||||
class ConversationDataSource extends PositionalDataSource<ConversationMessage> {
|
||||
|
||||
private static final String TAG = Log.tag(ConversationDataSource.class);
|
||||
|
|
|
@ -119,6 +119,7 @@ import org.thoughtcrime.securesms.sms.MessageSender;
|
|||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.CachedInflater;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.HtmlUtil;
|
||||
|
@ -144,6 +145,7 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
@Trace
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public class ConversationFragment extends LoggingFragment {
|
||||
private static final String TAG = ConversationFragment.class.getSimpleName();
|
||||
|
|
|
@ -37,11 +37,13 @@ import com.google.android.material.snackbar.Snackbar;
|
|||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.registration.PulsingFloatingActionButton;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.task.SnackbarAsyncTask;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@Trace
|
||||
public class ConversationListArchiveFragment extends ConversationListFragment implements ActionMode.Callback
|
||||
{
|
||||
private RecyclerView list;
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
|||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.ThrottledDebouncer;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.util.paging.Invalidator;
|
||||
|
@ -30,6 +31,7 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Trace
|
||||
abstract class ConversationListDataSource extends PositionalDataSource<Conversation> {
|
||||
|
||||
public static final Executor EXECUTOR = SignalExecutors.newFixedLifoThreadExecutor("signal-conversation-list", 1, 1);
|
||||
|
|
|
@ -116,6 +116,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
|||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.AvatarUtil;
|
||||
import org.thoughtcrime.securesms.util.PlayStoreUtil;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
|
@ -140,6 +141,7 @@ import java.util.Set;
|
|||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
|
||||
@Trace
|
||||
public class ConversationListFragment extends MainFragment implements ActionMode.Callback,
|
||||
ConversationListAdapter.OnConversationClickListener,
|
||||
ConversationListSearchAdapter.EventListener,
|
||||
|
|
|
@ -54,6 +54,7 @@ import org.thoughtcrime.securesms.mms.MediaStream;
|
|||
import org.thoughtcrime.securesms.mms.MmsException;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.FileUtils;
|
||||
|
@ -83,6 +84,7 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Trace
|
||||
public class AttachmentDatabase extends Database {
|
||||
|
||||
private static final String TAG = AttachmentDatabase.class.getSimpleName();
|
||||
|
|
|
@ -12,11 +12,13 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Trace
|
||||
public class DraftDatabase extends Database {
|
||||
|
||||
static final String TABLE_NAME = "drafts";
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.groups.GroupId;
|
|||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
@ -46,6 +47,7 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
@Trace
|
||||
public final class GroupDatabase extends Database {
|
||||
|
||||
private static final String TAG = Log.tag(GroupDatabase.class);
|
||||
|
|
|
@ -11,12 +11,14 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@Trace
|
||||
public class GroupReceiptDatabase extends Database {
|
||||
|
||||
public static final String TABLE_NAME = "group_receipts";
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
|||
import org.thoughtcrime.securesms.database.identity.IdentityRecordList;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.whispersystems.libsignal.IdentityKey;
|
||||
|
@ -40,6 +41,7 @@ import java.io.IOException;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@Trace
|
||||
public class IdentityDatabase extends Database {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
|
|
@ -14,10 +14,12 @@ import org.thoughtcrime.securesms.jobmanager.persistence.ConstraintSpec;
|
|||
import org.thoughtcrime.securesms.jobmanager.persistence.DependencySpec;
|
||||
import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec;
|
||||
import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@Trace
|
||||
public class JobDatabase extends Database {
|
||||
|
||||
public static String JOBS_TABLE_NAME = "job_spec";
|
||||
|
|
|
@ -10,10 +10,12 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.keyvalue.KeyValueDataSet;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@Trace
|
||||
public class KeyValueDatabase extends Database {
|
||||
|
||||
public static final String TABLE_NAME = "key_value";
|
||||
|
|
|
@ -12,10 +12,12 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Trace
|
||||
public class MediaDatabase extends Database {
|
||||
|
||||
public static final int ALL_THREADS = -1;
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
|||
import org.thoughtcrime.securesms.database.model.MegaphoneRecord;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.megaphone.Megaphones.Event;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -22,6 +23,7 @@ import java.util.Set;
|
|||
/**
|
||||
* IMPORTANT: Writes should only be made through {@link org.thoughtcrime.securesms.megaphone.MegaphoneRepository}.
|
||||
*/
|
||||
@Trace
|
||||
public class MegaphoneDatabase extends Database {
|
||||
|
||||
private static final String TAG = Log.tag(MegaphoneDatabase.class);
|
||||
|
|
|
@ -15,6 +15,7 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.database.model.Mention;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
|
||||
|
@ -24,6 +25,7 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Trace
|
||||
public class MentionDatabase extends Database {
|
||||
|
||||
static final String TABLE_NAME = "mention";
|
||||
|
|
|
@ -72,6 +72,7 @@ import org.thoughtcrime.securesms.revealable.ViewOnceExpirationInfo;
|
|||
import org.thoughtcrime.securesms.revealable.ViewOnceUtil;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
|
@ -94,6 +95,7 @@ import java.util.Set;
|
|||
|
||||
import static org.thoughtcrime.securesms.contactshare.Contact.Avatar;
|
||||
|
||||
@Trace
|
||||
public class MmsDatabase extends MessageDatabase {
|
||||
|
||||
private static final String TAG = MmsDatabase.class.getSimpleName();
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord;
|
|||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
@ -41,6 +42,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Trace
|
||||
public class MmsSmsDatabase extends Database {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
|
||||
|
@ -18,6 +19,7 @@ import org.whispersystems.signalservice.internal.util.Util;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
@Trace
|
||||
public class PushDatabase extends Database {
|
||||
|
||||
private static final String TAG = PushDatabase.class.getSimpleName();
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
|||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper.RecordUpdate;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncModels;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.Bitmask;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
|
@ -80,6 +81,7 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Trace
|
||||
public class RecipientDatabase extends Database {
|
||||
|
||||
private static final String TAG = RecipientDatabase.class.getSimpleName();
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -20,6 +21,7 @@ import java.util.Map;
|
|||
/**
|
||||
* The backing datastore for {@link RemappedRecords}. See that class for more details.
|
||||
*/
|
||||
@Trace
|
||||
public class RemappedRecordsDatabase extends Database {
|
||||
|
||||
public static final String[] CREATE_TABLE = { Recipients.CREATE_TABLE,
|
||||
|
|
|
@ -11,10 +11,12 @@ import net.sqlcipher.Cursor;
|
|||
import net.sqlcipher.database.SQLiteDatabase;
|
||||
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
|
||||
/**
|
||||
* Contains all databases necessary for full-text search (FTS).
|
||||
*/
|
||||
@Trace
|
||||
public class SearchDatabase extends Database {
|
||||
|
||||
public static final String SMS_FTS_TABLE_NAME = "sms_fts";
|
||||
|
|
|
@ -12,6 +12,7 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
import org.whispersystems.libsignal.state.SessionRecord;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
|
@ -20,6 +21,7 @@ import java.io.IOException;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@Trace
|
||||
public class SessionDatabase extends Database {
|
||||
|
||||
private static final String TAG = SessionDatabase.class.getSimpleName();
|
||||
|
|
|
@ -11,6 +11,7 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.whispersystems.libsignal.InvalidKeyException;
|
||||
import org.whispersystems.libsignal.ecc.Curve;
|
||||
|
@ -23,6 +24,7 @@ import java.io.IOException;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@Trace
|
||||
public class SignedPreKeyDatabase extends Database {
|
||||
|
||||
private static final String TAG = SignedPreKeyDatabase.class.getSimpleName();
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.thoughtcrime.securesms.revealable.ViewOnceExpirationInfo;
|
|||
import org.thoughtcrime.securesms.sms.IncomingGroupUpdateMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
|
@ -74,6 +75,7 @@ import java.util.Set;
|
|||
*
|
||||
* @author Moxie Marlinspike
|
||||
*/
|
||||
@Trace
|
||||
public class SmsDatabase extends MessageDatabase {
|
||||
|
||||
private static final String TAG = SmsDatabase.class.getSimpleName();
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.logging.Log;
|
|||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||
import org.thoughtcrime.securesms.stickers.BlessedPacks;
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
@ -36,6 +37,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Trace
|
||||
public class StickerDatabase extends Database {
|
||||
|
||||
private static final String TAG = Log.tag(StickerDatabase.class);
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.annotation.Nullable;
|
|||
import net.sqlcipher.database.SQLiteDatabase;
|
||||
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
|
||||
import org.whispersystems.signalservice.api.storage.StorageId;
|
||||
|
@ -23,6 +24,7 @@ import java.util.List;
|
|||
* A list of storage keys whose types we do not currently have syncing logic for. We need to
|
||||
* remember that these keys exist so that we don't blast any data away.
|
||||
*/
|
||||
@Trace
|
||||
public class StorageKeyDatabase extends Database {
|
||||
|
||||
private static final String TABLE_NAME = "storage_key";
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.thoughtcrime.securesms.recipients.RecipientDetails;
|
|||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
|
@ -76,6 +77,7 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@Trace
|
||||
public class ThreadDatabase extends Database {
|
||||
|
||||
private static final String TAG = ThreadDatabase.class.getSimpleName();
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.jobmanager.Job;
|
|||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
@ -51,6 +52,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Trace
|
||||
public final class PushDecryptMessageJob extends BaseJob {
|
||||
|
||||
public static final String KEY = "PushDecryptJob";
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
|||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
|
@ -69,6 +70,7 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Trace
|
||||
public final class PushGroupSendJob extends PushSendJob {
|
||||
|
||||
public static final String KEY = "PushGroupSendJob";
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
|||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
||||
|
@ -48,6 +49,7 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Trace
|
||||
public class PushMediaSendJob extends PushSendJob {
|
||||
|
||||
public static final String KEY = "PushMediaSendJob";
|
||||
|
|
|
@ -81,6 +81,7 @@ import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage;
|
|||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.Hex;
|
||||
|
@ -133,6 +134,7 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Trace
|
||||
public final class PushProcessMessageJob extends BaseJob {
|
||||
|
||||
public static final String KEY = "PushProcessJob";
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
|||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
@ -33,6 +34,7 @@ import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserExce
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
@Trace
|
||||
public class PushTextSendJob extends PushSendJob {
|
||||
|
||||
public static final String KEY = "PushTextSendJob";
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.profiles.ProfileName;
|
|||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
|
@ -66,6 +67,7 @@ import java.util.concurrent.TimeoutException;
|
|||
/**
|
||||
* Retrieves a users profile and sets the appropriate local fields.
|
||||
*/
|
||||
@Trace
|
||||
public class RetrieveProfileJob extends BaseJob {
|
||||
|
||||
public static final String KEY = "RetrieveProfileJob";
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.storage.StorageSyncHelper.MergeResult;
|
|||
import org.thoughtcrime.securesms.storage.StorageSyncHelper.WriteOperationResult;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncModels;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncValidations;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
@ -56,6 +57,7 @@ import java.util.concurrent.TimeUnit;
|
|||
* This should be performed whenever a change is made locally, or whenever we want to retrieve
|
||||
* changes that have been made remotely.
|
||||
*/
|
||||
@Trace
|
||||
public class StorageSyncJob extends BaseJob {
|
||||
|
||||
public static final String KEY = "StorageSyncJob";
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package org.thoughtcrime.securesms.logsubmit;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.tracing.Tracer;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class LogSectionTrace implements LogSection {
|
||||
|
||||
@Override
|
||||
public @NonNull String getTitle() {
|
||||
return "TRACE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CharSequence getContent(@NonNull Context context) {
|
||||
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream compressedStream = new GZIPOutputStream(outputStream))
|
||||
{
|
||||
compressedStream.write(Tracer.getInstance().serialize());
|
||||
compressedStream.flush();
|
||||
compressedStream.close();
|
||||
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
return Base64.encodeBytes(outputStream.toByteArray());
|
||||
} catch (IOException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
|
||||
public class SubmitDebugLogAdapter extends RecyclerView.Adapter<SubmitDebugLogAdapter.LineViewHolder> {
|
||||
|
||||
private static final int MAX_LINE_LENGTH = 1000;
|
||||
|
||||
private final List<LogLine> lines;
|
||||
private final ScrollManager scrollManager;
|
||||
private final Listener listener;
|
||||
|
@ -68,6 +70,7 @@ public class SubmitDebugLogAdapter extends RecyclerView.Adapter<SubmitDebugLogAd
|
|||
this.lines.addAll(lines);
|
||||
|
||||
this.longestLine = Stream.of(lines).reduce(0, (currentMax, line) -> Math.max(currentMax, line.getText().length()));
|
||||
this.longestLine = Math.min(longestLine, MAX_LINE_LENGTH);
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
@ -122,7 +125,9 @@ public class SubmitDebugLogAdapter extends RecyclerView.Adapter<SubmitDebugLogAd
|
|||
void bind(@NonNull LogLine line, int longestLine, boolean editing, @NonNull ScrollManager scrollManager, @NonNull Listener listener) {
|
||||
Context context = itemView.getContext();
|
||||
|
||||
if (line.getText().length() < longestLine) {
|
||||
if (line.getText().length() > longestLine) {
|
||||
text.setText(line.getText().substring(0, longestLine));
|
||||
} else if (line.getText().length() < longestLine) {
|
||||
text.setText(padRight(line.getText(), longestLine));
|
||||
} else {
|
||||
text.setText(line.getText());
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.logging.Log;
|
|||
import org.thoughtcrime.securesms.logsubmit.util.Scrubber;
|
||||
import org.thoughtcrime.securesms.net.StandardUserAgentInterceptor;
|
||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||
import org.thoughtcrime.securesms.tracing.Tracer;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
|
@ -60,6 +61,9 @@ public class SubmitDebugLogRepository {
|
|||
add(new LogSectionCapabilities());
|
||||
add(new LogSectionFeatureFlags());
|
||||
add(new LogSectionPermissions());
|
||||
if (Tracer.getInstance().isEnabled()) {
|
||||
add(new LogSectionTrace());
|
||||
}
|
||||
add(new LogSectionThreads());
|
||||
add(new LogSectionLogcat());
|
||||
add(new LogSectionLogger());
|
||||
|
|
|
@ -389,6 +389,7 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressLint({"MissingPermission"})
|
||||
private void initializeFlipButton(@NonNull View flipButton, @NonNull CameraXFlashToggleView flashButton) {
|
||||
if (camera.hasCameraWithLensFacing(CameraSelector.LENS_FACING_FRONT) && camera.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK)) {
|
||||
flipButton.setVisibility(View.VISIBLE);
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
|||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.SetUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
@ -52,6 +53,7 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Trace
|
||||
public final class StorageSyncHelper {
|
||||
|
||||
private static final String TAG = Log.tag(StorageSyncHelper.class);
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package org.thoughtcrime.securesms.tracing;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.CONSTRUCTOR;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.CLASS;
|
||||
|
||||
@Target({TYPE, METHOD, CONSTRUCTOR}) @Retention(CLASS)
|
||||
public @interface Trace {
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package org.thoughtcrime.securesms.tracing;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* A class to create Perfetto-compatible traces.
|
||||
*/
|
||||
public interface Tracer {
|
||||
|
||||
TracerImpl INSTANCE = new TracerImpl();
|
||||
|
||||
static @NonNull Tracer getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if enabled, otherwise false.
|
||||
*/
|
||||
boolean isEnabled();
|
||||
|
||||
/**
|
||||
* Marks the start of a method call. Always follow this with a call to {@link #end(String)}.
|
||||
*/
|
||||
void start(@NonNull String methodName);
|
||||
|
||||
/**
|
||||
* Marks the start of a method call. Always follow this with a call to {@link #end(String)}.
|
||||
*
|
||||
* Includes the ability to pass a key-value pair that will be shown in the trace when you click
|
||||
* on the slice.
|
||||
*/
|
||||
void start(@NonNull String methodName, @NonNull String key, @NonNull String value);
|
||||
|
||||
/**
|
||||
* Marks the end of a method call.
|
||||
*/
|
||||
void end(@NonNull String methodName);
|
||||
|
||||
/**
|
||||
* Serializes the current state of the trace to a Perfetto-compatible byte array. Note that
|
||||
* there's no locking here, and therefore tracing will continue. We're just grabbing a best-effort
|
||||
* snapshot.
|
||||
*/
|
||||
@NonNull byte[] serialize();
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.thoughtcrime.securesms.tracing;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Dummy implementation.
|
||||
*/
|
||||
final class TracerImpl implements Tracer {
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NonNull String methodName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NonNull String methodName, @NonNull String key, @NonNull String value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(@NonNull String methodName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull byte[] serialize() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.thoughtcrime.securesms.tracing;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Dummy implementation.
|
||||
*/
|
||||
final class TracerImpl implements Tracer {
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NonNull String methodName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NonNull String methodName, @NonNull String key, @NonNull String value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(@NonNull String methodName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull byte[] serialize() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue