1 /*
2  * Copyright (C) 2008 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.dumpeventlog;
18 
19 import com.android.ddmlib.AdbCommandRejectedException;
20 import com.android.ddmlib.AndroidDebugBridge;
21 import com.android.ddmlib.IDevice;
22 import com.android.ddmlib.Log;
23 import com.android.ddmlib.TimeoutException;
24 import com.android.ddmlib.Log.ILogOutput;
25 import com.android.ddmlib.Log.LogLevel;
26 import com.android.ddmlib.log.LogReceiver;
27 import com.android.ddmlib.log.LogReceiver.ILogListener;
28 import com.android.ddmlib.log.LogReceiver.LogEntry;
29 
30 import java.io.FileNotFoundException;
31 import java.io.FileOutputStream;
32 import java.io.IOException;
33 
34 /**
35  * Connects to a device using ddmlib and dumps its event log as long as the device is connected.
36  */
37 public class DumpEventLog {
38 
39     /**
40      * Custom {@link ILogListener} to receive and save the event log raw output.
41      */
42     private static class LogWriter implements ILogListener {
43         private FileOutputStream mOutputStream;
44         private LogReceiver mReceiver;
45 
LogWriter(String filePath)46         public LogWriter(String filePath) throws IOException {
47             mOutputStream = new FileOutputStream(filePath);
48         }
49 
newData(byte[] data, int offset, int length)50         public void newData(byte[] data, int offset, int length) {
51             try {
52                 mOutputStream.write(data, offset, length);
53             } catch (IOException e) {
54                 if (mReceiver != null) {
55                     mReceiver.cancel();
56                 }
57                 System.out.println(e);
58             }
59         }
60 
newEntry(LogEntry entry)61         public void newEntry(LogEntry entry) {
62             // pass
63         }
64 
setReceiver(LogReceiver receiver)65         public void setReceiver(LogReceiver receiver) {
66             mReceiver = receiver;
67         }
68 
done()69         public void done() throws IOException {
70             mOutputStream.close();
71         }
72     }
73 
main(String[] args)74     public static void main(String[] args) {
75         if (args.length != 2) {
76             System.out.println("Usage: dumpeventlog <device s/n> <filepath>");
77             return;
78         }
79 
80         // redirect the log output to /dev/null
81         Log.setLogOutput(new ILogOutput() {
82             public void printAndPromptLog(LogLevel logLevel, String tag, String message) {
83                 // pass
84             }
85 
86             public void printLog(LogLevel logLevel, String tag, String message) {
87                 // pass
88             }
89         });
90 
91         // init the lib
92         AndroidDebugBridge.init(false /* debugger support */);
93 
94         try {
95             AndroidDebugBridge bridge = AndroidDebugBridge.createBridge();
96 
97             // we can't just ask for the device list right away, as the internal thread getting
98             // them from ADB may not be done getting the first list.
99             // Since we don't really want getDevices() to be blocking, we wait here manually.
100             int count = 0;
101             while (bridge.hasInitialDeviceList() == false) {
102                 try {
103                     Thread.sleep(100);
104                     count++;
105                 } catch (InterruptedException e) {
106                     // pass
107                 }
108 
109                 // let's not wait > 10 sec.
110                 if (count > 100) {
111                     System.err.println("Timeout getting device list!");
112                     return;
113                 }
114             }
115 
116             // now get the devices
117             IDevice[] devices = bridge.getDevices();
118 
119             for (IDevice device : devices) {
120                 if (device.getSerialNumber().equals(args[0])) {
121                     try {
122                         grabLogFrom(device, args[1]);
123                     } catch (FileNotFoundException e) {
124                         e.printStackTrace();
125                     } catch (Exception e) {
126                         e.printStackTrace();
127                     }
128                     return;
129                 }
130             }
131 
132             System.err.println("Could not find " + args[0]);
133         } finally {
134             AndroidDebugBridge.terminate();
135         }
136     }
137 
grabLogFrom(IDevice device, String filePath)138     private static void grabLogFrom(IDevice device, String filePath) throws IOException,
139             TimeoutException, AdbCommandRejectedException {
140         LogWriter writer = new LogWriter(filePath);
141         LogReceiver receiver = new LogReceiver(writer);
142         writer.setReceiver(receiver);
143 
144         device.runEventLogService(receiver);
145 
146         writer.done();
147     }
148 }
149