• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.permissioncontroller
18 
19 import android.util.Log
20 import com.android.permissioncontroller.Constants.LOGS_TO_DUMP_FILE
21 import java.io.File
22 
23 /**
24  * Like {@link Log} but stores the logs in a file which can later be dumped via {@link #dump}
25  */
26 object DumpableLog {
27     private const val MAX_FILE_SIZE = 64 * 1024
28 
29     private val lock = Any()
30     private val file = File(PermissionControllerApplication.get().filesDir, LOGS_TO_DUMP_FILE)
31 
32     init {
33         file.createNewFile()
34     }
35 
36     /**
37      * Equivalent to {@link Log.v}
38      */
vnull39     fun v(tag: String, message: String, exception: Throwable? = null) {
40         Log.v(tag, message, exception)
41         addLogToDump("v", tag, message, exception)
42     }
43 
44     /**
45      * Equivalent to {@link Log.d}
46      */
dnull47     fun d(tag: String, message: String, exception: Throwable? = null) {
48         Log.d(tag, message, exception)
49         addLogToDump("d", tag, message, exception)
50     }
51 
52     /**
53      * Equivalent to {@link Log.i}
54      */
inull55     fun i(tag: String, message: String, exception: Throwable? = null) {
56         Log.i(tag, message, exception)
57         addLogToDump("i", tag, message, exception)
58     }
59 
60     /**
61      * Equivalent to {@link Log.w}
62      */
wnull63     fun w(tag: String, message: String, exception: Throwable? = null) {
64         Log.w(tag, message, exception)
65         addLogToDump("w", tag, message, exception)
66     }
67 
68     /**
69      * Equivalent to {@link Log.e}
70      */
enull71     fun e(tag: String, message: String, exception: Throwable? = null) {
72         Log.e(tag, message, exception)
73         addLogToDump("e", tag, message, exception)
74     }
75 
addLogToDumpnull76     private fun addLogToDump(level: String, tag: String, message: String, exception: Throwable?) {
77         synchronized(lock) {
78             // TODO: Needs to be replaced by proper log rotation
79             if (file.length() > MAX_FILE_SIZE) {
80                 val dump = file.readLines()
81 
82                 file.writeText("truncated at ${System.currentTimeMillis()}\n")
83                 dump.subList(dump.size / 2, dump.size).forEach { file.appendText(it + "\n") }
84             }
85 
86             file.appendText("${System.currentTimeMillis()} $tag:$level $message " +
87                     "${exception?.let { it.message + Log.getStackTraceString(it) } ?: ""}\n")
88         }
89     }
90 
91     /**
92      * @return the previously logged entries
93      */
getnull94     suspend fun get(): List<String> {
95         synchronized(lock) {
96             return file.readLines()
97         }
98     }
99 }