aboutsummaryrefslogtreecommitdiffstats
path: root/libs/thedevstacklogcat/src/main/java/de/thedevstack/android/logcat/tasks/ReadLogCatAsyncTask.java
blob: e16009ee3edd8cf9cd8003896889fd07bb4abe3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package de.thedevstack.android.logcat.tasks;

import android.os.AsyncTask;
import android.widget.ArrayAdapter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import de.thedevstack.android.logcat.Logging;
import de.thedevstack.android.logcat.adapters.LogCatArrayAdapter;

/**
 * Task to read the logcat of the App.
 * The command <code>logcat -d -v time</code> is used to load the logs.
 * This reader uses a white list to restrict the messages to display, otherwise it might be flooded with useless log messages.
 * The white list checks if a log messages contains one of the following strings:
 * <ul>
 *     <li>{@value Logging#LOG_TAG_PREFIX}</li>
 *     <li><code>E/</code> - for every error message</li>
 *     <li><code>W/</code> - for every warning message</li>
 * </ul>
 */
public class ReadLogCatAsyncTask extends AsyncTask<Void, Void, String[]> {
    /**
     * The array adapter to publish the log messages to.
     */
    private final LogCatArrayAdapter arrayAdapter;
    /**
     * The command to execute logcat.
     */
    private static final String[] LOG_CAT_CMD = { "logcat", "-d", "-v", "time"};
    /**
     * The white list to filter log messages.
     */
    private static final String[] WHITE_LIST = { Logging.getLogTagPrefix(), "E/", "W/" };

    /**
     * Initializes the Task with the array adapter to publish the log messages to.
     * @param arrayAdapter the array adapter
     */
    public ReadLogCatAsyncTask(LogCatArrayAdapter arrayAdapter) {
        this.arrayAdapter = arrayAdapter;
    }

    /**
     * Executes the logcat command, reads the output of the command and returns all log messages.
     * @param params no params will be passed. (interface compliance)
     * @return the array of log messages
     */
    @Override
    protected String[] doInBackground(Void... params) {
        ArrayList<String> logCatOutput = new ArrayList<>();
        BufferedReader bufferedReader = null;
        BufferedReader errorReader = null;
        try {
            Process process = Runtime.getRuntime().exec(ReadLogCatAsyncTask.LOG_CAT_CMD);
            bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String line = "";
            while ((line = bufferedReader.readLine()) != null) {
                logCatOutput.add(line);
            }

            String errorLine = "";
            StringBuilder sb = new StringBuilder();
            while ((errorLine = errorReader.readLine()) != null) {
                sb.append(errorLine);
                sb.append('\n');
            }
            int exitValue = process.waitFor();

            Logging.d("ReadLogCat", "Logcat command returned with exitValue '" + exitValue + "'.");

            String errorMessage = sb.toString();
            if (0 != exitValue && !errorMessage.isEmpty()) {
                Logging.e("ReadLogCat", errorMessage);
                logCatOutput.add(errorMessage);
            }
        } catch (IOException e) {
            Logging.e("ReadLogCat", "error while retrieving information from logcat: " + e.getMessage(), e);
        } catch (InterruptedException e) {
            Logging.e("ReadLogCat", "error while retrieving information from logcat: " + e.getMessage(), e);
        } finally {
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                }
            }
            if (null != errorReader) {
                try {
                    errorReader.close();
                } catch (IOException e) {
                }
            }
        }
        logCatOutput.trimToSize();
        return logCatOutput.toArray(new String[0]);
    }

    /**
     * Clears the array adapter and adds the filtered log messages.
     * @param items all log messages
     */
    @Override
    protected void onPostExecute(String[] items) {
        this.arrayAdapter.clear();
        if (null != items && items.length > 0) {
            for (String item : items) {
                if (!filter(item)) {
                    this.arrayAdapter.add(item);
                }
            }
        }
    }

    /**
     * Checks whether a log message contains a white listed string or not.
     * @param item the item to filter
     * @return <code>true</code> if the string should be filtered (removed from the list) <code>false</code> otherwise.
     */
    protected boolean filter(String item) {
        for (String whiteListed : ReadLogCatAsyncTask.WHITE_LIST) {
            if (item.contains(whiteListed)) {
                return false;
            }
        }
        return true;
    }
}