Home | History | Annotate | Download | only in bugreportsender
      1 /*
      2  * Copyright (C) 2009 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.bugreportsender;
     18 
     19 import android.app.ListActivity;
     20 import android.content.Intent;
     21 import android.net.Uri;
     22 import android.os.Build;
     23 import android.os.Bundle;
     24 import android.os.FileObserver;
     25 import android.os.Handler;
     26 import android.util.Log;
     27 import android.view.ContextMenu;
     28 import android.view.MenuItem;
     29 import android.view.View;
     30 import android.widget.AdapterView;
     31 import android.widget.ArrayAdapter;
     32 import android.widget.ListView;
     33 
     34 import java.io.File;
     35 import java.util.ArrayList;
     36 import java.util.Arrays;
     37 import java.util.Collections;
     38 import java.util.HashMap;
     39 
     40 /**
     41  * Shows a list of bug reports currently in /sdcard/bugreports
     42  */
     43 public class BugReportListActivity extends ListActivity {
     44     private static final String TAG = "BugReportListActivity";
     45     private static final File REPORT_DIR = new File("/sdcard/bugreports");
     46     private static final int SYSTEM_LOG_ID = 1;
     47     private static final int MEMORY_ID = 2;
     48     private static final int CPU_ID = 3;
     49     private static final int PROCRANK_ID = 4;
     50     private static final HashMap<Integer, String> ID_MAP = new HashMap<Integer, String>();
     51 
     52     static {
     53         ID_MAP.put(SYSTEM_LOG_ID, "SYSTEM LOG");
     54         ID_MAP.put(MEMORY_ID, "MEMORY INFO");
     55         ID_MAP.put(CPU_ID, "CPU INFO");
     56         ID_MAP.put(PROCRANK_ID, "PROCRANK");
     57     }
     58 
     59     private ArrayAdapter<String> mAdapter = null;
     60     private ArrayList<File> mFiles = null;
     61     private Handler mHandler = null;
     62     private FileObserver mObserver = null;
     63 
     64     @Override
     65     public void onCreate(Bundle savedInstanceState) {
     66         super.onCreate(savedInstanceState);
     67         mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
     68         mFiles = new ArrayList<File>();
     69         mHandler = new Handler();
     70 
     71         int flags = FileObserver.CREATE | FileObserver.MOVED_TO;
     72         mObserver = new FileObserver(REPORT_DIR.getPath(), flags) {
     73             public void onEvent(int event, String path) {
     74                 mHandler.post(new Runnable() { public void run() { scanDirectory(); } });
     75             }
     76         };
     77 
     78         setListAdapter(mAdapter);
     79         registerForContextMenu(getListView());
     80     }
     81 
     82     @Override
     83     public void onCreateContextMenu(ContextMenu menu, View v,
     84                                     ContextMenu.ContextMenuInfo menuInfo) {
     85         super.onCreateContextMenu(menu, v, menuInfo);
     86         menu.add(0, SYSTEM_LOG_ID, 0, "System Log");
     87         menu.add(0, CPU_ID, 0, "CPU Info");
     88         menu.add(0, MEMORY_ID, 0, "Memory Info");
     89         menu.add(0, PROCRANK_ID, 0, "Procrank");
     90     }
     91 
     92     @Override
     93     public void onStart() {
     94         super.onStart();
     95         mObserver.startWatching();
     96         scanDirectory();
     97     }
     98 
     99     @Override
    100     public void onStop() {
    101         super.onStop();
    102         mObserver.stopWatching();
    103     }
    104 
    105     @Override
    106     protected void onListItemClick(ListView l, View v, int position, long id) {
    107         super.onListItemClick(l, v, position, id);
    108         if (position < mFiles.size()) {
    109             File file = mFiles.get(position);
    110             Intent intent = new Intent(Intent.ACTION_SEND);
    111             intent.putExtra("subject", file.getName());
    112             intent.putExtra("body", "Build: " + Build.DISPLAY + "\n(Sent by BugReportSender)");
    113             intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
    114             if (file.getName().endsWith(".gz")) {
    115                 intent.setType("application/x-gzip");
    116             } else if (file.getName().endsWith(".txt")) {
    117                 intent.setType("text/plain");
    118             } else {
    119                 intent.setType("application/octet-stream");
    120             }
    121             startActivity(intent);
    122         }
    123     }
    124 
    125 
    126     @Override
    127     public boolean onContextItemSelected(MenuItem item) {
    128       AdapterView.AdapterContextMenuInfo info =
    129               (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    130       if (info.position >= mFiles.size()) {
    131         return true;
    132       }
    133       int id = item.getItemId();
    134       switch (id) {
    135           case SYSTEM_LOG_ID: // drop down
    136           case MEMORY_ID:     // drop down
    137           case CPU_ID:        // drop down
    138           case PROCRANK_ID:
    139           File file = mFiles.get(info.position);
    140           Intent intent = new Intent(Intent.ACTION_VIEW);
    141           intent.setDataAndType(Uri.fromFile(file), "vnd.android/bugreport");
    142           intent.putExtra("section", ID_MAP.get(id));
    143           startActivity(intent);
    144           return true;
    145       default:
    146         return super.onContextItemSelected(item);
    147       }
    148     }
    149 
    150     private void scanDirectory() {
    151         mAdapter.clear();
    152         mFiles.clear();
    153 
    154         File[] files = REPORT_DIR.listFiles();
    155         if (files == null) return;
    156 
    157         // Sort in reverse order: newest bug reports first
    158         Arrays.sort(files, Collections.reverseOrder());
    159         for (int i = 0; i < files.length; i++) {
    160             String name = files[i].getName();
    161             if (name.endsWith(".gz")) name = name.substring(0, name.length() - 3);
    162             if (!name.startsWith("bugreport-") || !name.endsWith(".txt")) {
    163                 Log.w(TAG, "Ignoring non-bugreport: " + files[i]);
    164                 continue;
    165             }
    166 
    167             // Make sure to keep the parallel arrays in sync
    168             mAdapter.add(name.substring(10, name.length() - 4));
    169             mFiles.add(files[i]);
    170         }
    171     }
    172 }
    173