Home | History | Annotate | Download | only in crashreportprovider
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.crashreportprovider;
     18 
     19 import android.content.ContentProvider;
     20 import android.content.ContentValues;
     21 import android.content.Intent;
     22 import android.database.Cursor;
     23 import android.database.MatrixCursor;
     24 import android.net.Uri;
     25 import android.os.FileObserver;
     26 import android.os.FileUtils;
     27 import android.os.ParcelFileDescriptor;
     28 import android.os.UserHandle;
     29 
     30 import java.io.File;
     31 import java.io.FileNotFoundException;
     32 import java.util.List;
     33 
     34 public class CrashReportProvider extends ContentProvider {
     35     private static final File sCrashReportDirectory = new File("/data/system/crash_reports/");
     36     private static FileObserver sFileObserver;
     37 
     38     public static final String ACTION_CRASH_REPORT_ADDED =
     39             "com.android.crashreportprovider.action.CRASH_REPORT_ADDED";
     40 
     41     public static final Uri URI = Uri.parse("content://com.android.crashreportprovider/");
     42 
     43     public final String COLUMN_NAME = "name";
     44     private final String[] DEFAULT_PROJECTION = { COLUMN_NAME };
     45 
     46     @Override
     47     public boolean onCreate() {
     48         if (sFileObserver == null) {
     49             sFileObserver = new FileObserver(sCrashReportDirectory.getPath(),
     50                     FileObserver.CLOSE_WRITE) {
     51                     @Override
     52                     public void onEvent(int event, String path) {
     53                         if (path.endsWith(".meta")) {
     54                             final Intent intent = new Intent(ACTION_CRASH_REPORT_ADDED);
     55                             getContext().sendBroadcastAsUser(intent, UserHandle.OWNER,
     56                                     android.Manifest.permission.READ_LOGS);
     57                         }
     58                     }
     59                 };
     60             sFileObserver.startWatching();
     61         }
     62         return true;
     63     }
     64 
     65     @Override
     66     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
     67             String sortOrder) {
     68         final MatrixCursor cursor =
     69                 new MatrixCursor(projection == null ? DEFAULT_PROJECTION : projection);
     70         final File[] files = sCrashReportDirectory.listFiles();
     71         if (files != null) {
     72             for (File file : files) {
     73                 final MatrixCursor.RowBuilder row = cursor.newRow();
     74                 row.add(COLUMN_NAME, file.getName());
     75             }
     76         }
     77         return cursor;
     78     }
     79 
     80     @Override
     81     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
     82         if (ParcelFileDescriptor.parseMode(mode) != ParcelFileDescriptor.MODE_READ_ONLY) {
     83             throw new FileNotFoundException("Cannot to open: " + uri + ", mode = " + mode);
     84         }
     85         List<String> segments = uri.getPathSegments();
     86         if (segments.size() != 1 || !FileUtils.isValidExtFilename(segments.get(0))) {
     87             throw new FileNotFoundException("Invalid path.");
     88         }
     89         return ParcelFileDescriptor.open(new File(sCrashReportDirectory, segments.get(0)),
     90                 ParcelFileDescriptor.MODE_READ_ONLY);
     91     }
     92 
     93     @Override
     94     public String getType(Uri uri) {
     95         return null;
     96     }
     97 
     98     @Override
     99     public int delete(Uri uri, String selection, String[] selectionArgs) {
    100         throw new UnsupportedOperationException("Cannot delete: " + uri);
    101     }
    102 
    103     @Override
    104     public Uri insert(Uri uri, ContentValues values) {
    105         throw new UnsupportedOperationException("Cannot insert: " + uri);
    106     }
    107 
    108     @Override
    109     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    110         throw new UnsupportedOperationException("Cannot update: " + uri);
    111     }
    112 }
    113