Home | History | Annotate | Download | only in development
      1 /*
      2 ** Copyright 2007, 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.development;
     18 
     19 import static com.android.internal.util.CharSequences.forAsciiBytes;
     20 
     21 import java.io.DataInputStream;
     22 import java.io.IOException;
     23 import java.io.FileOutputStream;
     24 import java.net.Socket;
     25 
     26 import android.app.Activity;
     27 import android.os.Handler;
     28 import android.os.Bundle;
     29 import android.util.Log;
     30 import android.graphics.Typeface;
     31 import android.view.Gravity;
     32 
     33 /**
     34  * Views the device log.
     35  */
     36 public class LogViewer extends Activity {
     37 
     38     static final String TAG = LogViewer.class.getSimpleName();
     39 
     40     FileOutputStream logger;
     41 
     42     volatile boolean active = true;
     43     Handler handler;
     44     LogTextBox text;
     45 
     46     @Override
     47     protected void onCreate(Bundle icicle) {
     48         super.onCreate(icicle);
     49         setContentView(R.layout.log_viewer);
     50         this.handler = new Handler();
     51 
     52         text = (LogTextBox) findViewById(R.id.text);
     53 
     54         text.setTextSize(10);
     55         text.setHorizontallyScrolling(true);
     56         text.setTypeface(Typeface.MONOSPACE);
     57         text.setGravity(Gravity.BOTTOM | Gravity.LEFT);
     58 
     59         this.active = true;
     60         try {
     61             logger = new FileOutputStream("/tmp/logviewer.txt");
     62             new Thread(new LogReader()).start();
     63         } catch (IOException e) {
     64             appendThrowable(e);
     65         }
     66     }
     67 
     68     private void appendThrowable(Throwable t) {
     69         StringBuilder builder = new StringBuilder();
     70         builder.append("Error reading log: ");
     71         builder.append(Log.getStackTraceString(t));
     72         text.getText().append(builder);
     73     }
     74 
     75     private class LogReader implements Runnable {
     76 
     77         final Socket socket;
     78         final DataInputStream in;
     79         StringBuilder builder = new StringBuilder();
     80         long lastTime = System.currentTimeMillis();
     81 
     82         private static final int HEADER_SIZE = 24;
     83 
     84         public LogReader() throws IOException {
     85             this.socket = new Socket("127.0.0.1", 5040);
     86             this.in = new DataInputStream(this.socket.getInputStream());
     87             // Write two newlines to indicate "no reader args"
     88             this.socket.getOutputStream().write('\n');
     89             this.socket.getOutputStream().write('\n');
     90         }
     91 
     92         public void run() {
     93             while (active) {
     94                 try {
     95                     while (in.available() > 0) {
     96                         logger.write("Reading message.\n".getBytes());
     97 
     98                         int length = in.readInt();
     99                         byte[] bytes = new byte[length];
    100                         in.readFully(bytes);
    101 
    102                         int tagEnd = next0(bytes, HEADER_SIZE);
    103                         int fileEnd = next0(bytes, tagEnd + 1);
    104                         int messageEnd = next0(bytes, fileEnd + 1);
    105 
    106                         CharSequence tag
    107                                 = forAsciiBytes(bytes, HEADER_SIZE, tagEnd);
    108                         CharSequence message
    109                                 = forAsciiBytes(bytes, fileEnd + 1, messageEnd);
    110 
    111                         builder.append(tag)
    112                                 .append(": ")
    113                                 .append(message)
    114                                 .append("\n");
    115                     }
    116 
    117                     logger.write("Updating UI.\n".getBytes());
    118                     handler.post(new AppendCharacters(builder));
    119                     builder = new StringBuilder();
    120 
    121                     try {
    122                         Thread.sleep(1000);
    123                     } catch (InterruptedException e) {}
    124                 } catch (final IOException e) {
    125                     handler.post(new AppendThrowable(e));
    126                 }
    127             }
    128         }
    129     }
    130 
    131     static int next0(byte[] bytes, int start) {
    132         for (int current = start; current < bytes.length; current++) {
    133             if (bytes[current] == 0)
    134                 return current;
    135         }
    136         return bytes.length;
    137     }
    138 
    139     private class AppendThrowable implements Runnable {
    140 
    141         private final Throwable t;
    142 
    143         public AppendThrowable(Throwable t) {
    144             this.t = t;
    145         }
    146 
    147         public void run() {
    148             appendThrowable(t);
    149         }
    150     }
    151 
    152     private class AppendCharacters implements Runnable {
    153 
    154         private final CharSequence message;
    155 
    156         public AppendCharacters(CharSequence message) {
    157             this.message = message;
    158         }
    159 
    160         public void run() {
    161             text.getText().append(message);
    162 //            try {
    163 //                logger.write(builder.toString().getBytes());
    164 //            } catch (IOException e) {
    165 //                appendThrowable(e);
    166 //            }
    167         }
    168     }
    169 }
    170