Loading packages/Shell/src/com/android/shell/BugreportProgressService.java +0 −8 Original line number Diff line number Diff line Loading @@ -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); Loading packages/Shell/src/com/android/shell/BugreportStorageProvider.java +45 −75 Original line number Diff line number Diff line Loading @@ -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"; Loading @@ -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; } Loading @@ -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 Loading @@ -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) { Loading @@ -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)) || Loading @@ -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); } } Loading
packages/Shell/src/com/android/shell/BugreportProgressService.java +0 −8 Original line number Diff line number Diff line Loading @@ -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); Loading
packages/Shell/src/com/android/shell/BugreportStorageProvider.java +45 −75 Original line number Diff line number Diff line Loading @@ -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"; Loading @@ -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; } Loading @@ -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 Loading @@ -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) { Loading @@ -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)) || Loading @@ -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); } }