summaryrefslogtreecommitdiff
path: root/src/com/android/loganalysis/parser/WakelockParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/loganalysis/parser/WakelockParser.java')
-rw-r--r--src/com/android/loganalysis/parser/WakelockParser.java155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/com/android/loganalysis/parser/WakelockParser.java b/src/com/android/loganalysis/parser/WakelockParser.java
new file mode 100644
index 0000000..91652f7
--- /dev/null
+++ b/src/com/android/loganalysis/parser/WakelockParser.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2015 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.loganalysis.parser;
+
+import com.android.loganalysis.item.WakelockItem;
+import com.android.loganalysis.item.WakelockItem.WakeLockCategory;
+import com.android.loganalysis.util.NumberFormattingUtil;
+
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A {@link IParser} to handle the parsing of wakelock information
+ */
+public class WakelockParser implements IParser {
+
+ private static final Pattern PARTIAL_WAKE_LOCK_START_PAT = Pattern.compile(
+ "^\\s*All partial wake locks:$");
+
+ private static final String WAKE_LOCK_PAT_SUFFIX =
+ "(?:(\\d+)d)?\\s?(?:(\\d+)h)?\\s?(?:(\\d+)m)?\\s?(?:(\\d+)s)?\\s?(?:(\\d+)ms)?"
+ + "\\s?\\((\\d+) times\\) realtime";
+
+ /**
+ * Match a valid line such as:
+ * " Kernel Wake lock PowerManagerService.WakeLocks: 1h 13m 50s 950ms (2858 times) realtime"
+ */
+ private static final Pattern KERNEL_WAKE_LOCK_PAT = Pattern.compile(
+ "^\\s*Kernel Wake lock (.+): " + WAKE_LOCK_PAT_SUFFIX);
+ /**
+ * Match a valid line such as:
+ * " Wake lock u0a7 NlpWakeLock: 8m 13s 203ms (1479 times) realtime";
+ */
+ private static final Pattern PARTIAL_WAKE_LOCK_PAT = Pattern.compile(
+ "^\\s*Wake lock (.*)\\s(.+): " + WAKE_LOCK_PAT_SUFFIX);
+
+ private WakelockItem mItem = new WakelockItem();
+
+ public static final int TOP_WAKELOCK_COUNT = 5;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public WakelockItem parse(List<String> lines) {
+ boolean inPartialWakeLock = false;
+ Matcher m = null;
+ int wakelockCounter = 0;
+ for (String line : lines) {
+ if ("".equals(line.trim())) {
+ if (inPartialWakeLock) {
+ // Done with parsing wakelock sections
+ break;
+ } else {
+ // Done with parsing kernel wakelocks and continue with
+ // partial wakelock
+ wakelockCounter = 0;
+ continue;
+ }
+ }
+ m = KERNEL_WAKE_LOCK_PAT.matcher(line);
+ if (m.matches()) {
+ if (wakelockCounter < TOP_WAKELOCK_COUNT &&
+ !line.contains("PowerManagerService.WakeLocks")) {
+ parseKernelWakeLock(line, WakeLockCategory.KERNEL_WAKELOCK);
+ wakelockCounter++;
+ }
+ continue;
+ }
+ m = PARTIAL_WAKE_LOCK_START_PAT.matcher(line);
+ if (m.matches()) {
+ inPartialWakeLock = true;
+ continue;
+ }
+ m = PARTIAL_WAKE_LOCK_PAT.matcher(line);
+ if (m.matches() && wakelockCounter < TOP_WAKELOCK_COUNT) {
+ parsePartialWakeLock(line, WakeLockCategory.PARTIAL_WAKELOCK);
+ wakelockCounter++;
+ }
+ }
+ return mItem;
+ }
+
+ /**
+ * Parse a line of output and add it to wakelock section
+ * <p>
+ * Exposed for unit testing.
+ * </p>
+ */
+ void parseKernelWakeLock(String line, WakeLockCategory category) {
+ Matcher m = KERNEL_WAKE_LOCK_PAT.matcher(line);
+ if (!m.matches()) {
+ return;
+ }
+ final String name = m.group(1);
+ final long wakelockTime = NumberFormattingUtil.getMs(
+ NumberFormattingUtil.parseIntOrZero(m.group(2)),
+ NumberFormattingUtil.parseIntOrZero(m.group(3)),
+ NumberFormattingUtil.parseIntOrZero(m.group(4)),
+ NumberFormattingUtil.parseIntOrZero(m.group(5)),
+ NumberFormattingUtil.parseIntOrZero(m.group(6)));
+
+ final int timesCalled = Integer.parseInt(m.group(7));
+
+ mItem.addWakeLock(name, wakelockTime, timesCalled, category);
+ }
+
+ /**
+ * Parse a line of output and add it to wake lock section.
+ * <p>
+ * Exposed for unit testing.
+ * </p>
+ */
+ void parsePartialWakeLock(String line, WakeLockCategory category) {
+ Matcher m = PARTIAL_WAKE_LOCK_PAT.matcher(line);
+ if (!m.matches()) {
+ return;
+ }
+ final String processUID = m.group(1);
+ final String name = m.group(2);
+ final long wakelockTime = NumberFormattingUtil.getMs(
+ NumberFormattingUtil.parseIntOrZero(m.group(3)),
+ NumberFormattingUtil.parseIntOrZero(m.group(4)),
+ NumberFormattingUtil.parseIntOrZero(m.group(5)),
+ NumberFormattingUtil.parseIntOrZero(m.group(6)),
+ NumberFormattingUtil.parseIntOrZero(m.group(7)));
+ final int timesCalled = Integer.parseInt(m.group(8));
+
+ mItem.addWakeLock(name, processUID, wakelockTime, timesCalled, category);
+ }
+
+ /**
+ * Get the {@link WakelockItem}.
+ * <p>
+ * Exposed for unit testing.
+ * </p>
+ */
+ WakelockItem getItem() {
+ return mItem;
+ }
+}