• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.server.crashrecovery;
18 
19 import android.os.Environment;
20 import android.util.IndentingPrintWriter;
21 import android.util.Log;
22 
23 import java.io.BufferedReader;
24 import java.io.File;
25 import java.io.FileOutputStream;
26 import java.io.FileReader;
27 import java.io.IOException;
28 import java.io.PrintWriter;
29 import java.time.LocalDateTime;
30 import java.time.ZoneId;
31 
32 /**
33  * Class containing helper methods for the CrashRecoveryModule.
34  *
35  * @hide
36  */
37 public class CrashRecoveryUtils {
38     private static final String TAG = "CrashRecoveryUtils";
39     private static final long MAX_CRITICAL_INFO_DUMP_SIZE = 1000 * 1000; // ~1MB
40     private static final Object sFileLock = new Object();
41 
42     /** Persist recovery related events in crashrecovery events file.**/
logCrashRecoveryEvent(int priority, String msg)43     public static void logCrashRecoveryEvent(int priority, String msg) {
44         Log.println(priority, TAG, msg);
45         try {
46             File fname = getCrashRecoveryEventsFile();
47             synchronized (sFileLock) {
48                 FileOutputStream out = new FileOutputStream(fname, true);
49                 PrintWriter pw = new PrintWriter(out);
50                 String dateString = LocalDateTime.now(ZoneId.systemDefault()).toString();
51                 pw.println(dateString + ": " + msg);
52                 pw.close();
53             }
54         } catch (IOException e) {
55             Log.e(TAG, "Unable to log CrashRecoveryEvents " + e.getMessage());
56         }
57     }
58 
59     /** Dump recovery related events from crashrecovery events file.**/
dumpCrashRecoveryEvents(IndentingPrintWriter pw)60     public static void dumpCrashRecoveryEvents(IndentingPrintWriter pw) {
61         pw.println("CrashRecovery Events: ");
62         pw.increaseIndent();
63         final File file = getCrashRecoveryEventsFile();
64         final long skipSize = file.length() - MAX_CRITICAL_INFO_DUMP_SIZE;
65         synchronized (sFileLock) {
66             try (BufferedReader in = new BufferedReader(new FileReader(file))) {
67                 if (skipSize > 0) {
68                     in.skip(skipSize);
69                 }
70                 String line;
71                 while ((line = in.readLine()) != null) {
72                     pw.println(line);
73                 }
74             } catch (IOException e) {
75                 Log.e(TAG, "Unable to dump CrashRecoveryEvents " + e.getMessage());
76             }
77         }
78         pw.decreaseIndent();
79     }
80 
getCrashRecoveryEventsFile()81     private static File getCrashRecoveryEventsFile() {
82         File systemDir = new File(Environment.getDataDirectory(), "system");
83         return new File(systemDir, "crashrecovery-events.txt");
84     }
85 }
86