Dialer: Remove persistent logger

* We don't use it
* Simulator: crashed on sharing anyway
* Generally not worth keeping

Change-Id: I5bd966b84997405dc884e7c6b800002770bbe1b7
diff --git a/java/com/android/dialer/binary/common/DialerApplication.java b/java/com/android/dialer/binary/common/DialerApplication.java
index 33164ae..69db1f9 100644
--- a/java/com/android/dialer/binary/common/DialerApplication.java
+++ b/java/com/android/dialer/binary/common/DialerApplication.java
@@ -23,7 +23,6 @@
 
 import com.android.dialer.inject.HasRootComponent;
 import com.android.dialer.notification.NotificationChannelManager;
-import com.android.dialer.persistentlog.PersistentLogger;
 
 /** A common application subclass for all Dialer build variants. */
 public abstract class DialerApplication extends Application implements HasRootComponent {
@@ -34,7 +33,6 @@
   public void onCreate() {
     Trace.beginSection("DialerApplication.onCreate");
     super.onCreate();
-    PersistentLogger.initialize(this);
     NotificationChannelManager.initChannels(this);
     Trace.endSection();
   }
diff --git a/java/com/android/dialer/persistentlog/PersistentLogFileHandler.java b/java/com/android/dialer/persistentlog/PersistentLogFileHandler.java
deleted file mode 100644
index be9bd71..0000000
--- a/java/com/android/dialer/persistentlog/PersistentLogFileHandler.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- * Copyright (C) 2023 The LineageOS 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
- */
-
-package com.android.dialer.persistentlog;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-
-import androidx.annotation.AnyThread;
-import androidx.annotation.MainThread;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.WorkerThread;
-import androidx.core.os.UserManagerCompat;
-import androidx.preference.PreferenceManager;
-
-import com.android.dialer.common.LogUtil;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Handles serialization of byte arrays and read/write them to multiple rotating files. If a logText
- * file exceeds {@code fileSizeLimit} after a write, a new file will be used. if the total number of
- * files exceeds {@code fileCountLimit} the oldest ones will be deleted. The logs are stored in the
- * cache but the file index is stored in the data (clearing data will also clear the cache). The
- * logs will be stored under /cache_dir/persistent_log/{@code subfolder}, so multiple independent
- * logs can be created.
- *
- * <p>This class is NOT thread safe. All methods expect the constructor must be called on the same
- * worker thread.
- */
-final class PersistentLogFileHandler {
-
-  private static final String LOG_DIRECTORY = "persistent_log";
-  private static final String NEXT_FILE_INDEX_PREFIX = "persistent_long_next_file_index_";
-
-  private static final byte[] ENTRY_PREFIX = {'P'};
-  private static final byte[] ENTRY_POSTFIX = {'L'};
-
-  private static class LogCorruptionException extends Exception {
-
-    public LogCorruptionException(String message) {
-      super(message);
-    }
-  }
-
-  private File logDirectory;
-  private final String subfolder;
-  private final int fileSizeLimit;
-  private final int fileCountLimit;
-
-  private SharedPreferences sharedPreferences;
-
-  private File outputFile;
-  private Context context;
-
-  @MainThread
-  PersistentLogFileHandler(String subfolder, int fileSizeLimit, int fileCountLimit) {
-    this.subfolder = subfolder;
-    this.fileSizeLimit = fileSizeLimit;
-    this.fileCountLimit = fileCountLimit;
-  }
-
-  /** Must be called right after the logger thread is created. */
-  @WorkerThread
-  void initialize(Context context) {
-    this.context = context;
-    logDirectory = new File(new File(context.getCacheDir(), LOG_DIRECTORY), subfolder);
-    initializeSharedPreference(context);
-  }
-
-  @WorkerThread
-  private boolean initializeSharedPreference(Context context) {
-    if (sharedPreferences == null && UserManagerCompat.isUserUnlocked(context)) {
-      sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
-      return true;
-    }
-    return sharedPreferences != null;
-  }
-
-  /**
-   * Write the list of byte arrays to the current log file, prefixing each entry with its' length. A
-   * new file will only be selected when the batch is completed, so the resulting file might be
-   * larger then {@code fileSizeLimit}
-   */
-  @WorkerThread
-  void writeLogs(List<byte[]> logs) throws IOException {
-    if (outputFile == null) {
-      selectNextFileToWrite();
-    }
-    outputFile.createNewFile();
-    try (DataOutputStream outputStream =
-        new DataOutputStream(new FileOutputStream(outputFile, true))) {
-      for (byte[] log : logs) {
-        outputStream.write(ENTRY_PREFIX);
-        outputStream.writeInt(log.length);
-        outputStream.write(log);
-        outputStream.write(ENTRY_POSTFIX);
-      }
-      outputStream.close();
-      if (outputFile.length() > fileSizeLimit) {
-        selectNextFileToWrite();
-      }
-    }
-  }
-
-  /** Concatenate all log files in chronicle order and return a byte array. */
-  @WorkerThread
-  @NonNull
-  private byte[] readBlob() throws IOException {
-    File[] files = getLogFiles();
-
-    ByteBuffer byteBuffer = ByteBuffer.allocate(getTotalSize(files));
-    for (File file : files) {
-      byteBuffer.put(readAllBytes(file));
-    }
-    return byteBuffer.array();
-  }
-
-  private static int getTotalSize(File[] files) {
-    int sum = 0;
-    for (File file : files) {
-      sum += (int) file.length();
-    }
-    return sum;
-  }
-
-  /** Parses the content of all files back to individual byte arrays. */
-  @WorkerThread
-  @NonNull
-  List<byte[]> getLogs() throws IOException {
-    byte[] blob = readBlob();
-    List<byte[]> logs = new ArrayList<>();
-    try (DataInputStream input = new DataInputStream(new ByteArrayInputStream(blob))) {
-      byte[] log = readLog(input);
-      while (log != null) {
-        logs.add(log);
-        log = readLog(input);
-      }
-    } catch (LogCorruptionException e) {
-      LogUtil.e("PersistentLogFileHandler.getLogs", "logs corrupted, deleting", e);
-      deleteLogs();
-      return new ArrayList<>();
-    }
-    return logs;
-  }
-
-  private void deleteLogs() throws IOException {
-    for (File file : getLogFiles()) {
-      file.delete();
-    }
-    selectNextFileToWrite();
-  }
-
-  @WorkerThread
-  private void selectNextFileToWrite() throws IOException {
-    File[] files = getLogFiles();
-
-    if (files.length == 0 || files[files.length - 1].length() > fileSizeLimit) {
-      if (files.length >= fileCountLimit) {
-        for (int i = 0; i <= files.length - fileCountLimit; i++) {
-          files[i].delete();
-        }
-      }
-      outputFile = new File(logDirectory, String.valueOf(getAndIncrementNextFileIndex()));
-    } else {
-      outputFile = files[files.length - 1];
-    }
-  }
-
-  @NonNull
-  @WorkerThread
-  private File[] getLogFiles() {
-    logDirectory.mkdirs();
-    File[] files = logDirectory.listFiles();
-    if (files == null) {
-      files = new File[0];
-    }
-    Arrays.sort(files, Comparator.comparingLong((File lhs) -> Long.valueOf(lhs.getName())));
-    return files;
-  }
-
-  @Nullable
-  @WorkerThread
-  private byte[] readLog(DataInputStream inputStream) throws IOException, LogCorruptionException {
-    try {
-      byte[] prefix = new byte[ENTRY_PREFIX.length];
-      if (inputStream.read(prefix) == -1) {
-        // EOF
-        return null;
-      }
-      if (!Arrays.equals(prefix, ENTRY_PREFIX)) {
-        throw new LogCorruptionException("entry prefix mismatch");
-      }
-      int dataLength = inputStream.readInt();
-      if (dataLength > fileSizeLimit) {
-        throw new LogCorruptionException("data length over max size");
-      }
-      byte[] data = new byte[dataLength];
-      inputStream.read(data);
-
-      byte[] postfix = new byte[ENTRY_POSTFIX.length];
-      inputStream.read(postfix);
-      if (!Arrays.equals(postfix, ENTRY_POSTFIX)) {
-        throw new LogCorruptionException("entry postfix mismatch");
-      }
-      return data;
-    } catch (EOFException e) {
-      return null;
-    }
-  }
-
-  @NonNull
-  @WorkerThread
-  private static byte[] readAllBytes(File file) throws IOException {
-    byte[] result = new byte[(int) file.length()];
-    try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
-      randomAccessFile.readFully(result);
-    }
-    return result;
-  }
-
-  @WorkerThread
-  private int getAndIncrementNextFileIndex() throws IOException {
-    if (!initializeSharedPreference(context)) {
-      throw new IOException("Shared preference is not available");
-    }
-
-    int index = sharedPreferences.getInt(getNextFileKey(), 0);
-    sharedPreferences.edit().putInt(getNextFileKey(), index + 1).commit();
-    return index;
-  }
-
-  @AnyThread
-  private String getNextFileKey() {
-    return NEXT_FILE_INDEX_PREFIX + subfolder;
-  }
-}
diff --git a/java/com/android/dialer/persistentlog/PersistentLogger.java b/java/com/android/dialer/persistentlog/PersistentLogger.java
deleted file mode 100644
index 9517d75..0000000
--- a/java/com/android/dialer/persistentlog/PersistentLogger.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- * Copyright (C) 2023 The LineageOS 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
- */
-
-package com.android.dialer.persistentlog;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.HandlerThread;
-
-import androidx.annotation.AnyThread;
-import androidx.annotation.NonNull;
-import androidx.annotation.WorkerThread;
-import androidx.core.os.UserManagerCompat;
-
-import com.android.dialer.common.Assert;
-import com.android.dialer.common.LogUtil;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.LinkedBlockingQueue;
-
-/**
- * Logs data that is persisted across app termination and device reboot. The logs are stored as
- * rolling files in cache with a limit of {@link #LOG_FILE_SIZE_LIMIT} * {@link
- * #LOG_FILE_COUNT_LIMIT}. The log writing is batched and there is a {@link #FLUSH_DELAY_MILLIS}
- * delay before the logs are committed to disk to avoid excessive IO. If the app is terminated
- * before the logs are committed it will be lost. {@link
- * com.google.android.apps.dialer.crashreporter.SilentCrashReporter} is expected to handle such
- * cases.
- *
- * <p>{@link #logText(String, String)} should be used to log ad-hoc text logs. TODO(twyen): switch
- * to structured logging
- */
-public final class PersistentLogger {
-
-  private static final int FLUSH_DELAY_MILLIS = 200;
-  private static final String LOG_FOLDER = "plain_text";
-  private static final int MESSAGE_FLUSH = 1;
-
-  private static final int LOG_FILE_SIZE_LIMIT = 64 * 1024;
-  private static final int LOG_FILE_COUNT_LIMIT = 8;
-
-  private static PersistentLogFileHandler fileHandler;
-
-  private static HandlerThread loggerThread;
-  private static Handler loggerThreadHandler;
-
-  private static final LinkedBlockingQueue<byte[]> messageQueue = new LinkedBlockingQueue<>();
-
-  private PersistentLogger() {}
-
-  public static void initialize(Context context) {
-    fileHandler =
-        new PersistentLogFileHandler(LOG_FOLDER, LOG_FILE_SIZE_LIMIT, LOG_FILE_COUNT_LIMIT);
-    loggerThread = new HandlerThread("PersistentLogger");
-    loggerThread.start();
-    loggerThreadHandler =
-        new Handler(
-            loggerThread.getLooper(),
-            (message) -> {
-              if (message.what == MESSAGE_FLUSH) {
-                if (messageQueue.isEmpty()) {
-                  return true;
-                }
-                loggerThreadHandler.removeMessages(MESSAGE_FLUSH);
-                List<byte[]> messages = new ArrayList<>();
-                messageQueue.drainTo(messages);
-                if (!UserManagerCompat.isUserUnlocked(context)) {
-                  return true;
-                }
-                try {
-                  fileHandler.writeLogs(messages);
-                } catch (IOException e) {
-                  LogUtil.e("PersistentLogger.MESSAGE_FLUSH", "error writing message", e);
-                }
-              }
-              return true;
-            });
-    loggerThreadHandler.post(() -> fileHandler.initialize(context));
-  }
-
-  static HandlerThread getLoggerThread() {
-    return loggerThread;
-  }
-
-  @AnyThread
-  public static void logText(String tag, String string) {
-    log(buildTextLog(tag, string));
-  }
-
-  @AnyThread
-  static void log(byte[] data) {
-    messageQueue.add(data);
-    loggerThreadHandler.sendEmptyMessageDelayed(MESSAGE_FLUSH, FLUSH_DELAY_MILLIS);
-  }
-
-  /** Dump the log as human readable string. Blocks until the dump is finished. */
-  @NonNull
-  @WorkerThread
-  public static String dumpLogToString() {
-    Assert.isWorkerThread();
-    DumpStringRunnable dumpStringRunnable = new DumpStringRunnable();
-    loggerThreadHandler.post(dumpStringRunnable);
-    try {
-      return dumpStringRunnable.get();
-    } catch (InterruptedException e) {
-      Thread.currentThread().interrupt();
-      return "Cannot dump logText: " + e;
-    }
-  }
-
-  private static class DumpStringRunnable implements Runnable {
-    private String result;
-    private final CountDownLatch latch = new CountDownLatch(1);
-
-    @Override
-    public void run() {
-      result = dumpLogToStringInternal();
-      latch.countDown();
-    }
-
-    public String get() throws InterruptedException {
-      latch.await();
-      return result;
-    }
-  }
-
-  @NonNull
-  @WorkerThread
-  private static String dumpLogToStringInternal() {
-    StringBuilder result = new StringBuilder();
-    List<byte[]> logs;
-    try {
-      logs = readLogs();
-    } catch (IOException e) {
-      return "Cannot dump logText: " + e;
-    }
-
-    for (byte[] log : logs) {
-      result.append(new String(log, StandardCharsets.UTF_8)).append("\n");
-    }
-    return result.toString();
-  }
-
-  @NonNull
-  @WorkerThread
-  static List<byte[]> readLogs() throws IOException {
-    Assert.isWorkerThread();
-    return fileHandler.getLogs();
-  }
-
-  private static byte[] buildTextLog(String tag, String string) {
-    Calendar c = Calendar.getInstance();
-    return String.format("%tm-%td %tH:%tM:%tS.%tL - %s - %s", c, c, c, c, c, c, tag, string)
-        .getBytes(StandardCharsets.UTF_8);
-  }
-}
diff --git a/java/com/android/dialer/simulator/impl/SimulatorMainPortal.java b/java/com/android/dialer/simulator/impl/SimulatorMainPortal.java
index 9667f21..caea72a 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorMainPortal.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorMainPortal.java
@@ -104,7 +104,6 @@
                     .put("Clean database", () -> SimulatorUtils.cleanDatabase(context))
                     .put("clear preferred SIM", () -> SimulatorUtils.clearPreferredSim(context))
                     .put("Sync voicemail", () -> SimulatorUtils.syncVoicemail(context))
-                    .put("Share persistent log", () -> SimulatorUtils.sharePersistentLog(context))
                     .put(
                         "Enable simulator mode",
                         () -> {
diff --git a/java/com/android/dialer/simulator/impl/SimulatorUtils.java b/java/com/android/dialer/simulator/impl/SimulatorUtils.java
index 9bd4578..2f99453 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorUtils.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorUtils.java
@@ -33,7 +33,6 @@
 import com.android.dialer.databasepopulator.CallLogPopulator;
 import com.android.dialer.databasepopulator.ContactsPopulator;
 import com.android.dialer.databasepopulator.VoicemailPopulator;
-import com.android.dialer.persistentlog.PersistentLogger;
 import com.android.dialer.preferredsim.PreferredSimFallbackContract;
 
 import java.util.ArrayList;
@@ -107,23 +106,6 @@
     context.sendBroadcast(intent);
   }
 
-  public static void sharePersistentLog(@NonNull Context context) {
-    DialerExecutorComponent.get(context)
-        .dialerExecutorFactory()
-        .createNonUiTaskBuilder(new ShareLogWorker())
-        .onSuccess(
-            (String log) -> {
-              Intent intent = new Intent(Intent.ACTION_SEND);
-              intent.setType("text/plain");
-              intent.putExtra(Intent.EXTRA_TEXT, log);
-              if (intent.resolveActivity(context.getPackageManager()) != null) {
-                context.startActivity(intent);
-              }
-            })
-        .build()
-        .executeSerial(null);
-  }
-
   public static void addVoicemailNotifications(@NonNull Context context, int notificationNum) {
     LogUtil.enterBlock("SimulatorNotifications.addVoicemailNotifications");
     List<ContentValues> voicemails = new ArrayList<>();
@@ -188,14 +170,6 @@
     }
   }
 
-  private static class ShareLogWorker implements Worker<Void, String> {
-    @Nullable
-    @Override
-    public String doInBackground(Void unused) {
-      return PersistentLogger.dumpLogToString();
-    }
-  }
-
   private static class PopulateDatabaseWorkerInput {
     final Context context;
     final boolean fastMode;
diff --git a/java/com/android/voicemail/impl/VvmLog.java b/java/com/android/voicemail/impl/VvmLog.java
index 1a7514a..c9e82ac 100644
--- a/java/com/android/voicemail/impl/VvmLog.java
+++ b/java/com/android/voicemail/impl/VvmLog.java
@@ -17,7 +17,6 @@
 package com.android.voicemail.impl;
 
 import com.android.dialer.common.LogUtil;
-import com.android.dialer.persistentlog.PersistentLogger;
 import com.android.voicemail.impl.utils.IndentingPrintWriter;
 
 import java.io.FileDescriptor;
@@ -34,10 +33,6 @@
 
   private static final LocalLog localLog = new LocalLog(MAX_OMTP_VVM_LOGS);
 
-  public static void log(String tag, String log) {
-    PersistentLogger.logText(tag, log);
-  }
-
   public static void dump(FileDescriptor fd, PrintWriter printwriter, String[] args) {
     IndentingPrintWriter indentingPrintWriter = new IndentingPrintWriter(printwriter, "  ");
     indentingPrintWriter.increaseIndent();
@@ -46,62 +41,50 @@
   }
 
   public static void e(String tag, String log) {
-    log(tag, log);
     LogUtil.e(tag, log);
   }
 
   public static void e(String tag, String log, Throwable e) {
-    log(tag, log + " " + e);
     LogUtil.e(tag, log, e);
   }
 
   public static void w(String tag, String log) {
-    log(tag, log);
     LogUtil.w(tag, log);
   }
 
   public static void w(String tag, String log, Throwable e) {
-    log(tag, log + " " + e);
     LogUtil.w(tag, log, e);
   }
 
   public static void i(String tag, String log) {
-    log(tag, log);
     LogUtil.i(tag, log);
   }
 
   public static void i(String tag, String log, Throwable e) {
-    log(tag, log + " " + e);
     LogUtil.i(tag, log, e);
   }
 
   public static void d(String tag, String log) {
-    log(tag, log);
     LogUtil.d(tag, log);
   }
 
   public static void d(String tag, String log, Throwable e) {
-    log(tag, log + " " + e);
     LogUtil.d(tag, log, e);
   }
 
   public static void v(String tag, String log) {
-    log(tag, log);
     LogUtil.v(tag, log);
   }
 
   public static void v(String tag, String log, Throwable e) {
-    log(tag, log + " " + e);
     LogUtil.v(tag, log, e);
   }
 
   public static void wtf(String tag, String log) {
-    log(tag, log);
     LogUtil.e(tag, log);
   }
 
   public static void wtf(String tag, String log, Throwable e) {
-    log(tag, log + " " + e);
     LogUtil.e(tag, log, e);
   }