upload android base code part9
This commit is contained in:
parent
5425409085
commit
071cdf34cd
2679 changed files with 329442 additions and 0 deletions
7
android/sdk/eventanalyzer/.classpath
Normal file
7
android/sdk/eventanalyzer/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
17
android/sdk/eventanalyzer/.project
Normal file
17
android/sdk/eventanalyzer/.project
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>eventanalyzer</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
18
android/sdk/eventanalyzer/Android.mk
Normal file
18
android/sdk/eventanalyzer/Android.mk
Normal file
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# Copyright (C) 2008 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
EVENTANALUZER_LOCAL_DIR := $(call my-dir)
|
||||
include $(EVENTANALUZER_LOCAL_DIR)/etc/Android.mk
|
||||
include $(EVENTANALUZER_LOCAL_DIR)/src/Android.mk
|
190
android/sdk/eventanalyzer/NOTICE
Normal file
190
android/sdk/eventanalyzer/NOTICE
Normal file
|
@ -0,0 +1,190 @@
|
|||
|
||||
Copyright (c) 2005-2008, The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
21
android/sdk/eventanalyzer/etc/Android.mk
Normal file
21
android/sdk/eventanalyzer/etc/Android.mk
Normal file
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# Copyright (C) 2008 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_PREBUILT_EXECUTABLES := eventanalyzer
|
||||
include $(BUILD_HOST_PREBUILT)
|
||||
|
73
android/sdk/eventanalyzer/etc/eventanalyzer
Executable file
73
android/sdk/eventanalyzer/etc/eventanalyzer
Executable file
|
@ -0,0 +1,73 @@
|
|||
#!/bin/sh
|
||||
# Copyright 2005-2007, The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Set up prog to be the path of this script, including following symlinks,
|
||||
# and set up progdir to be the fully-qualified pathname of its directory.
|
||||
prog="$0"
|
||||
while [ -h "${prog}" ]; do
|
||||
newProg=`/bin/ls -ld "${prog}"`
|
||||
newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
|
||||
if expr "x${newProg}" : 'x/' >/dev/null; then
|
||||
prog="${newProg}"
|
||||
else
|
||||
progdir=`dirname "${prog}"`
|
||||
prog="${progdir}/${newProg}"
|
||||
fi
|
||||
done
|
||||
oldwd=`pwd`
|
||||
progdir=`dirname "${prog}"`
|
||||
cd "${progdir}"
|
||||
progdir=`pwd`
|
||||
prog="${progdir}"/`basename "${prog}"`
|
||||
cd "${oldwd}"
|
||||
|
||||
jarfile=eventanalyzer.jar
|
||||
frameworkdir="$progdir"
|
||||
libdir="$progdir"
|
||||
if [ ! -r "$frameworkdir/$jarfile" ]
|
||||
then
|
||||
frameworkdir=`dirname "$progdir"`/tools/lib
|
||||
libdir=`dirname "$progdir"`/tools/lib
|
||||
fi
|
||||
if [ ! -r "$frameworkdir/$jarfile" ]
|
||||
then
|
||||
frameworkdir=`dirname "$progdir"`/framework
|
||||
libdir=`dirname "$progdir"`/lib
|
||||
fi
|
||||
if [ ! -r "$frameworkdir/$jarfile" ]
|
||||
then
|
||||
echo `basename "$prog"`": can't find $jarfile"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Check args.
|
||||
# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
|
||||
if [ `uname` = "Darwin" ]; then
|
||||
os_opts="-XstartOnFirstThread"
|
||||
else
|
||||
os_opts=
|
||||
fi
|
||||
|
||||
if [ "$OSTYPE" = "cygwin" ] ; then
|
||||
jarpath=`cygpath -w "$frameworkdir/$jarfile"`
|
||||
progdir=`cygpath -w "$progdir"`
|
||||
else
|
||||
jarpath="$frameworkdir/$jarfile"
|
||||
fi
|
||||
|
||||
# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
|
||||
# might need more memory, e.g. -Xmx128M
|
||||
exec java -Xmx128M $os_opts -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -jar "$jarpath" "$@"
|
1
android/sdk/eventanalyzer/etc/manifest.txt
Normal file
1
android/sdk/eventanalyzer/etc/manifest.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Main-Class: com.android.eventanalyzer.EventAnalyzer
|
26
android/sdk/eventanalyzer/src/Android.mk
Normal file
26
android/sdk/eventanalyzer/src/Android.mk
Normal file
|
@ -0,0 +1,26 @@
|
|||
#
|
||||
# Copyright (C) 2008 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||
|
||||
LOCAL_JAR_MANIFEST := ../etc/manifest.txt
|
||||
LOCAL_JAVA_LIBRARIES := \
|
||||
ddmlib-prebuilt
|
||||
LOCAL_MODULE := eventanalyzer
|
||||
|
||||
include $(BUILD_HOST_JAVA_LIBRARY)
|
|
@ -0,0 +1,488 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.eventanalyzer;
|
||||
|
||||
import com.android.ddmlib.AdbCommandRejectedException;
|
||||
import com.android.ddmlib.AndroidDebugBridge;
|
||||
import com.android.ddmlib.IDevice;
|
||||
import com.android.ddmlib.Log;
|
||||
import com.android.ddmlib.TimeoutException;
|
||||
import com.android.ddmlib.Log.ILogOutput;
|
||||
import com.android.ddmlib.Log.LogLevel;
|
||||
import com.android.ddmlib.log.EventContainer;
|
||||
import com.android.ddmlib.log.EventLogParser;
|
||||
import com.android.ddmlib.log.InvalidTypeException;
|
||||
import com.android.ddmlib.log.LogReceiver;
|
||||
import com.android.ddmlib.log.LogReceiver.ILogListener;
|
||||
import com.android.ddmlib.log.LogReceiver.LogEntry;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Connects to a device using ddmlib and analyze its event log.
|
||||
*/
|
||||
public class EventAnalyzer implements ILogListener {
|
||||
|
||||
private final static int TAG_ACTIVITY_LAUNCH_TIME = 30009;
|
||||
private final static char DATA_SEPARATOR = ',';
|
||||
|
||||
private final static String CVS_EXT = ".csv";
|
||||
private final static String TAG_FILE_EXT = ".tag"; //$NON-NLS-1$
|
||||
|
||||
private EventLogParser mParser;
|
||||
private TreeMap<String, ArrayList<Long>> mLaunchMap = new TreeMap<String, ArrayList<Long>>();
|
||||
|
||||
String mInputTextFile = null;
|
||||
String mInputBinaryFile = null;
|
||||
String mInputDevice = null;
|
||||
String mInputFolder = null;
|
||||
String mAlternateTagFile = null;
|
||||
String mOutputFile = null;
|
||||
|
||||
public static void main(String[] args) {
|
||||
new EventAnalyzer().run(args);
|
||||
}
|
||||
|
||||
private void run(String[] args) {
|
||||
if (args.length == 0) {
|
||||
printUsageAndQuit();
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
do {
|
||||
String argument = args[index++];
|
||||
|
||||
if ("-s".equals(argument)) {
|
||||
checkInputValidity("-s");
|
||||
|
||||
if (index == args.length) {
|
||||
printUsageAndQuit();
|
||||
}
|
||||
|
||||
mInputDevice = args[index++];
|
||||
} else if ("-fb".equals(argument)) {
|
||||
checkInputValidity("-fb");
|
||||
|
||||
if (index == args.length) {
|
||||
printUsageAndQuit();
|
||||
}
|
||||
|
||||
mInputBinaryFile = args[index++];
|
||||
} else if ("-ft".equals(argument)) {
|
||||
checkInputValidity("-ft");
|
||||
|
||||
if (index == args.length) {
|
||||
printUsageAndQuit();
|
||||
}
|
||||
|
||||
mInputTextFile = args[index++];
|
||||
} else if ("-F".equals(argument)) {
|
||||
checkInputValidity("-F");
|
||||
|
||||
if (index == args.length) {
|
||||
printUsageAndQuit();
|
||||
}
|
||||
|
||||
mInputFolder = args[index++];
|
||||
} else if ("-t".equals(argument)) {
|
||||
if (index == args.length) {
|
||||
printUsageAndQuit();
|
||||
}
|
||||
|
||||
mAlternateTagFile = args[index++];
|
||||
} else {
|
||||
// get the filepath and break.
|
||||
mOutputFile = argument;
|
||||
|
||||
// should not be any other device.
|
||||
if (index < args.length) {
|
||||
printAndExit("Too many arguments!", false /* terminate */);
|
||||
}
|
||||
}
|
||||
} while (index < args.length);
|
||||
|
||||
if ((mInputTextFile == null && mInputBinaryFile == null && mInputFolder == null &&
|
||||
mInputDevice == null)) {
|
||||
printUsageAndQuit();
|
||||
}
|
||||
|
||||
File outputParent = new File(mOutputFile).getParentFile();
|
||||
if (outputParent == null || outputParent.isDirectory() == false) {
|
||||
printAndExit(String.format("%1$s is not a valid ouput file", mOutputFile),
|
||||
false /* terminate */);
|
||||
}
|
||||
|
||||
// redirect the log output to /dev/null
|
||||
Log.setLogOutput(new ILogOutput() {
|
||||
public void printAndPromptLog(LogLevel logLevel, String tag, String message) {
|
||||
// pass
|
||||
}
|
||||
|
||||
public void printLog(LogLevel logLevel, String tag, String message) {
|
||||
// pass
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
if (mInputBinaryFile != null) {
|
||||
parseBinaryLogFile();
|
||||
} else if (mInputTextFile != null) {
|
||||
parseTextLogFile(mInputTextFile);
|
||||
} else if (mInputFolder != null) {
|
||||
parseFolder(mInputFolder);
|
||||
} else if (mInputDevice != null) {
|
||||
parseLogFromDevice();
|
||||
}
|
||||
|
||||
// analyze the data gathered by the parser methods
|
||||
analyzeData();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a binary event log file located at {@link #mInputBinaryFile}.
|
||||
* @throws IOException
|
||||
*/
|
||||
private void parseBinaryLogFile() throws IOException {
|
||||
mParser = new EventLogParser();
|
||||
|
||||
String tagFile = mInputBinaryFile + TAG_FILE_EXT;
|
||||
if (mParser.init(tagFile) == false) {
|
||||
// if we have an alternate location
|
||||
if (mAlternateTagFile != null) {
|
||||
if (mParser.init(mAlternateTagFile) == false) {
|
||||
printAndExit("Failed to get event tags from " + mAlternateTagFile,
|
||||
false /* terminate*/);
|
||||
}
|
||||
} else {
|
||||
printAndExit("Failed to get event tags from " + tagFile, false /* terminate*/);
|
||||
}
|
||||
}
|
||||
|
||||
LogReceiver receiver = new LogReceiver(this);
|
||||
|
||||
byte[] buffer = new byte[256];
|
||||
|
||||
FileInputStream fis = new FileInputStream(mInputBinaryFile);
|
||||
|
||||
int count;
|
||||
while ((count = fis.read(buffer)) != -1) {
|
||||
receiver.parseNewData(buffer, 0, count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a text Log file.
|
||||
* @param filePath the location of the file.
|
||||
* @throws IOException
|
||||
*/
|
||||
private void parseTextLogFile(String filePath) throws IOException {
|
||||
mParser = new EventLogParser();
|
||||
|
||||
String tagFile = filePath + TAG_FILE_EXT;
|
||||
if (mParser.init(tagFile) == false) {
|
||||
// if we have an alternate location
|
||||
if (mAlternateTagFile != null) {
|
||||
if (mParser.init(mAlternateTagFile) == false) {
|
||||
printAndExit("Failed to get event tags from " + mAlternateTagFile,
|
||||
false /* terminate*/);
|
||||
}
|
||||
} else {
|
||||
printAndExit("Failed to get event tags from " + tagFile, false /* terminate*/);
|
||||
}
|
||||
}
|
||||
|
||||
// read the lines from the file and process them.
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(new FileInputStream(filePath)));
|
||||
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
processEvent(mParser.parse(line));
|
||||
}
|
||||
}
|
||||
|
||||
private void parseLogFromDevice() throws IOException, TimeoutException,
|
||||
AdbCommandRejectedException {
|
||||
// init the lib
|
||||
AndroidDebugBridge.init(false /* debugger support */);
|
||||
|
||||
try {
|
||||
AndroidDebugBridge bridge = AndroidDebugBridge.createBridge();
|
||||
|
||||
// we can't just ask for the device list right away, as the internal thread getting
|
||||
// them from ADB may not be done getting the first list.
|
||||
// Since we don't really want getDevices() to be blocking, we wait here manually.
|
||||
int count = 0;
|
||||
while (bridge.hasInitialDeviceList() == false) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
count++;
|
||||
} catch (InterruptedException e) {
|
||||
// pass
|
||||
}
|
||||
|
||||
// let's not wait > 10 sec.
|
||||
if (count > 100) {
|
||||
printAndExit("Timeout getting device list!", true /* terminate*/);
|
||||
}
|
||||
}
|
||||
|
||||
// now get the devices
|
||||
IDevice[] devices = bridge.getDevices();
|
||||
|
||||
for (IDevice device : devices) {
|
||||
if (device.getSerialNumber().equals(mInputDevice)) {
|
||||
grabLogFrom(device);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("Could not find " + mInputDevice);
|
||||
} finally {
|
||||
AndroidDebugBridge.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the log files located in the folder, and its sub-folders.
|
||||
* @param folderPath the path to the folder.
|
||||
*/
|
||||
private void parseFolder(String folderPath) {
|
||||
File f = new File(folderPath);
|
||||
if (f.isDirectory() == false) {
|
||||
printAndExit(String.format("%1$s is not a valid folder", folderPath),
|
||||
false /* terminate */);
|
||||
}
|
||||
|
||||
String[] files = f.list(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
name = name.toLowerCase();
|
||||
return name.endsWith(".tag") == false;
|
||||
}
|
||||
});
|
||||
|
||||
for (String file : files) {
|
||||
try {
|
||||
f = new File(folderPath + File.separator + file);
|
||||
if (f.isDirectory()) {
|
||||
parseFolder(f.getAbsolutePath());
|
||||
} else {
|
||||
parseTextLogFile(f.getAbsolutePath());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// ignore this file.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void grabLogFrom(IDevice device) throws IOException, TimeoutException,
|
||||
AdbCommandRejectedException {
|
||||
mParser = new EventLogParser();
|
||||
if (mParser.init(device) == false) {
|
||||
printAndExit("Failed to get event-log-tags from " + device.getSerialNumber(),
|
||||
true /* terminate*/);
|
||||
}
|
||||
|
||||
LogReceiver receiver = new LogReceiver(this);
|
||||
|
||||
device.runEventLogService(receiver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze the data and writes it to {@link #mOutputFile}
|
||||
* @throws IOException
|
||||
*/
|
||||
private void analyzeData() throws IOException {
|
||||
BufferedWriter writer = null;
|
||||
try {
|
||||
// make sure the file name has the proper extension.
|
||||
if (mOutputFile.toLowerCase().endsWith(CVS_EXT) == false) {
|
||||
mOutputFile = mOutputFile + CVS_EXT;
|
||||
}
|
||||
|
||||
writer = new BufferedWriter(new FileWriter(mOutputFile));
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
// write the list of launch start. One column per activity.
|
||||
Set<String> activities = mLaunchMap.keySet();
|
||||
|
||||
// write the column headers.
|
||||
for (String activity : activities) {
|
||||
builder.append(activity).append(DATA_SEPARATOR);
|
||||
}
|
||||
writer.write(builder.append('\n').toString());
|
||||
|
||||
// loop on the activities and write their values.
|
||||
boolean moreValues = true;
|
||||
int index = 0;
|
||||
while (moreValues) {
|
||||
moreValues = false;
|
||||
builder.setLength(0);
|
||||
|
||||
for (String activity : activities) {
|
||||
// get the activity list.
|
||||
ArrayList<Long> list = mLaunchMap.get(activity);
|
||||
if (index < list.size()) {
|
||||
moreValues = true;
|
||||
builder.append(list.get(index).longValue()).append(DATA_SEPARATOR);
|
||||
} else {
|
||||
builder.append(DATA_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
// write the line.
|
||||
if (moreValues) {
|
||||
writer.write(builder.append('\n').toString());
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
// write per-activity stats.
|
||||
for (String activity : activities) {
|
||||
builder.setLength(0);
|
||||
builder.append(activity).append(DATA_SEPARATOR);
|
||||
|
||||
// get the activity list.
|
||||
ArrayList<Long> list = mLaunchMap.get(activity);
|
||||
|
||||
// sort the list
|
||||
Collections.sort(list);
|
||||
|
||||
// write min/max
|
||||
builder.append(list.get(0).longValue()).append(DATA_SEPARATOR);
|
||||
builder.append(list.get(list.size()-1).longValue()).append(DATA_SEPARATOR);
|
||||
|
||||
// write median value
|
||||
builder.append(list.get(list.size()/2).longValue()).append(DATA_SEPARATOR);
|
||||
|
||||
// compute and write average
|
||||
long total = 0; // despite being encoded on a long, the values are low enough that
|
||||
// a Long should be enough to compute the total
|
||||
for (Long value : list) {
|
||||
total += value.longValue();
|
||||
}
|
||||
builder.append(total / list.size()).append(DATA_SEPARATOR);
|
||||
|
||||
// finally write the data.
|
||||
writer.write(builder.append('\n').toString());
|
||||
}
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.android.ddmlib.log.LogReceiver.ILogListener#newData(byte[], int, int)
|
||||
*/
|
||||
public void newData(byte[] data, int offset, int length) {
|
||||
// we ignore raw data. New entries are processed in #newEntry(LogEntry)
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.android.ddmlib.log.LogReceiver.ILogListener#newEntry(com.android.ddmlib.log.LogReceiver.LogEntry)
|
||||
*/
|
||||
public void newEntry(LogEntry entry) {
|
||||
// parse and process the entry data.
|
||||
processEvent(mParser.parse(entry));
|
||||
}
|
||||
|
||||
private void processEvent(EventContainer event) {
|
||||
if (event != null && event.mTag == TAG_ACTIVITY_LAUNCH_TIME) {
|
||||
// get the activity name
|
||||
try {
|
||||
String name = event.getValueAsString(0);
|
||||
|
||||
// get the launch time
|
||||
Object value = event.getValue(1);
|
||||
if (value instanceof Long) {
|
||||
addLaunchTime(name, (Long)value);
|
||||
}
|
||||
|
||||
} catch (InvalidTypeException e) {
|
||||
// Couldn't get the name as a string...
|
||||
// Ignore this event.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addLaunchTime(String name, Long value) {
|
||||
ArrayList<Long> list = mLaunchMap.get(name);
|
||||
|
||||
if (list == null) {
|
||||
list = new ArrayList<Long>();
|
||||
mLaunchMap.put(name, list);
|
||||
}
|
||||
|
||||
list.add(value);
|
||||
}
|
||||
|
||||
private void checkInputValidity(String option) {
|
||||
if (mInputTextFile != null || mInputBinaryFile != null) {
|
||||
printAndExit(String.format("ERROR: %1$s cannot be used with an input file.", option),
|
||||
false /* terminate */);
|
||||
} else if (mInputFolder != null) {
|
||||
printAndExit(String.format("ERROR: %1$s cannot be used with an input file.", option),
|
||||
false /* terminate */);
|
||||
} else if (mInputDevice != null) {
|
||||
printAndExit(String.format("ERROR: %1$s cannot be used with an input device serial number.",
|
||||
option), false /* terminate */);
|
||||
}
|
||||
}
|
||||
|
||||
private static void printUsageAndQuit() {
|
||||
// 80 cols marker: 01234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
System.out.println("Usage:");
|
||||
System.out.println(" eventanalyzer [-t <TAG_FILE>] <SOURCE> <OUTPUT>");
|
||||
System.out.println("");
|
||||
System.out.println("Possible sources:");
|
||||
System.out.println(" -fb <file> The path to a binary event log, gathered by dumpeventlog");
|
||||
System.out.println(" -ft <file> The path to a text event log, gathered by adb logcat -b events");
|
||||
System.out.println(" -F <folder> The path to a folder containing multiple text log files.");
|
||||
System.out.println(" -s <serial> The serial number of the Device to grab the event log from.");
|
||||
System.out.println("Options:");
|
||||
System.out.println(" -t <file> The path to tag file to use in case the one associated with");
|
||||
System.out.println(" the source is missing");
|
||||
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
private static void printAndExit(String message, boolean terminate) {
|
||||
System.out.println(message);
|
||||
if (terminate) {
|
||||
AndroidDebugBridge.terminate();
|
||||
}
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue