251 lines
11 KiB
Java
251 lines
11 KiB
Java
package com.squareup.leakcanary.internal;
|
|
|
|
import android.content.Context;
|
|
import android.content.res.Resources;
|
|
import android.text.Html;
|
|
import android.text.SpannableStringBuilder;
|
|
import android.text.Spanned;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.BaseAdapter;
|
|
import android.widget.TextView;
|
|
import com.squareup.leakcanary.Exclusion;
|
|
import com.squareup.leakcanary.LeakReference;
|
|
import com.squareup.leakcanary.LeakTrace;
|
|
import com.squareup.leakcanary.LeakTraceElement;
|
|
import com.squareup.leakcanary.R;
|
|
import com.squareup.leakcanary.Reachability;
|
|
import com.squareup.leakcanary.internal.DisplayLeakConnectorView;
|
|
|
|
/* loaded from: classes.dex */
|
|
final class DisplayLeakAdapter extends BaseAdapter {
|
|
private static final int NORMAL_ROW = 1;
|
|
private static final int TOP_ROW = 0;
|
|
private final String classNameColorHexString;
|
|
private final String extraColorHexString;
|
|
private final String helpColorHexString;
|
|
private final String leakColorHexString;
|
|
private final String referenceColorHexString;
|
|
private String referenceKey;
|
|
private boolean[] opened = new boolean[0];
|
|
private LeakTrace leakTrace = null;
|
|
private String referenceName = "";
|
|
|
|
/* renamed from: com.squareup.leakcanary.internal.DisplayLeakAdapter$1, reason: invalid class name */
|
|
static /* synthetic */ class AnonymousClass1 {
|
|
static final /* synthetic */ int[] $SwitchMap$com$squareup$leakcanary$Reachability = new int[Reachability.values().length];
|
|
|
|
static {
|
|
try {
|
|
$SwitchMap$com$squareup$leakcanary$Reachability[Reachability.UNKNOWN.ordinal()] = 1;
|
|
} catch (NoSuchFieldError unused) {
|
|
}
|
|
try {
|
|
$SwitchMap$com$squareup$leakcanary$Reachability[Reachability.REACHABLE.ordinal()] = 2;
|
|
} catch (NoSuchFieldError unused2) {
|
|
}
|
|
try {
|
|
$SwitchMap$com$squareup$leakcanary$Reachability[Reachability.UNREACHABLE.ordinal()] = 3;
|
|
} catch (NoSuchFieldError unused3) {
|
|
}
|
|
}
|
|
}
|
|
|
|
DisplayLeakAdapter(Resources resources) {
|
|
this.classNameColorHexString = hexStringColor(resources, R.color.leak_canary_class_name);
|
|
this.leakColorHexString = hexStringColor(resources, R.color.leak_canary_leak);
|
|
this.referenceColorHexString = hexStringColor(resources, R.color.leak_canary_reference);
|
|
this.extraColorHexString = hexStringColor(resources, R.color.leak_canary_extra);
|
|
this.helpColorHexString = hexStringColor(resources, R.color.leak_canary_help);
|
|
}
|
|
|
|
private int elementIndex(int i) {
|
|
return i - 2;
|
|
}
|
|
|
|
private static <T extends View> T findById(View view, int i) {
|
|
return (T) view.findViewById(i);
|
|
}
|
|
|
|
private DisplayLeakConnectorView.Type getConnectorType(int i) {
|
|
if (i == 1) {
|
|
return DisplayLeakConnectorView.Type.HELP;
|
|
}
|
|
if (i == 2) {
|
|
return this.leakTrace.expectedReachability.size() == 1 ? DisplayLeakConnectorView.Type.START_LAST_REACHABLE : this.leakTrace.expectedReachability.get(elementIndex(i + 1)) != Reachability.REACHABLE ? DisplayLeakConnectorView.Type.START_LAST_REACHABLE : DisplayLeakConnectorView.Type.START;
|
|
}
|
|
if (i == getCount() - 1) {
|
|
return this.leakTrace.expectedReachability.get(elementIndex(i - 1)) != Reachability.UNREACHABLE ? DisplayLeakConnectorView.Type.END_FIRST_UNREACHABLE : DisplayLeakConnectorView.Type.END;
|
|
}
|
|
Reachability reachability = this.leakTrace.expectedReachability.get(elementIndex(i));
|
|
int i2 = AnonymousClass1.$SwitchMap$com$squareup$leakcanary$Reachability[reachability.ordinal()];
|
|
if (i2 == 1) {
|
|
return DisplayLeakConnectorView.Type.NODE_UNKNOWN;
|
|
}
|
|
if (i2 == 2) {
|
|
return this.leakTrace.expectedReachability.get(elementIndex(i + 1)) != Reachability.REACHABLE ? DisplayLeakConnectorView.Type.NODE_LAST_REACHABLE : DisplayLeakConnectorView.Type.NODE_REACHABLE;
|
|
}
|
|
if (i2 == 3) {
|
|
return this.leakTrace.expectedReachability.get(elementIndex(i - 1)) != Reachability.UNREACHABLE ? DisplayLeakConnectorView.Type.NODE_FIRST_UNREACHABLE : DisplayLeakConnectorView.Type.NODE_UNREACHABLE;
|
|
}
|
|
throw new IllegalStateException("Unknown value: " + reachability);
|
|
}
|
|
|
|
private static String hexStringColor(Resources resources, int i) {
|
|
return String.format("#%06X", Integer.valueOf(resources.getColor(i) & 16777215));
|
|
}
|
|
|
|
private Spanned htmlDetails(boolean z, LeakTraceElement leakTraceElement) {
|
|
String str;
|
|
if (leakTraceElement.extra != null) {
|
|
str = " <font color='" + this.extraColorHexString + "'>" + leakTraceElement.extra + "</font>";
|
|
} else {
|
|
str = "";
|
|
}
|
|
Exclusion exclusion = leakTraceElement.exclusion;
|
|
if (exclusion != null) {
|
|
String str2 = str + "<br/><br/>Excluded by rule";
|
|
if (exclusion.name != null) {
|
|
str2 = str2 + " <font color='#ffffff'>" + exclusion.name + "</font>";
|
|
}
|
|
str = str2 + " matching <font color='#f3cf83'>" + exclusion.matching + "</font>";
|
|
if (exclusion.reason != null) {
|
|
str = str + " because <font color='#f3cf83'>" + exclusion.reason + "</font>";
|
|
}
|
|
}
|
|
String str3 = str + "<br><font color='" + this.extraColorHexString + "'>" + leakTraceElement.toDetailedString().replace("\n", "<br>") + "</font>";
|
|
if (z && !this.referenceName.equals("")) {
|
|
str3 = str3 + " <font color='" + this.extraColorHexString + "'>" + this.referenceName + "</font>";
|
|
}
|
|
return Html.fromHtml(str3);
|
|
}
|
|
|
|
private Spanned htmlTitle(LeakTraceElement leakTraceElement, boolean z, Resources resources) {
|
|
String str;
|
|
String str2;
|
|
String str3 = "<font color='" + this.classNameColorHexString + "'>" + leakTraceElement.getSimpleClassName().replace("[]", "[ ]") + "</font>";
|
|
LeakReference leakReference = leakTraceElement.reference;
|
|
if (leakReference != null) {
|
|
String replaceAll = leakReference.getDisplayName().replaceAll("<", "<").replaceAll(">", ">");
|
|
if (z) {
|
|
str2 = "<u><font color='" + this.leakColorHexString + "'>" + replaceAll + "</font></u>";
|
|
} else {
|
|
str2 = "<font color='" + this.referenceColorHexString + "'>" + replaceAll + "</font>";
|
|
}
|
|
if (leakTraceElement.reference.type == LeakTraceElement.Type.STATIC_FIELD) {
|
|
str2 = "<i>" + str2 + "</i>";
|
|
}
|
|
String str4 = str3 + "." + str2;
|
|
if (z) {
|
|
str4 = "<b>" + str4 + "</b>";
|
|
}
|
|
str = "" + str4;
|
|
} else {
|
|
str = "" + str3;
|
|
}
|
|
if (leakTraceElement.exclusion != null) {
|
|
str = str + " (excluded)";
|
|
}
|
|
SpannableStringBuilder spannableStringBuilder = (SpannableStringBuilder) Html.fromHtml(str);
|
|
if (z) {
|
|
SquigglySpan.replaceUnderlineSpans(spannableStringBuilder, resources);
|
|
}
|
|
return spannableStringBuilder;
|
|
}
|
|
|
|
@Override // android.widget.Adapter
|
|
public int getCount() {
|
|
LeakTrace leakTrace = this.leakTrace;
|
|
if (leakTrace == null) {
|
|
return 2;
|
|
}
|
|
return leakTrace.elements.size() + 2;
|
|
}
|
|
|
|
@Override // android.widget.Adapter
|
|
public long getItemId(int i) {
|
|
return i;
|
|
}
|
|
|
|
@Override // android.widget.BaseAdapter, android.widget.Adapter
|
|
public int getItemViewType(int i) {
|
|
return i == 0 ? 0 : 1;
|
|
}
|
|
|
|
@Override // android.widget.Adapter
|
|
public View getView(int i, View view, ViewGroup viewGroup) {
|
|
Context context = viewGroup.getContext();
|
|
boolean z = false;
|
|
if (getItemViewType(i) == 0) {
|
|
if (view == null) {
|
|
view = LayoutInflater.from(context).inflate(R.layout.leak_canary_ref_top_row, viewGroup, false);
|
|
}
|
|
((TextView) findById(view, R.id.leak_canary_row_text)).setText(context.getPackageName());
|
|
} else {
|
|
if (view == null) {
|
|
view = LayoutInflater.from(context).inflate(R.layout.leak_canary_ref_row, viewGroup, false);
|
|
}
|
|
TextView textView = (TextView) findById(view, R.id.leak_canary_row_title);
|
|
TextView textView2 = (TextView) findById(view, R.id.leak_canary_row_details);
|
|
DisplayLeakConnectorView displayLeakConnectorView = (DisplayLeakConnectorView) findById(view, R.id.leak_canary_row_connector);
|
|
MoreDetailsView moreDetailsView = (MoreDetailsView) findById(view, R.id.leak_canary_row_more);
|
|
displayLeakConnectorView.setType(getConnectorType(i));
|
|
moreDetailsView.setOpened(this.opened[i]);
|
|
if (this.opened[i]) {
|
|
textView2.setVisibility(0);
|
|
} else {
|
|
textView2.setVisibility(8);
|
|
}
|
|
Resources resources = view.getResources();
|
|
if (i == 1) {
|
|
textView.setText(Html.fromHtml("<font color='" + this.helpColorHexString + "'><b>" + resources.getString(R.string.leak_canary_help_title) + "</b></font>"));
|
|
SpannableStringBuilder spannableStringBuilder = (SpannableStringBuilder) Html.fromHtml(resources.getString(R.string.leak_canary_help_detail));
|
|
SquigglySpan.replaceUnderlineSpans(spannableStringBuilder, resources);
|
|
textView2.setText(spannableStringBuilder);
|
|
} else {
|
|
boolean z2 = i == getCount() - 1;
|
|
LeakTraceElement item = getItem(i);
|
|
Reachability reachability = this.leakTrace.expectedReachability.get(elementIndex(i));
|
|
if (!z2 && reachability != Reachability.UNREACHABLE && this.leakTrace.expectedReachability.get(elementIndex(i + 1)) != Reachability.REACHABLE) {
|
|
z = true;
|
|
}
|
|
textView.setText(htmlTitle(item, z, resources));
|
|
if (this.opened[i]) {
|
|
textView2.setText(htmlDetails(z2, item));
|
|
}
|
|
}
|
|
}
|
|
return view;
|
|
}
|
|
|
|
@Override // android.widget.BaseAdapter, android.widget.Adapter
|
|
public int getViewTypeCount() {
|
|
return 2;
|
|
}
|
|
|
|
public void toggleRow(int i) {
|
|
this.opened[i] = !r0[i];
|
|
notifyDataSetChanged();
|
|
}
|
|
|
|
public void update(LeakTrace leakTrace, String str, String str2) {
|
|
if (str.equals(this.referenceKey)) {
|
|
return;
|
|
}
|
|
this.referenceKey = str;
|
|
this.referenceName = str2;
|
|
this.leakTrace = leakTrace;
|
|
this.opened = new boolean[leakTrace.elements.size() + 2];
|
|
notifyDataSetChanged();
|
|
}
|
|
|
|
@Override // android.widget.Adapter
|
|
public LeakTraceElement getItem(int i) {
|
|
if (getItemViewType(i) == 0 || i == 1) {
|
|
return null;
|
|
}
|
|
return this.leakTrace.elements.get(elementIndex(i));
|
|
}
|
|
}
|