Skip to content
Snippets Groups Projects
Commit 44e6c57b authored by Netta Peterbursky's avatar Netta Peterbursky
Browse files

Add app versions to Bugreport parser (for event history view in stability dashboard).

Bug: 38415015
Test: BugreportParserTest, DumpsysPackageStatsParserTest, DumpsysParserTest
Change-Id: Id6e5ccbd39188be0b6908df751b310cd0f642593
parent da7b04ca
No related branches found
No related tags found
No related merge requests found
/*
* Copyright (C) 2017 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.item;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/** An {@link IItem} used to store an app's version code and name. */
public class AppVersionItem extends GenericItem {
/** Constants for JSON output */
public static final String VERSION_CODE = "VERSION_CODE";
public static final String VERSION_NAME = "VERSION_NAME";
private static final Set<String> ATTRIBUTES =
new HashSet<String>(Arrays.asList(VERSION_CODE, VERSION_NAME));
/**
* The constructor for {@link AppVersionItem}
*
* @param versionCode the version code
* @param versionName the version name
*/
public AppVersionItem(int versionCode, String versionName) {
super(ATTRIBUTES);
setAttribute(VERSION_CODE, versionCode);
setAttribute(VERSION_NAME, versionName);
}
public int getVersionCode() {
return (Integer) getAttribute(VERSION_CODE);
}
public String getVersionName() {
return (String) getAttribute(VERSION_NAME);
}
}
...@@ -27,12 +27,15 @@ public class DumpsysItem extends GenericItem { ...@@ -27,12 +27,15 @@ public class DumpsysItem extends GenericItem {
/** Constant for JSON output */ /** Constant for JSON output */
private static final String BATTERY_STATS = "BATTERY_STATS"; private static final String BATTERY_STATS = "BATTERY_STATS";
/** Constant for JSON output */ /** Constant for JSON output */
private static final String PACKAGE_STATS = "PACKAGE_STATS";
/** Constant for JSON output */
private static final String PROC_STATS = "PROC_STATS"; private static final String PROC_STATS = "PROC_STATS";
/** Constant for JSON output */ /** Constant for JSON output */
private static final String WIFI_STATS = "WIFI_STATS"; private static final String WIFI_STATS = "WIFI_STATS";
private static final Set<String> ATTRIBUTES = new HashSet<String>(Arrays.asList( private static final Set<String> ATTRIBUTES =
BATTERY_STATS, PROC_STATS, WIFI_STATS)); new HashSet<String>(
Arrays.asList(BATTERY_STATS, PACKAGE_STATS, PROC_STATS, WIFI_STATS));
/** /**
* The constructor for {@link DumpsysItem}. * The constructor for {@link DumpsysItem}.
...@@ -48,9 +51,12 @@ public class DumpsysItem extends GenericItem { ...@@ -48,9 +51,12 @@ public class DumpsysItem extends GenericItem {
setAttribute(BATTERY_STATS, batteryStats); setAttribute(BATTERY_STATS, batteryStats);
} }
/** /** Set the {@link DumpsysPackageStatsItem} of the bugreport. */
* Set the {@link DumpsysProcStatsItem} of the bugreport. public void setPackageStats(DumpsysPackageStatsItem packageStats) {
*/ setAttribute(PACKAGE_STATS, packageStats);
}
/** Set the {@link DumpsysProcStatsItem} of the bugreport. */
public void setProcStats(DumpsysProcStatsItem procStats) { public void setProcStats(DumpsysProcStatsItem procStats) {
setAttribute(PROC_STATS, procStats); setAttribute(PROC_STATS, procStats);
} }
...@@ -69,9 +75,12 @@ public class DumpsysItem extends GenericItem { ...@@ -69,9 +75,12 @@ public class DumpsysItem extends GenericItem {
return (DumpsysBatteryStatsItem) getAttribute(BATTERY_STATS); return (DumpsysBatteryStatsItem) getAttribute(BATTERY_STATS);
} }
/** /** Get the {@link DumpsysPackageStatsItem} of the bugreport. */
* Get the {@link DumpsysProcStatsItem} of the bugreport. public DumpsysPackageStatsItem getPackageStats() {
*/ return (DumpsysPackageStatsItem) getAttribute(PACKAGE_STATS);
}
/** Get the {@link DumpsysProcStatsItem} of the bugreport. */
public DumpsysProcStatsItem getProcStats() { public DumpsysProcStatsItem getProcStats() {
return (DumpsysProcStatsItem) getAttribute(PROC_STATS); return (DumpsysProcStatsItem) getAttribute(PROC_STATS);
} }
......
/*
* Copyright (C) 2017 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.item;
import org.json.JSONException;
import org.json.JSONObject;
/** An {@link IItem} used to store apps and their version codes and names. */
public class DumpsysPackageStatsItem extends GenericMapItem<AppVersionItem> {
private static final long serialVersionUID = 1L;
/** Constant for JSON output */
public static final String APP_VERSIONS = "APP_VERSIONS";
/** {@inheritDoc} */
@Override
public JSONObject toJson() {
JSONObject object = new JSONObject();
try {
object.put(APP_VERSIONS, super.toJson());
} catch (JSONException e) {
// Ignore
}
return object;
}
}
/*
* Copyright (C) 2017 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.AppVersionItem;
import com.android.loganalysis.item.DumpsysPackageStatsItem;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** A {@link IParser} to parse package stats and create a mapping table of packages and versions */
public class DumpsysPackageStatsParser implements IParser {
/** Matches: Package [com.google.android.googlequicksearchbox] (607929e): */
private static final Pattern PACKAGE_NAME = Pattern.compile("^\\s*Package \\[(.*)\\].*");
/** Matches: versionCode=300734793 minSdk=10000 targetSdk=10000 */
private static final Pattern VERSION_CODE = Pattern.compile("^\\s*versionCode=(\\d+).*");
/** Matches: versionName=6.16.35.26.arm64 */
private static final Pattern VERSION_NAME = Pattern.compile("^\\s*versionName=(.*)$");
/**
* {@inheritDoc}
*
* @return The {@link DumpsysPackageStatsItem}.
*/
@Override
public DumpsysPackageStatsItem parse(List<String> lines) {
DumpsysPackageStatsItem item = new DumpsysPackageStatsItem();
String packageName = null;
String versionCode = null;
String versionName = null;
for (String line : lines) {
Matcher m = PACKAGE_NAME.matcher(line);
if (m.matches()) {
packageName = m.group(1);
versionCode = null;
versionName = null;
continue;
}
m = VERSION_CODE.matcher(line);
if (m.matches()) {
versionCode = m.group(1);
continue;
}
m = VERSION_NAME.matcher(line);
if (m.matches()) {
versionName = m.group(1).trim();
if (packageName != null && versionCode != null) {
item.put(
packageName,
new AppVersionItem(Integer.parseInt(versionCode), versionName));
}
packageName = null;
}
}
return item;
}
}
...@@ -18,6 +18,7 @@ package com.android.loganalysis.parser; ...@@ -18,6 +18,7 @@ package com.android.loganalysis.parser;
import com.android.loganalysis.item.DumpsysBatteryStatsItem; import com.android.loganalysis.item.DumpsysBatteryStatsItem;
import com.android.loganalysis.item.DumpsysItem; import com.android.loganalysis.item.DumpsysItem;
import com.android.loganalysis.item.DumpsysPackageStatsItem;
import com.android.loganalysis.item.DumpsysProcStatsItem; import com.android.loganalysis.item.DumpsysProcStatsItem;
import com.android.loganalysis.item.DumpsysWifiStatsItem; import com.android.loganalysis.item.DumpsysWifiStatsItem;
...@@ -29,11 +30,13 @@ import java.util.List; ...@@ -29,11 +30,13 @@ import java.util.List;
public class DumpsysParser extends AbstractSectionParser { public class DumpsysParser extends AbstractSectionParser {
private static final String BATTERY_STATS_SECTION_REGEX = "^DUMP OF SERVICE batterystats:$"; private static final String BATTERY_STATS_SECTION_REGEX = "^DUMP OF SERVICE batterystats:$";
private static final String PACKAGE_SECTION_REGEX = "^DUMP OF SERVICE package:";
private static final String PROC_STATS_SECTION_REGEX = "^DUMP OF SERVICE procstats:"; private static final String PROC_STATS_SECTION_REGEX = "^DUMP OF SERVICE procstats:";
private static final String WIFI_SECTION_REGEX = "^DUMP OF SERVICE wifi:"; private static final String WIFI_SECTION_REGEX = "^DUMP OF SERVICE wifi:";
private static final String NOOP_SECTION_REGEX = "DUMP OF SERVICE .*"; private static final String NOOP_SECTION_REGEX = "DUMP OF SERVICE .*";
private DumpsysBatteryStatsParser mBatteryStatsParser = new DumpsysBatteryStatsParser(); private DumpsysBatteryStatsParser mBatteryStatsParser = new DumpsysBatteryStatsParser();
private DumpsysPackageStatsParser mPackageStatsParser = new DumpsysPackageStatsParser();
private DumpsysProcStatsParser mProcStatsParser = new DumpsysProcStatsParser(); private DumpsysProcStatsParser mProcStatsParser = new DumpsysProcStatsParser();
private DumpsysWifiStatsParser mWifiStatsParser = new DumpsysWifiStatsParser(); private DumpsysWifiStatsParser mWifiStatsParser = new DumpsysWifiStatsParser();
...@@ -63,6 +66,7 @@ public class DumpsysParser extends AbstractSectionParser { ...@@ -63,6 +66,7 @@ public class DumpsysParser extends AbstractSectionParser {
*/ */
protected void setup() { protected void setup() {
addSectionParser(mBatteryStatsParser, BATTERY_STATS_SECTION_REGEX); addSectionParser(mBatteryStatsParser, BATTERY_STATS_SECTION_REGEX);
addSectionParser(mPackageStatsParser, PACKAGE_SECTION_REGEX);
addSectionParser(mProcStatsParser, PROC_STATS_SECTION_REGEX); addSectionParser(mProcStatsParser, PROC_STATS_SECTION_REGEX);
addSectionParser(mWifiStatsParser, WIFI_SECTION_REGEX); addSectionParser(mWifiStatsParser, WIFI_SECTION_REGEX);
addSectionParser(new NoopParser(), NOOP_SECTION_REGEX); addSectionParser(new NoopParser(), NOOP_SECTION_REGEX);
...@@ -80,6 +84,7 @@ public class DumpsysParser extends AbstractSectionParser { ...@@ -80,6 +84,7 @@ public class DumpsysParser extends AbstractSectionParser {
} }
if (mDumpsys != null) { if (mDumpsys != null) {
mDumpsys.setBatteryInfo((DumpsysBatteryStatsItem) getSection(mBatteryStatsParser)); mDumpsys.setBatteryInfo((DumpsysBatteryStatsItem) getSection(mBatteryStatsParser));
mDumpsys.setPackageStats((DumpsysPackageStatsItem) getSection(mPackageStatsParser));
mDumpsys.setProcStats((DumpsysProcStatsItem) getSection(mProcStatsParser)); mDumpsys.setProcStats((DumpsysProcStatsItem) getSection(mProcStatsParser));
mDumpsys.setWifiStats((DumpsysWifiStatsItem) getSection(mWifiStatsParser)); mDumpsys.setWifiStats((DumpsysWifiStatsItem) getSection(mWifiStatsParser));
} }
......
...@@ -38,7 +38,8 @@ public class BugreportParserTest extends TestCase { ...@@ -38,7 +38,8 @@ public class BugreportParserTest extends TestCase {
* Test that a bugreport can be parsed. * Test that a bugreport can be parsed.
*/ */
public void testParse() throws ParseException { public void testParse() throws ParseException {
List<String> lines = Arrays.asList( List<String> lines =
Arrays.asList(
"========================================================", "========================================================",
"== dumpstate: 2012-04-25 20:45:10", "== dumpstate: 2012-04-25 20:45:10",
"========================================================", "========================================================",
...@@ -139,6 +140,13 @@ public class BugreportParserTest extends TestCase { ...@@ -139,6 +140,13 @@ public class BugreportParserTest extends TestCase {
" Wakeup reason 2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio: 1m 5s 4ms (2 times) realtime", " Wakeup reason 2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio: 1m 5s 4ms (2 times) realtime",
" Wakeup reason 2:qcom,smd-rpm:2:fc4c.qcom,spmi: 7m 1s 914ms (7 times) realtime", " Wakeup reason 2:qcom,smd-rpm:2:fc4c.qcom,spmi: 7m 1s 914ms (7 times) realtime",
"", "",
"DUMP OF SERVICE package:",
"Package [com.google.android.calculator] (e075c9d):",
" userId=10071",
" secondaryCpuAbi=null",
" versionCode=73000302 minSdk=10000 targetSdk=10000",
" versionName=7.3 (3821978)",
" splits=[base]",
"========================================================", "========================================================",
"== Running Application Services", "== Running Application Services",
"========================================================", "========================================================",
...@@ -184,6 +192,7 @@ public class BugreportParserTest extends TestCase { ...@@ -184,6 +192,7 @@ public class BugreportParserTest extends TestCase {
assertNotNull(bugreport.getDumpsys()); assertNotNull(bugreport.getDumpsys());
assertNotNull(bugreport.getDumpsys().getBatteryStats()); assertNotNull(bugreport.getDumpsys().getBatteryStats());
assertNotNull(bugreport.getDumpsys().getPackageStats());
assertNotNull(bugreport.getActivityService()); assertNotNull(bugreport.getActivityService());
assertNotNull(bugreport.getActivityService().getLocationDumps().getLocationClients()); assertNotNull(bugreport.getActivityService().getLocationDumps().getLocationClients());
...@@ -546,7 +555,8 @@ public class BugreportParserTest extends TestCase { ...@@ -546,7 +555,8 @@ public class BugreportParserTest extends TestCase {
* Test that section headers are correctly parsed. * Test that section headers are correctly parsed.
*/ */
public void testSectionHeader() { public void testSectionHeader() {
List<String> lines = Arrays.asList( List<String> lines =
Arrays.asList(
"========================================================", "========================================================",
"== dumpstate: 2012-04-25 20:45:10", "== dumpstate: 2012-04-25 20:45:10",
"========================================================", "========================================================",
...@@ -576,6 +586,13 @@ public class BugreportParserTest extends TestCase { ...@@ -576,6 +586,13 @@ public class BugreportParserTest extends TestCase {
" All wakeup reasons:", " All wakeup reasons:",
" Wakeup reason 2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio: 1m 5s 4ms (2 times) realtime", " Wakeup reason 2:bcmsdh_sdmmc:2:qcom,smd:2:msmgio: 1m 5s 4ms (2 times) realtime",
" Wakeup reason 2:qcom,smd-rpm:2:fc4c.qcom,spmi: 7m 1s 914ms (7 times) realtime", " Wakeup reason 2:qcom,smd-rpm:2:fc4c.qcom,spmi: 7m 1s 914ms (7 times) realtime",
"DUMP OF SERVICE package:",
"Package [com.google.android.calculator] (e075c9d):",
" use rId=10071",
" secondaryCpuAbi=null",
" versionCode=73000302 minSdk=10000 targetSdk=10000",
" versionName=7.3 (3821978)",
" splits=[base]",
"DUMP OF SERVICE procstats:", "DUMP OF SERVICE procstats:",
"COMMITTED STATS FROM 2015-09-30-07-44-54:", "COMMITTED STATS FROM 2015-09-30-07-44-54:",
" * system / 1000 / v23:", " * system / 1000 / v23:",
...@@ -588,6 +605,7 @@ public class BugreportParserTest extends TestCase { ...@@ -588,6 +605,7 @@ public class BugreportParserTest extends TestCase {
BugreportItem bugreport = new BugreportParser().parse(lines); BugreportItem bugreport = new BugreportParser().parse(lines);
assertNotNull(bugreport.getDumpsys()); assertNotNull(bugreport.getDumpsys());
assertNotNull(bugreport.getDumpsys().getBatteryStats()); assertNotNull(bugreport.getDumpsys().getBatteryStats());
assertNotNull(bugreport.getDumpsys().getPackageStats());
assertNotNull(bugreport.getDumpsys().getProcStats()); assertNotNull(bugreport.getDumpsys().getProcStats());
} }
...@@ -673,4 +691,3 @@ public class BugreportParserTest extends TestCase { ...@@ -673,4 +691,3 @@ public class BugreportParserTest extends TestCase {
return formatter.parse(timeStr); return formatter.parse(timeStr);
} }
} }
/*
* Copyright (C) 2017 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.DumpsysPackageStatsItem;
import com.android.loganalysis.item.AppVersionItem;
import junit.framework.TestCase;
import java.util.Arrays;
import java.util.List;
/** Unit tests for {@link DumpsysPackageStatsParser} */
public class DumpsysPackageStatsParserTest extends TestCase {
/** Test that normal input is parsed. */
public void testDumpsysPackageStatsParser() {
List<String> inputBlock =
Arrays.asList(
"DUMP OF SERVICE package:",
"Package [com.google.android.calculator] (e075c9d):",
" userId=10071",
" secondaryCpuAbi=null",
" versionCode=73000302 minSdk=10000 targetSdk=10000",
" versionName=7.3 (3821978)",
" splits=[base]",
" Package [com.google.android.googlequicksearchbox] (607929e):",
" userId=10037",
" pkg=Package{af43294 com.google.android.googlequicksearchbox}",
" versionCode=300734793 minSdk=10000 targetSdk=10000",
" versionName=6.16.35.26.arm64",
" apkSigningVersion=2");
final DumpsysPackageStatsItem packagestats =
new DumpsysPackageStatsParser().parse(inputBlock);
assertEquals(2, packagestats.size());
assertNotNull(packagestats.get("com.google.android.calculator"));
final AppVersionItem calculator = packagestats.get("com.google.android.calculator");
assertEquals(73000302, calculator.getVersionCode());
assertEquals("7.3 (3821978)", calculator.getVersionName());
assertNotNull(packagestats.get("com.google.android.googlequicksearchbox"));
final AppVersionItem googlequicksearchbox =
packagestats.get("com.google.android.googlequicksearchbox");
assertEquals(300734793, googlequicksearchbox.getVersionCode());
assertEquals("6.16.35.26.arm64", googlequicksearchbox.getVersionName());
}
}
...@@ -31,7 +31,8 @@ public class DumpsysParserTest extends TestCase { ...@@ -31,7 +31,8 @@ public class DumpsysParserTest extends TestCase {
* Test that normal input is parsed. * Test that normal input is parsed.
*/ */
public void testDumpsysParser() { public void testDumpsysParser() {
List<String> inputBlock = Arrays.asList( List<String> inputBlock =
Arrays.asList(
"DUMP OF SERVICE batterystats:", "DUMP OF SERVICE batterystats:",
"Battery History (37% used, 95KB used of 256KB, 166 strings using 15KB):", "Battery History (37% used, 95KB used of 256KB, 166 strings using 15KB):",
" 0 (9) RESET:TIME: 2014-12-09-11-33-29", " 0 (9) RESET:TIME: 2014-12-09-11-33-29",
...@@ -85,6 +86,19 @@ public class DumpsysParserTest extends TestCase { ...@@ -85,6 +86,19 @@ public class DumpsysParserTest extends TestCase {
" Sensor 2: 12m 13s 15ms realtime (5 times)", " Sensor 2: 12m 13s 15ms realtime (5 times)",
" Sensor 32: (not used)", " Sensor 32: (not used)",
" Sensor 35: (not used)", " Sensor 35: (not used)",
"DUMP OF SERVICE package:",
"Package [com.google.android.calculator] (e075c9d):",
" userId=10071",
" secondaryCpuAbi=null",
" versionCode=73000302 minSdk=10000 targetSdk=10000",
" versionName=7.3 (3821978)",
" splits=[base]",
"Package [com.google.android.googlequicksearchbox] (607929e):",
" userId=10037",
" pkg=Package{af43294 com.google.android.googlequicksearchbox}",
" versionCode=300734793 minSdk=10000 targetSdk=10000",
" versionName=6.16.35.26.arm64",
" apkSigningVersion=2",
"DUMP OF SERVICE procstats:", "DUMP OF SERVICE procstats:",
"COMMITTED STATS FROM 2015-03-20-02-01-02 (checked in):", "COMMITTED STATS FROM 2015-03-20-02-01-02 (checked in):",
" * com.android.systemui / u0a22 / v22:", " * com.android.systemui / u0a22 / v22:",
...@@ -122,8 +136,8 @@ public class DumpsysParserTest extends TestCase { ...@@ -122,8 +136,8 @@ public class DumpsysParserTest extends TestCase {
DumpsysItem dumpsys = new DumpsysParser().parse(inputBlock); DumpsysItem dumpsys = new DumpsysParser().parse(inputBlock);
assertNotNull(dumpsys.getBatteryStats()); assertNotNull(dumpsys.getBatteryStats());
assertNotNull(dumpsys.getPackageStats());
assertNotNull(dumpsys.getProcStats()); assertNotNull(dumpsys.getProcStats());
assertNotNull(dumpsys.getWifiStats()); assertNotNull(dumpsys.getWifiStats());
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment