jimu-decompiled/sources/com/squareup/leakcanary/DefaultLeakDirectoryProvider.java
2025-05-13 19:24:51 +02:00

165 lines
7.2 KiB
Java

package com.squareup.leakcanary;
import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import com.squareup.leakcanary.internal.LeakCanaryInternals;
import com.squareup.leakcanary.internal.RequestStoragePermissionActivity;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
/* loaded from: classes.dex */
public final class DefaultLeakDirectoryProvider implements LeakDirectoryProvider {
private static final int ANALYSIS_MAX_DURATION_MS = 600000;
private static final int DEFAULT_MAX_STORED_HEAP_DUMPS = 7;
private static final String HPROF_SUFFIX = ".hprof";
private static final String PENDING_HEAPDUMP_SUFFIX = "_pending.hprof";
private final Context context;
private final int maxStoredHeapDumps;
private volatile boolean permissionNotificationDisplayed;
private volatile boolean writeExternalStorageGranted;
public DefaultLeakDirectoryProvider(Context context) {
this(context, 7);
}
private File appStorageDirectory() {
return new File(this.context.getFilesDir(), "leakcanary");
}
private void cleanupOldHeapDumps() {
List<File> listFiles = listFiles(new FilenameFilter() { // from class: com.squareup.leakcanary.DefaultLeakDirectoryProvider.3
@Override // java.io.FilenameFilter
public boolean accept(File file, String str) {
return str.endsWith(DefaultLeakDirectoryProvider.HPROF_SUFFIX);
}
});
int size = listFiles.size() - this.maxStoredHeapDumps;
if (size > 0) {
CanaryLog.d("Removing %d heap dumps", Integer.valueOf(size));
Collections.sort(listFiles, new Comparator<File>() { // from class: com.squareup.leakcanary.DefaultLeakDirectoryProvider.4
@Override // java.util.Comparator
public int compare(File file, File file2) {
return Long.valueOf(file.lastModified()).compareTo(Long.valueOf(file2.lastModified()));
}
});
for (int i = 0; i < size; i++) {
if (!listFiles.get(i).delete()) {
CanaryLog.d("Could not delete old hprof file %s", listFiles.get(i).getPath());
}
}
}
}
private boolean directoryWritableAfterMkdirs(File file) {
return (file.mkdirs() || file.exists()) && file.canWrite();
}
private File externalStorageDirectory() {
return new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "leakcanary-" + this.context.getPackageName());
}
@TargetApi(23)
private boolean hasStoragePermission() {
if (Build.VERSION.SDK_INT < 23 || this.writeExternalStorageGranted) {
return true;
}
this.writeExternalStorageGranted = this.context.checkSelfPermission("android.permission.WRITE_EXTERNAL_STORAGE") == 0;
return this.writeExternalStorageGranted;
}
private void requestWritePermissionNotification() {
if (this.permissionNotificationDisplayed) {
return;
}
this.permissionNotificationDisplayed = true;
PendingIntent createPendingIntent = RequestStoragePermissionActivity.createPendingIntent(this.context);
LeakCanaryInternals.showNotification(this.context, this.context.getString(R.string.leak_canary_permission_notification_title), this.context.getString(R.string.leak_canary_permission_notification_text, this.context.getPackageName()), createPendingIntent, -558907665);
}
@Override // com.squareup.leakcanary.LeakDirectoryProvider
public void clearLeakDirectory() {
for (File file : listFiles(new FilenameFilter() { // from class: com.squareup.leakcanary.DefaultLeakDirectoryProvider.2
@Override // java.io.FilenameFilter
public boolean accept(File file2, String str) {
return !str.endsWith(DefaultLeakDirectoryProvider.PENDING_HEAPDUMP_SUFFIX);
}
})) {
if (!file.delete()) {
CanaryLog.d("Could not delete file %s", file.getPath());
}
}
}
@Override // com.squareup.leakcanary.LeakDirectoryProvider
public List<File> listFiles(FilenameFilter filenameFilter) {
if (!hasStoragePermission()) {
requestWritePermissionNotification();
}
ArrayList arrayList = new ArrayList();
File[] listFiles = externalStorageDirectory().listFiles(filenameFilter);
if (listFiles != null) {
arrayList.addAll(Arrays.asList(listFiles));
}
File[] listFiles2 = appStorageDirectory().listFiles(filenameFilter);
if (listFiles2 != null) {
arrayList.addAll(Arrays.asList(listFiles2));
}
return arrayList;
}
@Override // com.squareup.leakcanary.LeakDirectoryProvider
public File newHeapDumpFile() {
Iterator<File> it = listFiles(new FilenameFilter() { // from class: com.squareup.leakcanary.DefaultLeakDirectoryProvider.1
@Override // java.io.FilenameFilter
public boolean accept(File file, String str) {
return str.endsWith(DefaultLeakDirectoryProvider.PENDING_HEAPDUMP_SUFFIX);
}
}).iterator();
while (it.hasNext()) {
if (System.currentTimeMillis() - it.next().lastModified() < 600000) {
CanaryLog.d("Could not dump heap, previous analysis still is in progress.", new Object[0]);
return HeapDumper.RETRY_LATER;
}
}
cleanupOldHeapDumps();
File externalStorageDirectory = externalStorageDirectory();
if (!directoryWritableAfterMkdirs(externalStorageDirectory)) {
if (hasStoragePermission()) {
String externalStorageState = Environment.getExternalStorageState();
if ("mounted".equals(externalStorageState)) {
CanaryLog.d("Could not create heap dump directory in external storage: [%s]", externalStorageDirectory.getAbsolutePath());
} else {
CanaryLog.d("External storage not mounted, state: %s", externalStorageState);
}
} else {
CanaryLog.d("WRITE_EXTERNAL_STORAGE permission not granted", new Object[0]);
requestWritePermissionNotification();
}
externalStorageDirectory = appStorageDirectory();
if (!directoryWritableAfterMkdirs(externalStorageDirectory)) {
CanaryLog.d("Could not create heap dump directory in app storage: [%s]", externalStorageDirectory.getAbsolutePath());
return HeapDumper.RETRY_LATER;
}
}
return new File(externalStorageDirectory, UUID.randomUUID().toString() + PENDING_HEAPDUMP_SUFFIX);
}
public DefaultLeakDirectoryProvider(Context context, int i) {
if (i < 1) {
throw new IllegalArgumentException("maxStoredHeapDumps must be at least 1");
}
this.context = context.getApplicationContext();
this.maxStoredHeapDumps = i;
}
}