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

Commit d8235e26 authored by Ben Lin's avatar Ben Lin
Browse files

Make BugreportStorageProvider subclass FileSystemProvider.

This allows it to gain all the benefits of FSP, ie. listening in on
File-system level changes without any explicitly notification Uri
passing back and forth.

This also reverts commit 6c9ff513c6d7d3de7ab8920d88111c2b1dc1bb1f.

Test: Manual test.
Bug: 38183534
Change-Id: I30a1d8489ec8732bdb80611bd8fa7099763de2a3
parent b44a966c
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -778,14 +778,6 @@ public class BugreportProgressService extends Service {
     */
    private void onBugreportFinished(int id, Intent intent) {
        final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
        // Since BugreportProvider and BugreportProgressService aren't tightly coupled,
        // we need to make sure they are explicitly tied to a single unique notification URI
        // so that the service can alert the provider of changes it has done (ie. new bug
        // reports)
        // See { @link Cursor#setNotificationUri } and {@link ContentResolver#notifyChanges }
        final Uri notificationUri = BugreportStorageProvider.getNotificationUri();
        mContext.getContentResolver().notifyChange(notificationUri, null, false);

        if (bugreportFile == null) {
            // Should never happen, dumpstate always set the file.
            Log.wtf(TAG, "Missing " + EXTRA_BUGREPORT + " on intent " + intent);
+45 −75
Original line number Diff line number Diff line
@@ -26,13 +26,13 @@ import android.os.ParcelFileDescriptor;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
import android.provider.DocumentsProvider;
import android.webkit.MimeTypeMap;

import com.android.internal.content.FileSystemProvider;

import java.io.File;
import java.io.FileNotFoundException;

public class BugreportStorageProvider extends DocumentsProvider {
public class BugreportStorageProvider extends FileSystemProvider {
    private static final String AUTHORITY = "com.android.shell.documents";
    private static final String DOC_ID_ROOT = "bugreport";

@@ -50,6 +50,7 @@ public class BugreportStorageProvider extends DocumentsProvider {

    @Override
    public boolean onCreate() {
        super.onCreate(DEFAULT_DOCUMENT_PROJECTION);
        mRoot = new File(getContext().getFilesDir(), "bugreports");
        return true;
    }
@@ -69,35 +70,13 @@ public class BugreportStorageProvider extends DocumentsProvider {
    @Override
    public Cursor queryDocument(String documentId, String[] projection)
            throws FileNotFoundException {
        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
        if (DOC_ID_ROOT.equals(documentId)) {
            final RowBuilder row = result.newRow();
            row.add(Document.COLUMN_DOCUMENT_ID, documentId);
            row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
            row.add(Document.COLUMN_DISPLAY_NAME, mRoot.getName());
            row.add(Document.COLUMN_LAST_MODIFIED, mRoot.lastModified());
            row.add(Document.COLUMN_FLAGS, Document.FLAG_DIR_PREFERS_LAST_MODIFIED);
        } else {
            addFileRow(result, getFileForDocId(documentId));
        }
        return result;
    }

    @Override
    public Cursor queryChildDocuments(
            String parentDocumentId, String[] projection, String sortOrder)
            throws FileNotFoundException {
            final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
        if (DOC_ID_ROOT.equals(parentDocumentId)) {
            final File[] files = mRoot.listFiles();
            if (files != null) {
                for (File file : files) {
                    addFileRow(result, file);
                }
                result.setNotificationUri(getContext().getContentResolver(), getNotificationUri());
            }
        }
            includeDefaultDocument(result);
            return result;
        } else {
            return super.queryDocument(documentId, projection);
        }
    }

    @Override
@@ -112,17 +91,8 @@ public class BugreportStorageProvider extends DocumentsProvider {
    }

    @Override
    public void deleteDocument(String documentId) throws FileNotFoundException {
        if (!getFileForDocId(documentId).delete()) {
            throw new FileNotFoundException("Failed to delete: " + documentId);
        }
        getContext().getContentResolver().notifyChange(getNotificationUri(), null);
    }

    // This is used by BugreportProgressService so that the notification uri shared by
    // BugreportProgressService and BugreportStorageProvider are guaranteed the same and unique
    protected static Uri getNotificationUri() {
      return DocumentsContract.buildChildDocumentsUri(AUTHORITY, DOC_ID_ROOT);
    protected Uri buildNotificationUri(String docId) {
        return DocumentsContract.buildChildDocumentsUri(AUTHORITY, docId);
    }

    private static String[] resolveRootProjection(String[] projection) {
@@ -133,23 +103,17 @@ public class BugreportStorageProvider extends DocumentsProvider {
        return projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION;
    }

    private static String getTypeForName(String name) {
        final int lastDot = name.lastIndexOf('.');
        if (lastDot >= 0) {
            final String extension = name.substring(lastDot + 1).toLowerCase();
            final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
            if (mime != null) {
                return mime;
            }
        }
        return "application/octet-stream";
    }

    private String getDocIdForFile(File file) {
    @Override
    protected String getDocIdForFile(File file) {
        return DOC_ID_ROOT + ":" + file.getName();
    }

    private File getFileForDocId(String documentId) throws FileNotFoundException {
    @Override
    protected File getFileForDocId(String documentId, boolean visible)
            throws FileNotFoundException {
        if (DOC_ID_ROOT.equals(documentId)) {
            return mRoot;
        } else {
            final int splitIndex = documentId.indexOf(':', 1);
            final String name = documentId.substring(splitIndex + 1);
            if (splitIndex == -1 || !DOC_ID_ROOT.equals(documentId.substring(0, splitIndex)) ||
@@ -162,16 +126,22 @@ public class BugreportStorageProvider extends DocumentsProvider {
            }
            return file;
        }
    }

    @Override
    protected RowBuilder includeFile(MatrixCursor result, String docId, File file)
            throws FileNotFoundException {
        RowBuilder row = super.includeFile(result, docId, file);
        row.add(Document.COLUMN_FLAGS, Document.FLAG_SUPPORTS_DELETE);
        return row;
    }

    private void addFileRow(MatrixCursor result, File file) {
        String mimeType = getTypeForName(file.getName());
        int flags = Document.FLAG_SUPPORTS_DELETE;
    private void includeDefaultDocument(MatrixCursor result) {
        final RowBuilder row = result.newRow();
        row.add(Document.COLUMN_DOCUMENT_ID, getDocIdForFile(file));
        row.add(Document.COLUMN_MIME_TYPE, mimeType);
        row.add(Document.COLUMN_DISPLAY_NAME, file.getName());
        row.add(Document.COLUMN_LAST_MODIFIED, file.lastModified());
        row.add(Document.COLUMN_FLAGS, flags);
        row.add(Document.COLUMN_SIZE, file.length());
        row.add(Document.COLUMN_DOCUMENT_ID, DOC_ID_ROOT);
        row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
        row.add(Document.COLUMN_DISPLAY_NAME, mRoot.getName());
        row.add(Document.COLUMN_LAST_MODIFIED, mRoot.lastModified());
        row.add(Document.COLUMN_FLAGS, Document.FLAG_DIR_PREFERS_LAST_MODIFIED);
    }
}