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