Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f51ced6d authored by Kholoud Mohamed's avatar Kholoud Mohamed
Browse files

Fix bugreport storage limit

We've now introduced a separate limit for deferred bugreports files
(.tmp files).

Fixes: 330177040
Test: atest com.android.shell.BugreportProgressServiceTest
Test: atest android.bugreport.cts_root.BugreportManagerTest#testBugreportsLimitReached

Change-Id: Ie4eb8235b17e93baac250bd7ae662b2ba6cca7a3
parent 8e1ad154
Loading
Loading
Loading
Loading
+17 −7
Original line number Original line Diff line number Diff line
@@ -284,6 +284,16 @@ flag {
  }
  }
}
}


flag {
  name: "onboarding_bugreport_storage_bug_fix"
  namespace: "enterprise"
  description: "Add a separate storage limit for deferred bugreports"
  bug: "330177040"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
flag {
    name: "headless_single_user_fixes"
    name: "headless_single_user_fixes"
    namespace: "enterprise"
    namespace: "enterprise"
+3 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,9 @@ android_app {
        include_dirs: ["frameworks/native/cmds/dumpstate/binder"],
        include_dirs: ["frameworks/native/cmds/dumpstate/binder"],
    },
    },
    static_libs: shell_static_libs,
    static_libs: shell_static_libs,
    libs: [
        "device_policy_aconfig_flags_lib",
    ],
    platform_apis: true,
    platform_apis: true,
    certificate: "platform",
    certificate: "platform",
    privileged: true,
    privileged: true,
+54 −7
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.shell;
package com.android.shell;


import static android.app.admin.flags.Flags.onboardingBugreportStorageBugFix;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
@@ -89,10 +90,10 @@ import com.android.internal.app.ChooserActivity;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;


import com.google.android.collect.Lists;

import libcore.io.Streams;
import libcore.io.Streams;


import com.google.android.collect.Lists;

import java.io.BufferedOutputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.File;
@@ -109,6 +110,8 @@ import java.security.NoSuchAlgorithmException;
import java.text.NumberFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.Date;
import java.util.Enumeration;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashMap;
@@ -442,10 +445,14 @@ public class BugreportProgressService extends Service {
        }
        }
    }
    }


    private static void sendRemoteBugreportFinishedBroadcast(Context context,
    private void sendRemoteBugreportFinishedBroadcast(Context context,
            String bugreportFileName, File bugreportFile, long nonce) {
            String bugreportFileName, File bugreportFile, long nonce) {
        cleanupOldFiles(REMOTE_BUGREPORT_FILES_AMOUNT, REMOTE_MIN_KEEP_AGE,
        // Remote bugreports are stored in the same directory as normal bugreports, meaning that
                bugreportFile.getParentFile());
        // the remote bugreport storage limit will get applied to normal bugreports whenever a
        // remote bugreport is triggered. The fix in cleanupOldFiles applies the normal bugreport
        // limit to the remote bugreports as a quick fix.
        cleanupOldFiles(
                REMOTE_BUGREPORT_FILES_AMOUNT, REMOTE_MIN_KEEP_AGE, bugreportFile.getParentFile());
        final Intent intent = new Intent(DevicePolicyManager.ACTION_REMOTE_BUGREPORT_DISPATCH);
        final Intent intent = new Intent(DevicePolicyManager.ACTION_REMOTE_BUGREPORT_DISPATCH);
        final Uri bugreportUri = getUri(context, bugreportFile);
        final Uri bugreportUri = getUri(context, bugreportFile);
        final String bugreportHash = generateFileHash(bugreportFileName);
        final String bugreportHash = generateFileHash(bugreportFileName);
@@ -496,12 +503,16 @@ public class BugreportProgressService extends Service {
        return fileHash;
        return fileHash;
    }
    }


    static void cleanupOldFiles(final int minCount, final long minAge, File bugreportsDir) {
    void cleanupOldFiles(final int minCount, final long minAge, File bugreportsDir) {
        new AsyncTask<Void, Void, Void>() {
        new AsyncTask<Void, Void, Void>() {
            @Override
            @Override
            protected Void doInBackground(Void... params) {
            protected Void doInBackground(Void... params) {
                try {
                try {
                    if (onboardingBugreportStorageBugFix()) {
                        cleanupOldBugreports();
                    } else {
                        FileUtils.deleteOlderFiles(bugreportsDir, minCount, minAge);
                        FileUtils.deleteOlderFiles(bugreportsDir, minCount, minAge);
                    }
                } catch (RuntimeException e) {
                } catch (RuntimeException e) {
                    Log.e(TAG, "RuntimeException deleting old files", e);
                    Log.e(TAG, "RuntimeException deleting old files", e);
                }
                }
@@ -510,6 +521,42 @@ public class BugreportProgressService extends Service {
        }.execute();
        }.execute();
    }
    }


    private void cleanupOldBugreports() {
        final File[] files = mBugreportsDir.listFiles();
        if (files == null) return;

        // Sort with newest files first
        Arrays.sort(files, new Comparator<File>() {
            @Override
            public int compare(File lhs, File rhs) {
                return Long.compare(rhs.lastModified(), lhs.lastModified());
            }
        });

        int normalBugreportFilesCount = 0;
        int deferredBugreportFilesCount = 0;
        for (int i = 0; i < files.length; i++) {
            final File file = files[i];

            // tmp files are deferred bugreports which have their separate storage limit
            boolean isDeferredBugreportFile = file.getName().endsWith(".tmp");
            if (isDeferredBugreportFile) {
                deferredBugreportFilesCount++;
            } else {
                normalBugreportFilesCount++;
            }
            // Keep files newer than minAgeMs
            final long age = System.currentTimeMillis() - file.lastModified();
            final int count = isDeferredBugreportFile
                    ? deferredBugreportFilesCount : normalBugreportFilesCount;
            if (count > MIN_KEEP_COUNT  && age > MIN_KEEP_AGE) {
                if (file.delete()) {
                    Log.d(TAG, "Deleted old file " + file);
                }
            }
        }
    }

    /**
    /**
     * Main thread used to handle all requests but taking screenshots.
     * Main thread used to handle all requests but taking screenshots.
     */
     */