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

Commit b29522f7 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add dropbox entries to incident report"

parents 87bf2b23 6a72b391
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import "frameworks/base/core/proto/android/service/appwidget.proto";
import "frameworks/base/core/proto/android/service/battery.proto";
import "frameworks/base/core/proto/android/service/batterystats.proto";
import "frameworks/base/core/proto/android/service/diskstats.proto";
import "frameworks/base/core/proto/android/service/dropbox.proto";
import "frameworks/base/core/proto/android/service/graphicsstats.proto";
import "frameworks/base/core/proto/android/service/netstats.proto";
import "frameworks/base/core/proto/android/service/notification.proto";
@@ -329,6 +330,22 @@ message IncidentProto {
        (section).userdebug_and_eng_only = true
    ];

    // Dropbox entries split by tags.
    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_data_app_crashes = 3027 [
        (section).type = SECTION_DUMPSYS,
        (section).args = "dropbox --proto data_app_crash"
    ];

    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_data_app_anr = 3028 [
        (section).type = SECTION_DUMPSYS,
        (section).args = "dropbox --proto data_app_anr"
    ];

    optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_data_app_native_crash = 3029 [
        (section).type = SECTION_DUMPSYS,
        (section).args = "dropbox --proto data_app_native_crash"
    ];

    // Reserved for OEMs.
    extensions 50000 to 100000;
}
+34 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 android.service.dropbox;

import "frameworks/base/core/proto/android/privacy.proto";

option java_multiple_files = true;

// Dump from com.android.server.DropboxManagerService.java.
message DropBoxManagerServiceDumpProto {
    option (android.msg_privacy).dest = DEST_EXPLICIT;

    message Entry {
        // Time when entry was originally created.
        optional int64 time_ms = 1 [ (.android.privacy).dest = DEST_AUTOMATIC ] ;
        optional bytes data = 2;
    }
    repeated Entry entries = 1;
}
+68 −8
Original line number Diff line number Diff line
@@ -41,11 +41,13 @@ import android.os.StatFs;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.dropbox.DropBoxManagerServiceDumpProto;
import android.text.TextUtils;
import android.text.format.TimeMigrationUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -66,6 +68,7 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.zip.GZIPOutputStream;
@@ -86,6 +89,9 @@ public final class DropBoxManagerService extends SystemService {

    private static final boolean PROFILE_DUMP = false;

    // Max number of bytes of a dropbox entry to write into protobuf.
    private static final int PROTO_MAX_DATA_BYTES = 256 * 1024;

    // TODO: This implementation currently uses one file per entry, which is
    // inefficient for smallish entries -- consider using a single queue file
    // per tag (or even globally) instead.
@@ -556,18 +562,22 @@ public final class DropBoxManagerService extends SystemService {

        StringBuilder out = new StringBuilder();
        boolean doPrint = false, doFile = false;
        boolean dumpProto = false;
        ArrayList<String> searchArgs = new ArrayList<String>();
        for (int i = 0; args != null && i < args.length; i++) {
            if (args[i].equals("-p") || args[i].equals("--print")) {
                doPrint = true;
            } else if (args[i].equals("-f") || args[i].equals("--file")) {
                doFile = true;
            } else if (args[i].equals("--proto")) {
                dumpProto = true;
            } else if (args[i].equals("-h") || args[i].equals("--help")) {
                pw.println("Dropbox (dropbox) dump options:");
                pw.println("  [-h|--help] [-p|--print] [-f|--file] [timestamp]");
                pw.println("    -h|--help: print this help");
                pw.println("    -p|--print: print full contents of each entry");
                pw.println("    -f|--file: print path of each entry's file");
                pw.println("    --proto: dump data to proto");
                pw.println("  [timestamp] optionally filters to only those entries.");
                return;
            } else if (args[i].startsWith("-")) {
@@ -577,6 +587,11 @@ public final class DropBoxManagerService extends SystemService {
            }
        }

        if (dumpProto) {
            dumpProtoLocked(fd, searchArgs);
            return;
        }

        out.append("Drop box contents: ").append(mAllFiles.contents.size()).append(" entries\n");
        out.append("Max entries: ").append(mMaxFiles).append("\n");

@@ -590,19 +605,15 @@ public final class DropBoxManagerService extends SystemService {
            out.append("\n");
        }

        int numFound = 0, numArgs = searchArgs.size();
        int numFound = 0;
        out.append("\n");
        for (EntryFile entry : mAllFiles.contents) {
            String date = TimeMigrationUtils.formatMillisWithFixedFormat(entry.timestampMillis);
            boolean match = true;
            for (int i = 0; i < numArgs && match; i++) {
                String arg = searchArgs.get(i);
                match = (date.contains(arg) || arg.equals(entry.tag));
            }
            if (!match) continue;
            if (!matchEntry(entry, searchArgs)) continue;

            numFound++;
            if (doPrint) out.append("========================================\n");

            String date = TimeMigrationUtils.formatMillisWithFixedFormat(entry.timestampMillis);
            out.append(date).append(" ").append(entry.tag == null ? "(no tag)" : entry.tag);

            final File file = entry.getFile(mDropBoxDir);
@@ -688,6 +699,55 @@ public final class DropBoxManagerService extends SystemService {
        if (PROFILE_DUMP) Debug.stopMethodTracing();
    }

    private boolean matchEntry(EntryFile entry, ArrayList<String> searchArgs) {
        String date = TimeMigrationUtils.formatMillisWithFixedFormat(entry.timestampMillis);
        boolean match = true;
        int numArgs = searchArgs.size();
        for (int i = 0; i < numArgs && match; i++) {
            String arg = searchArgs.get(i);
            match = (date.contains(arg) || arg.equals(entry.tag));
        }
        return match;
    }

    private void dumpProtoLocked(FileDescriptor fd, ArrayList<String> searchArgs) {
        final ProtoOutputStream proto = new ProtoOutputStream(fd);

        for (EntryFile entry : mAllFiles.contents) {
            if (!matchEntry(entry, searchArgs)) continue;

            final File file = entry.getFile(mDropBoxDir);
            if ((file == null) || ((entry.flags & DropBoxManager.IS_EMPTY) != 0)) {
                continue;
            }

            final long bToken = proto.start(DropBoxManagerServiceDumpProto.ENTRIES);
            proto.write(DropBoxManagerServiceDumpProto.Entry.TIME_MS, entry.timestampMillis);
            try (
                DropBoxManager.Entry dbe = new DropBoxManager.Entry(
                        entry.tag, entry.timestampMillis, file, entry.flags);
                InputStream is = dbe.getInputStream();
            ) {
                if (is != null) {
                    byte[] buf = new byte[PROTO_MAX_DATA_BYTES];
                    int readBytes = 0;
                    int n = 0;
                    while (n >= 0 && (readBytes += n) < PROTO_MAX_DATA_BYTES) {
                        n = is.read(buf, readBytes, PROTO_MAX_DATA_BYTES - readBytes);
                    }
                    proto.write(DropBoxManagerServiceDumpProto.Entry.DATA,
                            Arrays.copyOf(buf, readBytes));
                }
            } catch (IOException e) {
                Slog.e(TAG, "Can't read: " + file, e);
            }

            proto.end(bToken);
        }

        proto.flush();
    }

    ///////////////////////////////////////////////////////////////////////////

    /** Chronologically sorted list of {@link EntryFile} */