1 /*
2  * Copyright (C) 2013 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 package com.example.android.common.logger;
17 
18 import android.app.Activity;
19 import android.content.Context;
20 import android.util.*;
21 import android.widget.TextView;
22 
23 /** Simple TextView which is used to output log data received through the LogNode interface.
24 */
25 public class LogView extends TextView implements LogNode {
26 
LogView(Context context)27     public LogView(Context context) {
28         super(context);
29     }
30 
LogView(Context context, AttributeSet attrs)31     public LogView(Context context, AttributeSet attrs) {
32         super(context, attrs);
33     }
34 
LogView(Context context, AttributeSet attrs, int defStyle)35     public LogView(Context context, AttributeSet attrs, int defStyle) {
36         super(context, attrs, defStyle);
37     }
38 
39     /**
40      * Formats the log data and prints it out to the LogView.
41      * @param priority Log level of the data being logged.  Verbose, Error, etc.
42      * @param tag Tag for for the log data.  Can be used to organize log statements.
43      * @param msg The actual message to be logged. The actual message to be logged.
44      * @param tr If an exception was thrown, this can be sent along for the logging facilities
45      *           to extract and print useful information.
46      */
47     @Override
println(int priority, String tag, String msg, Throwable tr)48     public void println(int priority, String tag, String msg, Throwable tr) {
49 
50 
51         String priorityStr = null;
52 
53         // For the purposes of this View, we want to print the priority as readable text.
54         switch(priority) {
55             case android.util.Log.VERBOSE:
56                 priorityStr = "VERBOSE";
57                 break;
58             case android.util.Log.DEBUG:
59                 priorityStr = "DEBUG";
60                 break;
61             case android.util.Log.INFO:
62                 priorityStr = "INFO";
63                 break;
64             case android.util.Log.WARN:
65                 priorityStr = "WARN";
66                 break;
67             case android.util.Log.ERROR:
68                 priorityStr = "ERROR";
69                 break;
70             case android.util.Log.ASSERT:
71                 priorityStr = "ASSERT";
72                 break;
73             default:
74                 break;
75         }
76 
77         // Handily, the Log class has a facility for converting a stack trace into a usable string.
78         String exceptionStr = null;
79         if (tr != null) {
80             exceptionStr = android.util.Log.getStackTraceString(tr);
81         }
82 
83         // Take the priority, tag, message, and exception, and concatenate as necessary
84         // into one usable line of text.
85         final StringBuilder outputBuilder = new StringBuilder();
86 
87         String delimiter = "\t";
88         appendIfNotNull(outputBuilder, priorityStr, delimiter);
89         appendIfNotNull(outputBuilder, tag, delimiter);
90         appendIfNotNull(outputBuilder, msg, delimiter);
91         appendIfNotNull(outputBuilder, exceptionStr, delimiter);
92 
93         // In case this was originally called from an AsyncTask or some other off-UI thread,
94         // make sure the update occurs within the UI thread.
95         ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
96             @Override
97             public void run() {
98                 // Display the text we just generated within the LogView.
99                 appendToLog(outputBuilder.toString());
100             }
101         })));
102 
103         if (mNext != null) {
104             mNext.println(priority, tag, msg, tr);
105         }
106     }
107 
getNext()108     public LogNode getNext() {
109         return mNext;
110     }
111 
setNext(LogNode node)112     public void setNext(LogNode node) {
113         mNext = node;
114     }
115 
116     /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
117      * the logger takes so many arguments that might be null, this method helps cut out some of the
118      * agonizing tedium of writing the same 3 lines over and over.
119      * @param source StringBuilder containing the text to append to.
120      * @param addStr The String to append
121      * @param delimiter The String to separate the source and appended strings. A tab or comma,
122      *                  for instance.
123      * @return The fully concatenated String as a StringBuilder
124      */
appendIfNotNull(StringBuilder source, String addStr, String delimiter)125     private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
126         if (addStr != null) {
127             if (addStr.length() == 0) {
128                 delimiter = "";
129             }
130 
131             return source.append(addStr).append(delimiter);
132         }
133         return source;
134     }
135 
136     // The next LogNode in the chain.
137     LogNode mNext;
138 
139     /** Outputs the string as a new line of log data in the LogView. */
appendToLog(String s)140     public void appendToLog(String s) {
141         append("\n" + s);
142     }
143 
144 
145 }
146