Fix a crash when opening a drawer while restarting. https://redmine.stoutner.com...
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / asynctasks / GetLogcat.java
1 /*
2  * Copyright © 2020-2021 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
5  *
6  * Privacy Browser is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Browser is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacybrowser.asynctasks;
21
22 import android.app.Activity;
23 import android.os.AsyncTask;
24 import android.widget.ScrollView;
25 import android.widget.TextView;
26
27 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
28
29 import com.stoutner.privacybrowser.R;
30
31 import java.io.BufferedReader;
32 import java.io.IOException;
33 import java.io.InputStreamReader;
34 import java.lang.ref.WeakReference;
35
36 // `Void` does not declare any parameters.  `Void` does not declare progress units.  `String` contains the results.
37 public class GetLogcat extends AsyncTask<Void, Void, String> {
38     // Define the class variables.
39     private final WeakReference<Activity> activityWeakReference;
40     private final int scrollViewYPositionInt;
41
42     // The public constructor.
43     public GetLogcat(Activity activity, int scrollViewYPositionInt) {
44         // Populate the weak reference to the calling activity.
45         activityWeakReference = new WeakReference<>(activity);
46
47         // Store the scrollview Y position.
48         this.scrollViewYPositionInt = scrollViewYPositionInt;
49     }
50
51     @Override
52     protected String doInBackground(Void... parameters) {
53         // Get a handle for the activity.
54         Activity activity = activityWeakReference.get();
55
56         // Abort if the activity is gone.
57         if ((activity == null) || activity.isFinishing()) {
58             return "";
59         }
60
61         // Create a log string builder.
62         StringBuilder logStringBuilder = new StringBuilder();
63
64         try {
65             // Get the logcat.  `-b all` gets all the buffers (instead of just crash, main, and system).  `-v long` produces more complete information.  `-d` dumps the logcat and exits.
66             Process process = Runtime.getRuntime().exec("logcat -b all -v long -d");
67
68             // Wrap the logcat in a buffered reader.
69             BufferedReader logBufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
70
71             // Create a log transfer string.
72             String logTransferString;
73
74             // Use the log transfer string to copy the logcat from the buffered reader to the string builder.
75             while ((logTransferString = logBufferedReader.readLine()) != null) {
76                 // Append a line.
77                 logStringBuilder.append(logTransferString);
78
79                 // Append a line break.
80                 logStringBuilder.append("\n");
81             }
82
83             // Close the buffered reader.
84             logBufferedReader.close();
85         } catch (IOException exception) {
86             // Do nothing.
87         }
88
89         // Return the logcat.
90         return logStringBuilder.toString();
91     }
92
93     // `onPostExecute()` operates on the UI thread.
94     @Override
95     protected void onPostExecute(String logcatString) {
96         // Get a handle for the activity.
97         Activity activity = activityWeakReference.get();
98
99         // Abort if the activity is gone.
100         if ((activity == null) || activity.isFinishing()) {
101             return;
102         }
103
104         // Get handles for the views.
105         TextView logcatTextView = activity.findViewById(R.id.logcat_textview);
106         SwipeRefreshLayout swipeRefreshLayout = activity.findViewById(R.id.logcat_swiperefreshlayout);
107         ScrollView scrollView = activity.findViewById(R.id.logcat_scrollview);
108
109         // Display the logcat.
110         logcatTextView.setText(logcatString);
111
112         // Update the scroll position after the text is populated.
113         logcatTextView.post(() -> {
114             // Set the scroll position.
115             scrollView.setScrollY(scrollViewYPositionInt);
116         });
117
118         // Stop the swipe to refresh animation if it is displayed.
119         swipeRefreshLayout.setRefreshing(false);
120     }
121 }