summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Campbell <ryanjcampbell@google.com>2017-06-19 11:17:10 -0700
committerRyan Campbell <ryanjcampbell@google.com>2017-06-19 12:26:07 -0700
commit67c9a5397bd972a173cdf08aaccba44678f3aea0 (patch)
treee02d3fa1d9c91d8cfaaef276c2b3ffb4c064a4b5
parent7054de7189ba17d6516861e437b8f50fc837191d (diff)
downloaddashboard-67c9a5397bd972a173cdf08aaccba44678f3aea0.tar.gz
Move dashboard to test/vti.
Copy code from test/vts/web to test/vti/. Bug: 62339915 Test: none Change-Id: I6e07fbaca77018f6d7bd24bd3da9e3bbbafab495
-rw-r--r--.gitignore45
-rw-r--r--README.md151
-rw-r--r--pom.xml187
-rw-r--r--src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java130
-rw-r--r--src/main/java/com/android/vts/api/DatastoreRestServlet.java93
-rw-r--r--src/main/java/com/android/vts/api/TestRunRestServlet.java89
-rw-r--r--src/main/java/com/android/vts/api/UserFavoriteRestServlet.java138
-rw-r--r--src/main/java/com/android/vts/entity/CoverageEntity.java156
-rw-r--r--src/main/java/com/android/vts/entity/DashboardEntity.java29
-rw-r--r--src/main/java/com/android/vts/entity/DeviceInfoEntity.java171
-rw-r--r--src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java204
-rw-r--r--src/main/java/com/android/vts/entity/TestCaseRunEntity.java176
-rw-r--r--src/main/java/com/android/vts/entity/TestEntity.java163
-rw-r--r--src/main/java/com/android/vts/entity/TestPlanEntity.java65
-rw-r--r--src/main/java/com/android/vts/entity/TestPlanRunEntity.java141
-rw-r--r--src/main/java/com/android/vts/entity/TestRunEntity.java287
-rw-r--r--src/main/java/com/android/vts/entity/UserFavoriteEntity.java79
-rw-r--r--src/main/java/com/android/vts/proto/VtsReportMessage.java18604
-rw-r--r--src/main/java/com/android/vts/servlet/BaseServlet.java159
-rw-r--r--src/main/java/com/android/vts/servlet/DashboardMainServlet.java208
-rw-r--r--src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java118
-rw-r--r--src/main/java/com/android/vts/servlet/ShowCoverageServlet.java141
-rw-r--r--src/main/java/com/android/vts/servlet/ShowGraphServlet.java229
-rw-r--r--src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java268
-rw-r--r--src/main/java/com/android/vts/servlet/ShowPlanReleaseServlet.java239
-rw-r--r--src/main/java/com/android/vts/servlet/ShowPlanRunServlet.java154
-rw-r--r--src/main/java/com/android/vts/servlet/ShowReleaseServlet.java91
-rw-r--r--src/main/java/com/android/vts/servlet/ShowTableServlet.java244
-rw-r--r--src/main/java/com/android/vts/servlet/ShowTreeServlet.java290
-rw-r--r--src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java447
-rw-r--r--src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java258
-rw-r--r--src/main/java/com/android/vts/util/DatastoreHelper.java457
-rw-r--r--src/main/java/com/android/vts/util/EmailHelper.java152
-rw-r--r--src/main/java/com/android/vts/util/FilterUtil.java321
-rw-r--r--src/main/java/com/android/vts/util/Graph.java90
-rw-r--r--src/main/java/com/android/vts/util/GraphSerializer.java30
-rw-r--r--src/main/java/com/android/vts/util/Histogram.java165
-rw-r--r--src/main/java/com/android/vts/util/LineGraph.java149
-rw-r--r--src/main/java/com/android/vts/util/PerformanceSummary.java143
-rw-r--r--src/main/java/com/android/vts/util/PerformanceUtil.java246
-rw-r--r--src/main/java/com/android/vts/util/ProfilingPointSummary.java146
-rw-r--r--src/main/java/com/android/vts/util/StatSummary.java143
-rw-r--r--src/main/java/com/android/vts/util/TestResults.java387
-rw-r--r--src/main/java/com/android/vts/util/TestRunDetails.java100
-rw-r--r--src/main/java/com/android/vts/util/TestRunMetadata.java129
-rw-r--r--src/main/java/com/android/vts/util/UrlUtil.java74
-rw-r--r--src/main/webapp/WEB-INF/appengine-web.xml31
-rw-r--r--src/main/webapp/WEB-INF/cron.xml29
-rw-r--r--src/main/webapp/WEB-INF/datastore-indexes.xml77
-rw-r--r--src/main/webapp/WEB-INF/jsp/dashboard_main.jsp177
-rw-r--r--src/main/webapp/WEB-INF/jsp/footer.jsp25
-rw-r--r--src/main/webapp/WEB-INF/jsp/header.jsp70
-rw-r--r--src/main/webapp/WEB-INF/jsp/show_coverage.jsp171
-rw-r--r--src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp168
-rw-r--r--src/main/webapp/WEB-INF/jsp/show_graph.jsp292
-rw-r--r--src/main/webapp/WEB-INF/jsp/show_performance_digest.jsp100
-rw-r--r--src/main/webapp/WEB-INF/jsp/show_plan_release.jsp109
-rw-r--r--src/main/webapp/WEB-INF/jsp/show_plan_run.jsp131
-rw-r--r--src/main/webapp/WEB-INF/jsp/show_release.jsp45
-rw-r--r--src/main/webapp/WEB-INF/jsp/show_table.jsp340
-rw-r--r--src/main/webapp/WEB-INF/jsp/show_tree.jsp225
-rw-r--r--src/main/webapp/WEB-INF/web.xml197
-rw-r--r--src/main/webapp/css/common.css25
-rw-r--r--src/main/webapp/css/dashboard_main.css109
-rw-r--r--src/main/webapp/css/datepicker.css70
-rw-r--r--src/main/webapp/css/navbar.css69
-rw-r--r--src/main/webapp/css/plan_runs.css30
-rw-r--r--src/main/webapp/css/search_header.css80
-rw-r--r--src/main/webapp/css/show_coverage.css104
-rw-r--r--src/main/webapp/css/show_graph.css70
-rw-r--r--src/main/webapp/css/show_performance_digest.css82
-rw-r--r--src/main/webapp/css/show_plan_release.css23
-rw-r--r--src/main/webapp/css/show_release.css40
-rw-r--r--src/main/webapp/css/show_table.css156
-rw-r--r--src/main/webapp/css/show_test_runs_common.css136
-rw-r--r--src/main/webapp/css/test_results.css78
-rw-r--r--src/main/webapp/js/plan_runs.js64
-rw-r--r--src/main/webapp/js/search_header.js242
-rw-r--r--src/main/webapp/js/test_results.js272
-rw-r--r--src/main/webapp/js/time.js53
-rw-r--r--src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java237
-rw-r--r--src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java136
-rw-r--r--src/test/java/com/android/vts/util/StatSummaryTest.java98
-rwxr-xr-xsrc/test/res/driver/chromedriverbin0 -> 5503600 bytes
-rw-r--r--src/test/res/driver/config.properties1
-rw-r--r--src/test/res/servlet/performanceSummary1.html1
-rw-r--r--src/test/res/servlet/performanceSummary2.html1
-rw-r--r--src/test/res/servlet/performanceSummary3.html1
-rw-r--r--src/test/res/servlet/performanceSummary4.html1
89 files changed, 30852 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9a94e36
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,45 @@
+# Google App Engine generated folder
+appengine-generated/
+
+# Java
+*.class
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# maven
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+
+service-account.json
+
+# intellij
+.idea/
+*.iml
+
+# Eclipse files
+.project
+.classpath
+.settings
+
+# vim
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+Session.vim
+.netrwhist
+*~
+tags \ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9b6ca36
--- /dev/null
+++ b/README.md
@@ -0,0 +1,151 @@
+# VTS Dashboard
+
+## Introduction
+
+The VTS Dashboard displays the summarized results of the Multi Device Tests along with graphs.
+
+## Installation
+
+### Steps to run locally:
+
+1. Google App Engine uses Java 8. Install Java 8 before running running locally:
+ 'sudo apt install openjdk-8-jdk'
+
+ To use java 8:
+ Copy the following lines in ~/.bashrc :
+
+```
+ function setup_jdk() {
+ # Remove the current JDK from PATH
+ if [ -n "$JAVA_HOME" ] ; then
+ PATH=${PATH/$JAVA_HOME\/bin:/}
+ fi
+ export JAVA_HOME=$1
+ export PATH=$JAVA_HOME/bin:$PATH
+ }
+
+ function use_java8() {
+ # setup_jdk /usr/java/jre1.8.0_73
+ setup_jdk /usr/lib/jvm/java-8-openjdk-amd64
+ }
+
+ Then from cmd:
+ $ use_java8
+```
+
+2. Maven is used for build. Install Maven 3.3.9:
+ Download maven from:
+ https://maven.apache.org/download.cgi
+
+ Steps to Install Maven:
+ 1) Unzip the Binary tar:
+ tar -zxf apache-maven-3.3.3-bin.tar.gz
+
+ 2) Move the application directory to /usr/local
+ sudo cp -R apache-maven-3.3.3 /usr/local
+
+ 3) Make a soft link in /usr/bin for universal access of mvn
+ sudo ln -s /usr/local/apache-maven-3.3.3/bin/mvn /usr/bin/mvn
+
+ 4) Verify maven installation:
+ $ mvn -v
+
+ The output should resemble this:
+
+ Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T08:41:47-08:00)
+ Maven home: /opt/apache-maven-3.3.9
+ Java version: 1.8.0_45-internal, vendor: Oracle Corporation
+ Java home: /usr/lib/jvm/java-8-openjdk-amd64/jre
+ Default locale: en_US, platform encoding: UTF-8
+ OS name: "linux", version: "3.13.0-88-generic", arch: "amd64", family: "unix"
+
+3. Install Google Cloud SDK. Follow the instructions listed on official source:
+ https://cloud.google.com/sdk/docs/quickstart-linux
+
+ The default location where the application searches for a google-cloud-sdk is:
+ /usr/local/share/google/google-cloud-sdk
+
+ Therefore move the extracted folder to this location: /usr/local/share/google/
+
+ Otherwise, to have a custom location, specify the location of
+ google-cloud-sdk in test/vti/dashboard/pom.xml by putting the configuration:
+
+```
+ <configuration>
+ <gcloud_directory>PATH/TO/GCLOUD_DIRECTORY</gcloud_directory>
+ </configuration>
+```
+ within the 'com.google.appengine' plugin tag :
+
+## To run GAE on local machine:
+
+$ cd test/vti/dashboard
+$ mvn appengine:devserver
+
+## To deploy to Google App Engine
+
+$ cd test/vti/dashboard
+$ mvn appengine:update
+
+visit https://<YOUR-PROJECT-NAME>.appspot.com
+
+## Monitoring
+
+The following steps list how to create a monitoring service for the VTS Dashboard.
+
+### Create a Stackdriver account
+
+1. Go to Google Cloud Platform Console:
+ http://console.developers.google.com
+
+2. In the Google Cloud Platform Console, select Stackdriver > Monitoring.
+ If your project is not in a Stackdriver account you'll see a message to
+ create a new project.
+
+3. Click Create new Stackdriver account and then Continue.
+
+4. With your project shown, click Create account.
+
+5. In the page, "Add Google Cloud Platform projects to monitor", click Continue to skip ahead.
+
+6. In the page, "Monitor AWS accounts", click Done to skip ahead.
+
+7. In a few seconds you see the following message:
+ "Finished Initial collection"
+ Click Launch Monitoring.
+
+8. In the page, "Get reports by email", click No reports and Continue.
+
+9. You will see your Stackdriver account dashboard.
+ Close the "Welcome to Stackdriver" banner if you don't need it.
+
+### Steps to create an uptime check and an alerting policy
+
+1. Go to Stack Monitoring console:
+ https://app.google.stackdriver.com/
+
+2. Go to Alerting > Uptime Checks in the top menu and then click Add Uptime Check.
+ You see the New Uptime Check panel.
+
+3. Fill in the following fields for the uptime check:
+
+ Check type: HTTP
+ Resource Type: Instance
+ Applies To: Single, lamp-1-vm
+ Leave the other fields with their default values.
+
+4. Click Test to verify your uptime check is working.
+
+5. Click Save. After you click on save you'll see a panel to
+ 'Create Alerting Policy'
+
+6. Fill out the configuration for notifications and click save policy.
+
+### Test the check and alert
+
+This procedure can take up to fifteen minutes.
+
+To test the check and alert, go to the VM Instances page, select your instance, and click Stop from the top menu.
+You'll have to wait up to five minutes for the next uptime check to fail. The alert and notification don't happen until the next failure occurs.
+
+To correct the "problem," return to the VM Instances page, select your instance, and click Start from the top menu.
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..d5bc0ff
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,187 @@
+<!--
+ Copyright 2016 Google Inc.
+
+ 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>war</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <groupId>com.android.vts</groupId>
+ <artifactId>vts-dashboard</artifactId>
+
+ <properties>
+ <appengine.clientID></appengine.clientID>
+ <appengine.serviceClientID></appengine.serviceClientID>
+ <appengine.senderEmail></appengine.senderEmail>
+ <appengine.emailDomain></appengine.emailDomain>
+ <appengine.defaultEmail></appengine.defaultEmail>
+ <gerrit.uri></gerrit.uri>
+ <gerrit.scope></gerrit.scope>
+ <analytics.id></analytics.id>
+
+ <maven.compiler.target>1.7</maven.compiler.target>
+ <maven.compiler.source>1.7</maven.compiler.source>
+ <maven.war.filteringDeploymentDescriptors>true</maven.war.filteringDeploymentDescriptors>
+
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ </properties>
+
+
+ <dependencies>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jsp-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-math3</artifactId>
+ <version>3.6.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.9</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.cloud</groupId>
+ <artifactId>google-cloud</artifactId>
+ <version>0.8.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.7</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>2.8.6</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.api-client</groupId>
+ <artifactId>google-api-client</artifactId>
+ <version>1.22.0</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava-jdk5</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.appengine</groupId>
+ <artifactId>appengine-api-1.0-sdk</artifactId>
+ <version>1.9.50</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.apis</groupId>
+ <artifactId>google-api-services-oauth2</artifactId>
+ <version>v1-rev131-1.22.0</version>
+ </dependency>
+
+ <!-- Test Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.appengine</groupId>
+ <artifactId>appengine-testing</artifactId>
+ <version>1.9.50</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.appengine</groupId>
+ <artifactId>appengine-api-stubs</artifactId>
+ <version>1.9.50</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.appengine</groupId>
+ <artifactId>appengine-tools-sdk</artifactId>
+ <version>1.9.50</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+
+ <build>
+ <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
+
+ <plugins>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>2.6</version>
+ <configuration>
+ <archiveClasses>true</archiveClasses>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ <webResources>
+ <resource>
+ <directory>${basedir}/src/main/webapp/WEB-INF</directory>
+ <filtering>true</filtering>
+ <targetPath>WEB-INF</targetPath>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <version>3.3</version>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.7</source>
+ <target>1.7</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>com.google.appengine</groupId>
+ <artifactId>appengine-maven-plugin</artifactId>
+ <version>1.9.51</version>
+ </plugin>
+
+ </plugins>
+ </build>
+</project>
diff --git a/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java b/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java
new file mode 100644
index 0000000..d2b4a61
--- /dev/null
+++ b/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.api;
+
+import com.android.vts.proto.VtsReportMessage.TestReportMessage;
+import com.android.vts.util.DatastoreHelper;
+import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
+import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.api.client.json.jackson.JacksonFactory;
+import com.google.api.services.oauth2.Oauth2;
+import com.google.api.services.oauth2.model.Tokeninfo;
+import com.google.protobuf.InvalidProtocolBufferException;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.codec.binary.Base64;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/** REST endpoint for posting data JSON to the Dashboard. */
+@Deprecated
+public class BigtableLegacyJsonServlet extends HttpServlet {
+ private static final String SERVICE_CLIENT_ID = System.getProperty("SERVICE_CLIENT_ID");
+ private static final String SERVICE_NAME = "VTS Dashboard";
+ private static final Logger logger =
+ Logger.getLogger(BigtableLegacyJsonServlet.class.getName());
+
+ @Override
+ public void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ // Retrieve the params
+ String payload = new String();
+ JSONObject payloadJson;
+ try {
+ String line = null;
+ BufferedReader reader = request.getReader();
+ while ((line = reader.readLine()) != null) {
+ payload += line;
+ }
+ payloadJson = new JSONObject(payload);
+ } catch (IOException | JSONException e) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ logger.log(Level.WARNING, "Invalid JSON: " + payload);
+ return;
+ }
+
+ // Verify service account access token.
+ boolean authorized = false;
+ if (payloadJson.has("accessToken")) {
+ String accessToken = payloadJson.getString("accessToken").trim();
+ GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
+ Oauth2 oauth2 =
+ new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential)
+ .setApplicationName(SERVICE_NAME)
+ .build();
+ Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute();
+ if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) {
+ authorized = true;
+ }
+ }
+
+ if (!authorized) {
+ response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ }
+
+ // Parse the desired action and execute the command
+ try {
+ if (payloadJson.has("verb")) {
+ switch (payloadJson.getString("verb")) {
+ case "createTable":
+ logger.log(Level.INFO, "Deprecated verb: createTable.");
+ break;
+ case "insertRow":
+ insertData(payloadJson);
+ break;
+ default:
+ logger.log(Level.WARNING,
+ "Invalid Datastore REST verb: " + payloadJson.getString("verb"));
+ throw new IOException("Unsupported POST verb.");
+ }
+ }
+ } catch (IOException e) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+
+ /**
+ * Inserts a data into the Cloud Datastore
+ *
+ * @param payloadJson The JSON object representing the row to be inserted. Of the form: {
+ * (deprecated) 'tableName' : 'table', (deprecated) 'rowKey' : 'row', (deprecated) 'family'
+ * :
+ * 'family', (deprecated) 'qualifier' : 'qualifier', 'value' : 'value' }
+ * @throws IOException
+ */
+ private void insertData(JSONObject payloadJson) throws IOException {
+ if (!payloadJson.has("value")) {
+ logger.log(Level.WARNING, "Missing attributes for datastore api insertRow().");
+ return;
+ }
+ try {
+ byte[] value = Base64.decodeBase64(payloadJson.getString("value"));
+ TestReportMessage testReportMessage = TestReportMessage.parseFrom(value);
+ DatastoreHelper.insertTestReport(testReportMessage);
+ } catch (InvalidProtocolBufferException e) {
+ logger.log(Level.WARNING, "Invalid report posted to dashboard.");
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/api/DatastoreRestServlet.java b/src/main/java/com/android/vts/api/DatastoreRestServlet.java
new file mode 100644
index 0000000..761c292
--- /dev/null
+++ b/src/main/java/com/android/vts/api/DatastoreRestServlet.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.api;
+
+import com.android.vts.proto.VtsReportMessage.DashboardPostMessage;
+import com.android.vts.proto.VtsReportMessage.TestPlanReportMessage;
+import com.android.vts.proto.VtsReportMessage.TestReportMessage;
+import com.android.vts.util.DatastoreHelper;
+import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
+import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.api.client.json.jackson.JacksonFactory;
+import com.google.api.services.oauth2.Oauth2;
+import com.google.api.services.oauth2.model.Tokeninfo;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.codec.binary.Base64;
+
+/** REST endpoint for posting data to the Dashboard. */
+public class DatastoreRestServlet extends HttpServlet {
+ private static final String SERVICE_CLIENT_ID = System.getProperty("SERVICE_CLIENT_ID");
+ private static final String SERVICE_NAME = "VTS Dashboard";
+ private static final Logger logger = Logger.getLogger(DatastoreRestServlet.class.getName());
+
+ @Override
+ public void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ // Retrieve the params
+ String payload = new String();
+ DashboardPostMessage postMessage;
+ try {
+ String line = null;
+ BufferedReader reader = request.getReader();
+ while ((line = reader.readLine()) != null) {
+ payload += line;
+ }
+ byte[] value = Base64.decodeBase64(payload);
+ postMessage = DashboardPostMessage.parseFrom(value);
+ } catch (IOException e) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ logger.log(Level.WARNING, "Invalid proto: " + payload);
+ return;
+ }
+
+ // Verify service account access token.
+ boolean authorized = false;
+ if (postMessage.hasAccessToken()) {
+ String accessToken = postMessage.getAccessToken();
+ GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
+ Oauth2 oauth2 =
+ new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential)
+ .setApplicationName(SERVICE_NAME)
+ .build();
+ Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute();
+ if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) {
+ authorized = true;
+ }
+ }
+
+ if (!authorized) {
+ response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ }
+
+ for (TestReportMessage testReportMessage : postMessage.getTestReportList()) {
+ DatastoreHelper.insertTestReport(testReportMessage);
+ }
+
+ for (TestPlanReportMessage planReportMessage : postMessage.getTestPlanReportList()) {
+ DatastoreHelper.insertTestPlanReport(planReportMessage);
+ }
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+}
diff --git a/src/main/java/com/android/vts/api/TestRunRestServlet.java b/src/main/java/com/android/vts/api/TestRunRestServlet.java
new file mode 100644
index 0000000..ac84a3b
--- /dev/null
+++ b/src/main/java/com/android/vts/api/TestRunRestServlet.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.api;
+
+import com.android.vts.entity.TestCaseRunEntity;
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.util.TestRunDetails;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.EntityNotFoundException;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Servlet for handling requests to fetch test case results. */
+public class TestRunRestServlet extends HttpServlet {
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ String test = request.getParameter("test");
+ String timeString = request.getParameter("timestamp");
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+
+ long timestamp;
+ try {
+ timestamp = Long.parseLong(timeString);
+ if (timestamp <= 0)
+ throw new NumberFormatException();
+ timestamp = timestamp > 0 ? timestamp : null;
+ } catch (NumberFormatException e) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ Key testKey = KeyFactory.createKey(TestEntity.KIND, test);
+ Key testRunKey = KeyFactory.createKey(testKey, TestRunEntity.KIND, timestamp);
+ TestRunEntity testRunEntity;
+ try {
+ Entity testRun = datastore.get(testRunKey);
+ testRunEntity = TestRunEntity.fromEntity(testRun);
+ if (testRunEntity == null) {
+ throw new EntityNotFoundException(testRunKey);
+ }
+ } catch (EntityNotFoundException e) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+ TestRunDetails details = new TestRunDetails();
+ List<Key> gets = new ArrayList<>();
+ for (long testCaseId : testRunEntity.testCaseIds) {
+ gets.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseId));
+ }
+ Map<Key, Entity> entityMap = datastore.get(gets);
+ for (Key key : entityMap.keySet()) {
+ TestCaseRunEntity testCaseRun = TestCaseRunEntity.fromEntity(entityMap.get(key));
+ if (testCaseRun == null) {
+ continue;
+ }
+ details.addTestCase(testCaseRun);
+ }
+ response.setContentType("application/json");
+ PrintWriter writer = response.getWriter();
+ writer.print(new Gson().toJson(details.toJson()));
+ writer.flush();
+ }
+}
diff --git a/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java b/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java
new file mode 100644
index 0000000..f863051
--- /dev/null
+++ b/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.api;
+
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.UserFavoriteEntity;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.EntityNotFoundException;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Transaction;
+import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.FilterOperator;
+import com.google.appengine.api.datastore.Query.FilterPredicate;
+import com.google.appengine.api.users.User;
+import com.google.appengine.api.users.UserService;
+import com.google.appengine.api.users.UserServiceFactory;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Servlet for handling requests to add or remove subscriptions. */
+public class UserFavoriteRestServlet extends HttpServlet {
+ protected static final Logger logger =
+ Logger.getLogger(UserFavoriteRestServlet.class.getName());
+
+ /**
+ * Add a test to the user's favorites.
+ */
+ @Override
+ public void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ UserService userService = UserServiceFactory.getUserService();
+ User currentUser = userService.getCurrentUser();
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+
+ // Retrieve the added tests from the request.
+ String test = request.getPathInfo();
+ if (test == null) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+ if (test.startsWith("/")) {
+ test = test.substring(1);
+ }
+ Key addedTestKey = KeyFactory.createKey(TestEntity.KIND, test);
+ // Filter the tests that exist from the set of tests to add
+ try {
+ datastore.get(addedTestKey);
+ } catch (EntityNotFoundException e) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ Filter userFilter =
+ new FilterPredicate(UserFavoriteEntity.USER, FilterOperator.EQUAL, currentUser);
+ Filter testFilter = new FilterPredicate(
+ UserFavoriteEntity.TEST_KEY, FilterOperator.EQUAL, addedTestKey);
+ Query q = new Query(UserFavoriteEntity.KIND)
+ .setFilter(CompositeFilterOperator.and(userFilter, testFilter))
+ .setKeysOnly();
+
+ Key favoriteKey = null;
+
+ Transaction txn = datastore.beginTransaction();
+ try {
+ for (Entity e : datastore.prepare(q).asIterable()) {
+ favoriteKey = e.getKey();
+ break;
+ }
+ if (favoriteKey == null) {
+ UserFavoriteEntity favorite = new UserFavoriteEntity(currentUser, addedTestKey);
+ Entity entity = favorite.toEntity();
+ datastore.put(entity);
+ favoriteKey = entity.getKey();
+ }
+ txn.commit();
+ } finally {
+ if (txn.isActive()) {
+ logger.log(Level.WARNING,
+ "Transaction rollback forced for favorite creation: " + test);
+ txn.rollback();
+ }
+ }
+
+ response.setContentType("application/json");
+ PrintWriter writer = response.getWriter();
+ JsonObject json = new JsonObject();
+ json.add("key", new JsonPrimitive(KeyFactory.keyToString(favoriteKey)));
+ writer.print(new Gson().toJson(json));
+ writer.flush();
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+
+ /**
+ * Remove a test from the user's favorites.
+ */
+ @Override
+ public void doDelete(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ String stringKey = request.getPathInfo();
+ if (stringKey == null) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+ if (stringKey.startsWith("/")) {
+ stringKey = stringKey.substring(1);
+ }
+ datastore.delete(KeyFactory.stringToKey(stringKey));
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/CoverageEntity.java b/src/main/java/com/android/vts/entity/CoverageEntity.java
new file mode 100644
index 0000000..a0f8cca
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/CoverageEntity.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.entity;
+
+import com.android.vts.proto.VtsReportMessage.CoverageReportMessage;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Object describing coverage data gathered for a file. */
+public class CoverageEntity implements DashboardEntity {
+ protected static final Logger logger = Logger.getLogger(CoverageEntity.class.getName());
+
+ public static final String KIND = "Coverage";
+
+ // Property keys
+ public static final String GROUP = "group";
+ public static final String COVERED_LINE_COUNT = "coveredCount";
+ public static final String TOTAL_LINE_COUNT = "totalCount";
+ public static final String FILE_PATH = "filePath";
+ public static final String PROJECT_NAME = "projectName";
+ public static final String PROJECT_VERSION = "projectVersion";
+ public static final String LINE_COVERAGE = "lineCoverage";
+
+ private final Key parentKey;
+
+ public final String group;
+ public final long coveredLineCount;
+ public final long totalLineCount;
+ public final String filePath;
+ public final String projectName;
+ public final String projectVersion;
+ public final List<Long> lineCoverage;
+
+ /**
+ * Create a CoverageEntity object for a file.
+ *
+ * @param parentKey The key to the parent TestRunEntity object in the database.
+ * @param group The group within the test run describing the coverage.
+ * @param coveredLineCount The total number of covered lines in the file.
+ * @param totalLineCount The total number of uncovered executable lines in the file.
+ * @param filePath The path to the file.
+ * @param projectName The name of the git project.
+ * @param projectVersion The commit hash of the project at the time the test was executed.
+ * @param lineCoverage List of coverage counts per executable line in the file.
+ */
+ public CoverageEntity(Key parentKey, String group, long coveredLineCount, long totalLineCount,
+ String filePath, String projectName, String projectVersion, List<Long> lineCoverage) {
+ this.parentKey = parentKey;
+ this.group = group;
+ this.coveredLineCount = coveredLineCount;
+ this.totalLineCount = totalLineCount;
+ this.filePath = filePath;
+ this.projectName = projectName;
+ this.projectVersion = projectVersion;
+ this.lineCoverage = lineCoverage;
+ }
+
+ @Override
+ public Entity toEntity() {
+ Entity coverageEntity = new Entity(KIND, parentKey);
+ coverageEntity.setProperty(GROUP, group);
+ coverageEntity.setUnindexedProperty(COVERED_LINE_COUNT, coveredLineCount);
+ coverageEntity.setUnindexedProperty(TOTAL_LINE_COUNT, totalLineCount);
+ coverageEntity.setProperty(FILE_PATH, filePath);
+ coverageEntity.setUnindexedProperty(PROJECT_NAME, projectName);
+ coverageEntity.setUnindexedProperty(PROJECT_VERSION, projectVersion);
+ if (lineCoverage != null && lineCoverage.size() > 0) {
+ coverageEntity.setUnindexedProperty(LINE_COVERAGE, lineCoverage);
+ }
+ return coverageEntity;
+ }
+
+ /**
+ * Convert an Entity object to a CoverageEntity.
+ *
+ * @param e The entity to process.
+ * @return CoverageEntity object with the properties from e, or null if incompatible.
+ */
+ @SuppressWarnings("unchecked")
+ public static CoverageEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND) || !e.hasProperty(GROUP) || !e.hasProperty(COVERED_LINE_COUNT)
+ || !e.hasProperty(TOTAL_LINE_COUNT) || !e.hasProperty(FILE_PATH)
+ || !e.hasProperty(PROJECT_NAME) || !e.hasProperty(PROJECT_VERSION)) {
+ logger.log(Level.WARNING, "Missing coverage attributes in entity: " + e.toString());
+ return null;
+ }
+ try {
+ String group = (String) e.getProperty(GROUP);
+ long coveredLineCount = (long) e.getProperty(COVERED_LINE_COUNT);
+ long totalLineCount = (long) e.getProperty(TOTAL_LINE_COUNT);
+ String filePath = (String) e.getProperty(FILE_PATH);
+ String projectName = (String) e.getProperty(PROJECT_NAME);
+ String projectVersion = (String) e.getProperty(PROJECT_VERSION);
+ List<Long> lineCoverage;
+ if (e.hasProperty(LINE_COVERAGE)) {
+ lineCoverage = (List<Long>) e.getProperty(LINE_COVERAGE);
+ } else {
+ lineCoverage = new ArrayList<>();
+ }
+ return new CoverageEntity(e.getKey().getParent(), group, coveredLineCount,
+ totalLineCount, filePath, projectName, projectVersion, lineCoverage);
+ } catch (ClassCastException exception) {
+ // Invalid contents or null values
+ logger.log(Level.WARNING, "Error parsing coverage entity.", exception);
+ }
+ return null;
+ }
+
+ /**
+ * Convert a coverage report to a CoverageEntity.
+ *
+ * @param parentKey The ancestor key for the coverage entity.
+ * @param group The group to display the coverage report with.
+ * @param coverage The coverage report containing coverage data.
+ * @return The CoverageEntity for the coverage report message, or null if not compatible.
+ */
+ public static CoverageEntity fromCoverageReport(
+ Key parentKey, String group, CoverageReportMessage coverage) {
+ if (!coverage.hasFilePath() || !coverage.hasProjectName() || !coverage.hasRevision()
+ || !coverage.hasTotalLineCount() || !coverage.hasCoveredLineCount()) {
+ return null; // invalid coverage report;
+ }
+ long coveredLineCount = coverage.getCoveredLineCount();
+ long totalLineCount = coverage.getTotalLineCount();
+ String filePath = coverage.getFilePath().toStringUtf8();
+ String projectName = coverage.getProjectName().toStringUtf8();
+ String projectVersion = coverage.getRevision().toStringUtf8();
+ List<Long> lineCoverage = null;
+ if (coverage.getLineCoverageVectorCount() > 0) {
+ lineCoverage = new ArrayList<>();
+ for (int count : coverage.getLineCoverageVectorList()) {
+ lineCoverage.add((long) count);
+ }
+ }
+ return new CoverageEntity(parentKey, group, coveredLineCount, totalLineCount, filePath,
+ projectName, projectVersion, lineCoverage);
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/DashboardEntity.java b/src/main/java/com/android/vts/entity/DashboardEntity.java
new file mode 100644
index 0000000..402a1e5
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/DashboardEntity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.entity;
+
+import com.google.appengine.api.datastore.Entity;
+
+/** Interface for interacting with VTS Dashboard entities in Cloud Datastore. */
+public interface DashboardEntity {
+ /**
+ * Serialize the DashboardEntity to an Entity object.
+ *
+ * @return Entity object representing the properties defined in the DashboardEntity.
+ */
+ public Entity toEntity();
+}
diff --git a/src/main/java/com/android/vts/entity/DeviceInfoEntity.java b/src/main/java/com/android/vts/entity/DeviceInfoEntity.java
new file mode 100644
index 0000000..ad4e83b
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/DeviceInfoEntity.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.entity;
+
+import com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Class describing a device used for a test run. */
+public class DeviceInfoEntity implements DashboardEntity {
+ protected static final Logger logger = Logger.getLogger(DeviceInfoEntity.class.getName());
+
+ public static final String KIND = "DeviceInfo";
+
+ // Property keys
+ public static final String BRANCH = "branch";
+ public static final String PRODUCT = "product";
+ public static final String BUILD_FLAVOR = "buildFlavor";
+ public static final String BUILD_ID = "buildId";
+ public static final String ABI_BITNESS = "abiBitness";
+ public static final String ABI_NAME = "abiName";
+
+ private final Key parentKey;
+
+ public final String branch;
+ public final String product;
+ public final String buildFlavor;
+ public final String buildId;
+ public final String abiBitness;
+ public final String abiName;
+
+ /**
+ * Create a DeviceInfoEntity object.
+ *
+ * @param parentKey The key for the parent entity in the database.
+ * @param branch The build branch.
+ * @param product The device product.
+ * @param buildFlavor The device build flavor.
+ * @param buildID The device build ID.
+ * @param abiBitness The abi bitness of the device.
+ * @param abiName The name of the abi.
+ */
+ public DeviceInfoEntity(Key parentKey, String branch, String product, String buildFlavor,
+ String buildID, String abiBitness, String abiName) {
+ this.parentKey = parentKey;
+ this.branch = branch;
+ this.product = product;
+ this.buildFlavor = buildFlavor;
+ this.buildId = buildID;
+ this.abiBitness = abiBitness;
+ this.abiName = abiName;
+ }
+
+ @Override
+ public Entity toEntity() {
+ Entity deviceEntity = new Entity(KIND, this.parentKey);
+ deviceEntity.setProperty(BRANCH, this.branch.toLowerCase());
+ deviceEntity.setProperty(PRODUCT, this.product.toLowerCase());
+ deviceEntity.setProperty(BUILD_FLAVOR, this.buildFlavor.toLowerCase());
+ deviceEntity.setProperty(BUILD_ID, this.buildId.toLowerCase());
+ if (this.abiBitness != null && this.abiName != null) {
+ deviceEntity.setUnindexedProperty(ABI_BITNESS, this.abiBitness.toLowerCase());
+ deviceEntity.setUnindexedProperty(ABI_NAME, this.abiName.toLowerCase());
+ }
+
+ return deviceEntity;
+ }
+
+ /**
+ * Convert an Entity object to a DeviceInfoEntity.
+ *
+ * @param e The entity to process.
+ * @return DeviceInfoEntity object with the properties from e, or null if incompatible.
+ */
+ public static DeviceInfoEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND) || !e.hasProperty(BRANCH) || !e.hasProperty(PRODUCT)
+ || !e.hasProperty(BUILD_FLAVOR) || !e.hasProperty(BUILD_ID)
+ || !e.hasProperty(ABI_BITNESS) || !e.hasProperty(ABI_NAME)) {
+ logger.log(Level.WARNING, "Missing device info attributes in entity: " + e.toString());
+ return null;
+ }
+ try {
+ Key parentKey = e.getKey().getParent();
+ String branch = (String) e.getProperty(BRANCH);
+ String product = (String) e.getProperty(PRODUCT);
+ String buildFlavor = (String) e.getProperty(BUILD_FLAVOR);
+ String buildId = (String) e.getProperty(BUILD_ID);
+ String abiBitness = null;
+ String abiName = null;
+ if (e.hasProperty(ABI_BITNESS) && e.hasProperty(ABI_NAME)) {
+ abiBitness = (String) e.getProperty(ABI_BITNESS);
+ abiName = (String) e.getProperty(ABI_NAME);
+ }
+ return new DeviceInfoEntity(
+ parentKey, branch, product, buildFlavor, buildId, abiBitness, abiName);
+ } catch (ClassCastException exception) {
+ // Invalid cast
+ logger.log(Level.WARNING, "Error parsing device info entity.", exception);
+ }
+ return null;
+ }
+
+ /**
+ * Convert a device info message to a DeviceInfoEntity.
+ *
+ * @param parentKey The ancestor key for the device entity.
+ * @param device The device info report describing the target Android device.
+ * @return The DeviceInfoEntity for the target device, or null if incompatible
+ */
+ public static DeviceInfoEntity fromDeviceInfoMessage(
+ Key parentKey, AndroidDeviceInfoMessage device) {
+ if (!device.hasBuildAlias() || !device.hasBuildFlavor() || !device.hasProductVariant()
+ || !device.hasBuildId()) {
+ return null;
+ }
+ String branch = device.getBuildAlias().toStringUtf8();
+ String buildFlavor = device.getBuildFlavor().toStringUtf8();
+ String product = device.getProductVariant().toStringUtf8();
+ String buildId = device.getBuildId().toStringUtf8();
+ String abiBitness = device.getAbiBitness().toStringUtf8();
+ String abiName = device.getAbiName().toStringUtf8();
+ return new DeviceInfoEntity(
+ parentKey, branch, product, buildFlavor, buildId, abiBitness, abiName);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof DeviceInfoEntity)) {
+ return false;
+ }
+ DeviceInfoEntity device2 = (DeviceInfoEntity) obj;
+ if (!this.branch.equals(device2.branch) || !this.product.equals(device2.product)
+ || !this.buildFlavor.equals(device2.buildFlavor)
+ || !this.buildId.equals(device2.buildId)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ String deviceId = this.branch + this.product + this.buildFlavor + this.buildId;
+ return deviceId.hashCode();
+ }
+
+ /**
+ * Create a copy of the device info under a near parent.
+ * @param parentKey The new parent key.
+ * @return A copy of the DeviceInfoEntity with the specified parent.
+ */
+ public DeviceInfoEntity copyWithParent(Key parentKey) {
+ return new DeviceInfoEntity(parentKey, this.branch, this.product, this.buildFlavor,
+ this.buildId, this.abiBitness, this.abiName);
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java b/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java
new file mode 100644
index 0000000..fdbbb29
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.entity;
+
+import com.android.vts.proto.VtsReportMessage.ProfilingReportMessage;
+import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
+import com.android.vts.proto.VtsReportMessage.VtsProfilingType;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.protobuf.ByteString;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Entity describing a profiling point execution. */
+public class ProfilingPointRunEntity implements DashboardEntity {
+ protected static final Logger logger =
+ Logger.getLogger(ProfilingPointRunEntity.class.getName());
+
+ public static final String KIND = "ProfilingPointRun";
+
+ // Property keys
+ public static final String TYPE = "type";
+ public static final String REGRESSION_MODE = "regressionMode";
+ public static final String LABELS = "labels";
+ public static final String VALUES = "values";
+ public static final String X_LABEL = "xLabel";
+ public static final String Y_LABEL = "yLabel";
+ public static final String OPTIONS = "options";
+
+ private final Key parentKey;
+
+ public final String name;
+ public final VtsProfilingType type;
+ public final VtsProfilingRegressionMode regressionMode;
+ public final List<String> labels;
+ public final List<Long> values;
+ public final String xLabel;
+ public final String yLabel;
+ public final List<String> options;
+
+ /**
+ * Create a ProfilingPointRunEntity object.
+ *
+ * @param parentKey The Key object for the parent TestRunEntity in the database.
+ * @param name The name of the profiling point.
+ * @param type The (number) type of the profiling point data.
+ * @param regressionMode The (number) mode to use for detecting regression.
+ * @param labels List of data labels, or null if the data is unlabeled.
+ * @param values List of data values.
+ * @param xLabel The x axis label.
+ * @param yLabel The y axis label.
+ * @param options The list of key=value options for the profiling point run.
+ */
+ public ProfilingPointRunEntity(Key parentKey, String name, int type, int regressionMode,
+ List<String> labels, List<Long> values, String xLabel, String yLabel,
+ List<String> options) {
+ this.parentKey = parentKey;
+ this.name = name;
+ this.type = VtsProfilingType.valueOf(type);
+ this.regressionMode = VtsProfilingRegressionMode.valueOf(regressionMode);
+ this.labels = labels == null ? null : new ArrayList<>(labels);
+ this.values = new ArrayList<>(values);
+ this.xLabel = xLabel;
+ this.yLabel = yLabel;
+ this.options = options;
+ }
+
+ @Override
+ public Entity toEntity() {
+ Entity profilingRun = new Entity(KIND, this.name, this.parentKey);
+ profilingRun.setUnindexedProperty(TYPE, this.type.getNumber());
+ profilingRun.setUnindexedProperty(REGRESSION_MODE, this.regressionMode.getNumber());
+ if (this.labels != null) {
+ profilingRun.setUnindexedProperty(LABELS, this.labels);
+ }
+ profilingRun.setUnindexedProperty(VALUES, this.values);
+ profilingRun.setUnindexedProperty(X_LABEL, this.xLabel);
+ profilingRun.setUnindexedProperty(Y_LABEL, this.yLabel);
+ if (this.options != null) {
+ profilingRun.setUnindexedProperty(OPTIONS, this.options);
+ }
+
+ return profilingRun;
+ }
+
+ /**
+ * Convert an Entity object to a ProflilingPointRunEntity.
+ *
+ * @param e The entity to process.
+ * @return ProfilingPointRunEntity object with the properties from e, or null if incompatible.
+ */
+ @SuppressWarnings("unchecked")
+ public static ProfilingPointRunEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND) || e.getKey().getName() == null || !e.hasProperty(TYPE)
+ || !e.hasProperty(REGRESSION_MODE) || !e.hasProperty(VALUES)
+ || !e.hasProperty(X_LABEL) || !e.hasProperty(Y_LABEL)) {
+ logger.log(
+ Level.WARNING, "Missing profiling point attributes in entity: " + e.toString());
+ return null;
+ }
+ try {
+ Key parentKey = e.getParent();
+ String name = e.getKey().getName();
+ int type = (int) (long) e.getProperty(TYPE);
+ int regressionMode = (int) (long) e.getProperty(REGRESSION_MODE);
+ List<Long> values = (List<Long>) e.getProperty(VALUES);
+ String xLabel = (String) e.getProperty(X_LABEL);
+ String yLabel = (String) e.getProperty(Y_LABEL);
+ List<String> labels = null;
+ if (e.hasProperty(LABELS)) {
+ labels = (List<String>) e.getProperty(LABELS);
+ }
+ List<String> options = null;
+ if (e.hasProperty(OPTIONS)) {
+ options = (List<String>) e.getProperty(OPTIONS);
+ }
+ return new ProfilingPointRunEntity(
+ parentKey, name, type, regressionMode, labels, values, xLabel, yLabel, options);
+ } catch (ClassCastException exception) {
+ // Invalid cast
+ logger.log(Level.WARNING, "Error parsing profiling point run entity.", exception);
+ }
+ return null;
+ }
+
+ /**
+ * Convert a coverage report to a CoverageEntity.
+ *
+ * @param parentKey The ancestor key for the coverage entity.
+ * @param profilingReport The profiling report containing profiling data.
+ * @return The ProfilingPointRunEntity for the profiling report message, or null if incompatible
+ */
+ public static ProfilingPointRunEntity fromProfilingReport(
+ Key parentKey, ProfilingReportMessage profilingReport) {
+ if (!profilingReport.hasName() || !profilingReport.hasType()
+ || profilingReport.getType() == VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE
+ || !profilingReport.hasRegressionMode() || !profilingReport.hasXAxisLabel()
+ || !profilingReport.hasYAxisLabel()) {
+ return null; // invalid profiling report;
+ }
+ String name = profilingReport.getName().toStringUtf8();
+ VtsProfilingType type = profilingReport.getType();
+ VtsProfilingRegressionMode regressionMode = profilingReport.getRegressionMode();
+ String xLabel = profilingReport.getXAxisLabel().toStringUtf8();
+ String yLabel = profilingReport.getYAxisLabel().toStringUtf8();
+ List<Long> values;
+ List<String> labels = null;
+ switch (type) {
+ case VTS_PROFILING_TYPE_TIMESTAMP:
+ if (!profilingReport.hasStartTimestamp() || !profilingReport.hasEndTimestamp()
+ || profilingReport.getEndTimestamp()
+ < profilingReport.getStartTimestamp()) {
+ return null; // missing timestamp
+ }
+ long value =
+ profilingReport.getEndTimestamp() - profilingReport.getStartTimestamp();
+ values = new ArrayList<>();
+ values.add(value);
+ break;
+ case VTS_PROFILING_TYPE_LABELED_VECTOR:
+ if (profilingReport.getValueCount() != profilingReport.getLabelCount()) {
+ return null; // jagged data
+ }
+ labels = new ArrayList<>();
+ for (ByteString label : profilingReport.getLabelList()) {
+ labels.add(label.toStringUtf8());
+ }
+ values = profilingReport.getValueList();
+ break;
+ case VTS_PROFILING_TYPE_UNLABELED_VECTOR:
+ values = profilingReport.getValueList();
+ break;
+ default: // should never happen
+ return null;
+ }
+ List<String> options = null;
+ if (profilingReport.getOptionsCount() > 0) {
+ options = new ArrayList<>();
+ for (ByteString optionBytes : profilingReport.getOptionsList()) {
+ options.add(optionBytes.toStringUtf8());
+ }
+ }
+ return new ProfilingPointRunEntity(parentKey, name, type.getNumber(),
+ regressionMode.getNumber(), labels, values, xLabel, yLabel, options);
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/TestCaseRunEntity.java b/src/main/java/com/android/vts/entity/TestCaseRunEntity.java
new file mode 100644
index 0000000..02fac2d
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/TestCaseRunEntity.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.entity;
+
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Entity describing the execution of a test case. */
+public class TestCaseRunEntity implements DashboardEntity {
+ protected static final Logger logger = Logger.getLogger(TestCaseRunEntity.class.getName());
+
+ public static final String KIND = "TestCaseRun";
+
+ // Property keys
+ public static final String TEST_CASE_NAME = "testCaseName";
+ public static final String RESULT = "result";
+ public static final String TEST_CASE_NAMES = "testCaseNames";
+ public static final String RESULTS = "results";
+ public static final String SYSTRACE_URL = "systraceUrl";
+
+ // Maximum number of test cases in the entity.
+ private static final int SIZE_LIMIT = 500;
+
+ public final Key key;
+ public final List<TestCase> testCases;
+ private String systraceUrl;
+
+ /**
+ * Class describing an individual test case run.
+ */
+ public static class TestCase {
+ public final long parentId;
+ public final int offset;
+ public final String name;
+ public final int result;
+
+ /**
+ * Create a test case run.
+ * @param parentId The ID of the TestCaseRunEntity containing the test case.
+ * @param offset The offset of the TestCase into the TestCaseRunEntity.
+ * @param name The name of the test case.
+ * @param result The result of the test case.
+ */
+ public TestCase(long parentId, int offset, String name, int result) {
+ this.parentId = parentId;
+ this.offset = offset;
+ this.name = name;
+ this.result = result;
+ }
+ }
+
+ /**
+ * Create a TestCaseRunEntity with the specified key.
+ * @param key The key to use for the entity in Cloud Datastore.
+ */
+ public TestCaseRunEntity(Key key) {
+ this.key = key;
+ this.testCases = new ArrayList<>();
+ this.systraceUrl = null;
+ }
+
+ /**
+ * Determine if the TestCaseRunEntity is full.
+ * @return True if the entity is full, false otherwise.
+ */
+ public boolean isFull() {
+ return this.testCases.size() >= SIZE_LIMIT;
+ }
+
+ /**
+ * Set the systrace url.
+ * @param url The systrace url, or null.
+ */
+ public void setSystraceUrl(String url) {
+ this.systraceUrl = url;
+ }
+
+ /**
+ * Get the systrace url.
+ * returns The systrace url, or null.
+ */
+ public String getSystraceUrl() {
+ return this.systraceUrl;
+ }
+
+ /**
+ * Add a test case to the test case run entity.
+ * @param name The name of the test case.
+ * @param result The result of the test case.
+ * @return true if added, false otherwise.
+ */
+ public boolean addTestCase(String name, int result) {
+ if (isFull())
+ return false;
+ long parentId = this.key.getId();
+ this.testCases.add(new TestCase(parentId, this.testCases.size(), name, result));
+ return true;
+ }
+
+ @Override
+ public Entity toEntity() {
+ Entity testCaseRunEntity = new Entity(key);
+ if (this.testCases.size() > 0) {
+ List<String> testCaseNames = new ArrayList<>();
+ List<Integer> results = new ArrayList<>();
+ for (TestCase testCase : this.testCases) {
+ testCaseNames.add(testCase.name);
+ results.add(testCase.result);
+ }
+ testCaseRunEntity.setUnindexedProperty(TEST_CASE_NAMES, testCaseNames);
+ testCaseRunEntity.setUnindexedProperty(RESULTS, results);
+ }
+ if (systraceUrl != null) {
+ testCaseRunEntity.setUnindexedProperty(SYSTRACE_URL, this.systraceUrl);
+ }
+
+ return testCaseRunEntity;
+ }
+
+ /**
+ * Convert an Entity object to a TestCaseRunEntity.
+ *
+ * @param e The entity to process.
+ * @return TestCaseRunEntity object with the properties from e, or null if incompatible.
+ */
+ @SuppressWarnings("unchecked")
+ public static TestCaseRunEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND)) {
+ logger.log(Level.WARNING, "Wrong kind: " + e.getKey());
+ return null;
+ }
+ try {
+ TestCaseRunEntity testCaseRun = new TestCaseRunEntity(e.getKey());
+ if (e.hasProperty(TEST_CASE_NAMES) && e.hasProperty(RESULTS)) {
+ List<String> testCaseNames = (List<String>) e.getProperty(TEST_CASE_NAMES);
+ List<Long> results = (List<Long>) e.getProperty(RESULTS);
+ if (testCaseNames.size() == results.size()) {
+ for (int i = 0; i < testCaseNames.size(); i++) {
+ testCaseRun.addTestCase(testCaseNames.get(i), results.get(i).intValue());
+ }
+ }
+ }
+ if (e.hasProperty(TEST_CASE_NAME) && e.hasProperty(RESULT)) {
+ testCaseRun.addTestCase(
+ (String) e.getProperty(TEST_CASE_NAME), (int) (long) e.getProperty(RESULT));
+ }
+ if (e.hasProperty(SYSTRACE_URL)) {
+ String systraceUrl = (String) e.getProperty(SYSTRACE_URL);
+ testCaseRun.setSystraceUrl(systraceUrl);
+ }
+ return testCaseRun;
+ } catch (ClassCastException exception) {
+ // Invalid cast
+ logger.log(Level.WARNING, "Error parsing test case run entity.", exception);
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/TestEntity.java b/src/main/java/com/android/vts/entity/TestEntity.java
new file mode 100644
index 0000000..a5664f4
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/TestEntity.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.entity;
+
+import com.android.vts.entity.TestCaseRunEntity.TestCase;
+import com.google.appengine.api.datastore.Entity;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Entity describing test metadata. */
+public class TestEntity implements DashboardEntity {
+ protected static final Logger logger = Logger.getLogger(TestEntity.class.getName());
+
+ public static final String KIND = "Test";
+
+ // Property keys
+ public static final String PASS_COUNT = "passCount";
+ public static final String FAIL_COUNT = "failCount";
+ public static final String UPDATED_TIMESTAMP = "updatedTimestamp";
+
+ protected static final String FAILING_IDS = "failingTestcaseIds";
+ protected static final String FAILING_OFFSETS = "failingTestcaseOffsets";
+
+ public final String testName;
+ public final int passCount;
+ public final int failCount;
+ public final long timestamp;
+ public final List<TestCaseReference> failingTestCases;
+
+ /**
+ * Object representing a reference to a test case.
+ */
+ public static class TestCaseReference {
+ public final long parentId;
+ public final int offset;
+
+ /**
+ * Create a test case reference.
+ * @param parentId The ID of the TestCaseRunEntity containing the test case.
+ * @param offset The offset of the test case into the TestCaseRunEntity.
+ */
+ public TestCaseReference(long parentId, int offset) {
+ this.parentId = parentId;
+ this.offset = offset;
+ }
+
+ /**
+ * Create a test case reference.
+ * @param testCase The TestCase to reference.
+ */
+ public TestCaseReference(TestCase testCase) {
+ this(testCase.parentId, testCase.offset);
+ }
+ }
+
+ /**
+ * Create a TestEntity object with status metadata.
+ *
+ * @param testName The name of the test.
+ * @param timestamp The timestamp indicating the most recent test run event in the test state.
+ * @param passCount The number of tests passing up to the timestamp specified.
+ * @param failCount The number of tests failing up to the timestamp specified.
+ * @param failingTestCases The TestCaseReferences of the last observed failing test cases.
+ */
+ public TestEntity(String testName, long timestamp, int passCount, int failCount,
+ List<TestCaseReference> failingTestCases) {
+ this.testName = testName;
+ this.timestamp = timestamp;
+ this.passCount = passCount;
+ this.failCount = failCount;
+ this.failingTestCases = failingTestCases;
+ }
+
+ /**
+ * Create a TestEntity object without metadata.
+ *
+ * @param testName The name of the test.
+ */
+ public TestEntity(String testName) {
+ this(testName, 0, -1, -1, new ArrayList<TestCaseReference>());
+ }
+
+ @Override
+ public Entity toEntity() {
+ Entity testEntity = new Entity(KIND, this.testName);
+ if (this.timestamp >= 0 && this.passCount >= 0 && this.failCount >= 0) {
+ testEntity.setProperty(UPDATED_TIMESTAMP, this.timestamp);
+ testEntity.setProperty(PASS_COUNT, this.passCount);
+ testEntity.setProperty(FAIL_COUNT, this.failCount);
+ if (this.failingTestCases.size() > 0) {
+ List<Long> failingTestcaseIds = new ArrayList<>();
+ List<Integer> failingTestcaseOffsets = new ArrayList<>();
+ for (TestCaseReference testCase : this.failingTestCases) {
+ failingTestcaseIds.add(testCase.parentId);
+ failingTestcaseOffsets.add(testCase.offset);
+ }
+ testEntity.setUnindexedProperty(FAILING_IDS, failingTestcaseIds);
+ testEntity.setUnindexedProperty(FAILING_OFFSETS, failingTestcaseOffsets);
+ }
+ }
+ return testEntity;
+ }
+
+ /**
+ * Convert an Entity object to a TestEntity.
+ *
+ * @param e The entity to process.
+ * @return TestEntity object with the properties from e processed, or null if incompatible.
+ */
+ @SuppressWarnings("unchecked")
+ public static TestEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND) || e.getKey().getName() == null) {
+ logger.log(Level.WARNING, "Missing test attributes in entity: " + e.toString());
+ return null;
+ }
+ String testName = e.getKey().getName();
+ long timestamp = 0;
+ int passCount = -1;
+ int failCount = -1;
+ List<TestCaseReference> failingTestCases = new ArrayList<>();
+ try {
+ if (e.hasProperty(UPDATED_TIMESTAMP)) {
+ timestamp = (long) e.getProperty(UPDATED_TIMESTAMP);
+ }
+ if (e.hasProperty(PASS_COUNT)) {
+ passCount = ((Long) e.getProperty(PASS_COUNT)).intValue();
+ }
+ if (e.hasProperty(FAIL_COUNT)) {
+ failCount = ((Long) e.getProperty(FAIL_COUNT)).intValue();
+ }
+ if (e.hasProperty(FAILING_IDS) && e.hasProperty(FAILING_OFFSETS)) {
+ List<Long> ids = (List<Long>) e.getProperty(FAILING_IDS);
+ List<Long> offsets = (List<Long>) e.getProperty(FAILING_OFFSETS);
+ if (ids.size() == offsets.size()) {
+ for (int i = 0; i < ids.size(); i++) {
+ failingTestCases.add(
+ new TestCaseReference(ids.get(i), offsets.get(i).intValue()));
+ }
+ }
+ }
+ } catch (ClassCastException exception) {
+ // Invalid contents or null values
+ logger.log(Level.WARNING, "Error parsing test entity.", exception);
+ }
+ return new TestEntity(testName, timestamp, passCount, failCount, failingTestCases);
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/TestPlanEntity.java b/src/main/java/com/android/vts/entity/TestPlanEntity.java
new file mode 100644
index 0000000..82d7e5e
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/TestPlanEntity.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.entity;
+
+import com.google.appengine.api.datastore.Entity;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Entity describing test plan metadata. */
+public class TestPlanEntity implements DashboardEntity {
+ protected static final Logger logger = Logger.getLogger(TestPlanEntity.class.getName());
+
+ public static final String KIND = "TestPlan";
+
+ // Property keys
+ public static final String TEST_PLAN_NAME = "testPlanName";
+
+ public final String testPlanName;
+
+ /**
+ * Create a TestPlanEntity object.
+ *
+ * @param testPlanName The name of the test plan.
+ */
+ public TestPlanEntity(String testPlanName) {
+ this.testPlanName = testPlanName;
+ }
+
+ @Override
+ public Entity toEntity() {
+ Entity planEntity = new Entity(KIND, this.testPlanName);
+ return planEntity;
+ }
+
+ /**
+ * Convert an Entity object to a TestEntity.
+ *
+ * @param e The entity to process.
+ * @return TestEntity object with the properties from e processed, or null if incompatible.
+ */
+ @SuppressWarnings("unchecked")
+ public static TestPlanEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND) || e.getKey().getName() == null
+ || !e.hasProperty(TEST_PLAN_NAME)) {
+ logger.log(Level.WARNING, "Missing test plan attributes in entity: " + e.toString());
+ return null;
+ }
+ String testPlanName = e.getKey().getName();
+ return new TestPlanEntity(testPlanName);
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/TestPlanRunEntity.java b/src/main/java/com/android/vts/entity/TestPlanRunEntity.java
new file mode 100644
index 0000000..cc161ac
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/TestPlanRunEntity.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.entity;
+
+import com.android.vts.entity.TestRunEntity.TestRunType;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Entity describing test plan run information. */
+public class TestPlanRunEntity implements DashboardEntity {
+ protected static final Logger logger = Logger.getLogger(TestPlanRunEntity.class.getName());
+
+ public static final String KIND = "TestPlanRun";
+
+ // Property keys
+ public static final String TEST_PLAN_NAME = "testPlanName";
+ public static final String TYPE = "type";
+ public static final String START_TIMESTAMP = "startTimestamp";
+ public static final String END_TIMESTAMP = "endTimestamp";
+ public static final String TEST_BUILD_ID = "testBuildId";
+ public static final String PASS_COUNT = "passCount";
+ public static final String FAIL_COUNT = "failCount";
+ public static final String TEST_RUNS = "testRuns";
+
+ public final Key key;
+ public final String testPlanName;
+ public final TestRunType type;
+ public final long startTimestamp;
+ public final long endTimestamp;
+ public final String testBuildId;
+ public final long passCount;
+ public final long failCount;
+ public final List<Key> testRuns;
+
+ /**
+ * Create a TestPlanRunEntity object describing a test plan run.
+ *
+ * @param parentKey The key for the parent entity in the database.
+ * @param type The test run type (e.g. presubmit, postsubmit, other)
+ * @param startTimestamp The time in microseconds when the test plan run started.
+ * @param endTimestamp The time in microseconds when the test plan run ended.
+ * @param testBuildId The build ID of the VTS test build.
+ * @param passCount The number of passing test cases in the run.
+ * @param failCount The number of failing test cases in the run.
+ * @param testRuns A list of keys to the TestRunEntity objects for the plan run run.
+ */
+ public TestPlanRunEntity(Key parentKey, String testPlanName, TestRunType type,
+ long startTimestamp, long endTimestamp, String testBuildId, long passCount,
+ long failCount, List<Key> testRuns) {
+ this.key = KeyFactory.createKey(parentKey, KIND, startTimestamp);
+ this.testPlanName = testPlanName;
+ this.type = type;
+ this.startTimestamp = startTimestamp;
+ this.endTimestamp = endTimestamp;
+ this.testBuildId = testBuildId;
+ this.passCount = passCount;
+ this.failCount = failCount;
+ this.testRuns = testRuns;
+ }
+
+ @Override
+ public Entity toEntity() {
+ Entity planRun = new Entity(this.key);
+ planRun.setProperty(TEST_PLAN_NAME, this.testPlanName);
+ planRun.setProperty(TYPE, this.type.getNumber());
+ planRun.setProperty(START_TIMESTAMP, this.startTimestamp);
+ planRun.setProperty(END_TIMESTAMP, this.endTimestamp);
+ planRun.setProperty(TEST_BUILD_ID, this.testBuildId.toLowerCase());
+ planRun.setProperty(PASS_COUNT, this.passCount);
+ planRun.setProperty(FAIL_COUNT, this.failCount);
+ if (this.testRuns != null && this.testRuns.size() > 0) {
+ planRun.setUnindexedProperty(TEST_RUNS, this.testRuns);
+ }
+ return planRun;
+ }
+
+ /**
+ * Convert an Entity object to a TestPlanRunEntity.
+ *
+ * @param e The entity to process.
+ * @return TestPlanRunEntity object with the properties from e processed, or null if
+ * incompatible.
+ */
+ @SuppressWarnings("unchecked")
+ public static TestPlanRunEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND) || !e.hasProperty(TEST_PLAN_NAME) || !e.hasProperty(TYPE)
+ || !e.hasProperty(START_TIMESTAMP) || !e.hasProperty(END_TIMESTAMP)
+ || !e.hasProperty(TEST_BUILD_ID) || !e.hasProperty(PASS_COUNT)
+ || !e.hasProperty(FAIL_COUNT) || !e.hasProperty(TEST_RUNS)) {
+ logger.log(Level.WARNING, "Missing test run attributes in entity: " + e.toString());
+ return null;
+ }
+ try {
+ String testPlanName = (String) e.getProperty(TEST_PLAN_NAME);
+ TestRunType type = TestRunType.fromNumber((int) (long) e.getProperty(TYPE));
+ long startTimestamp = (long) e.getProperty(START_TIMESTAMP);
+ long endTimestamp = (long) e.getProperty(END_TIMESTAMP);
+ String testBuildId = (String) e.getProperty(TEST_BUILD_ID);
+ long passCount = (long) e.getProperty(PASS_COUNT);
+ long failCount = (long) e.getProperty(FAIL_COUNT);
+ List<Key> testRuns = (List<Key>) e.getProperty(TEST_RUNS);
+ return new TestPlanRunEntity(e.getKey().getParent(), testPlanName, type, startTimestamp,
+ endTimestamp, testBuildId, passCount, failCount, testRuns);
+ } catch (ClassCastException exception) {
+ // Invalid cast
+ logger.log(Level.WARNING, "Error parsing test plan run entity.", exception);
+ }
+ return null;
+ }
+
+ public JsonObject toJson() {
+ JsonObject json = new JsonObject();
+ json.add(TEST_PLAN_NAME, new JsonPrimitive(this.testPlanName));
+ json.add(TEST_BUILD_ID, new JsonPrimitive(this.testBuildId));
+ json.add(PASS_COUNT, new JsonPrimitive(this.passCount));
+ json.add(FAIL_COUNT, new JsonPrimitive(this.failCount));
+ json.add(START_TIMESTAMP, new JsonPrimitive(this.startTimestamp));
+ json.add(END_TIMESTAMP, new JsonPrimitive(this.endTimestamp));
+ return json;
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/TestRunEntity.java b/src/main/java/com/android/vts/entity/TestRunEntity.java
new file mode 100644
index 0000000..8bb94a8
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/TestRunEntity.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.entity;
+
+import com.android.vts.util.UrlUtil;
+import com.android.vts.util.UrlUtil.LinkDisplay;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Entity describing test run information. */
+public class TestRunEntity implements DashboardEntity {
+ protected static final Logger logger = Logger.getLogger(TestRunEntity.class.getName());
+
+ /** Enum for classifying test run types. */
+ public enum TestRunType {
+ OTHER(0),
+ PRESUBMIT(1),
+ POSTSUBMIT(2);
+
+ private final int value;
+
+ private TestRunType(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the ordinal representation of the type.
+ *
+ * @return The value associated with the test run type.
+ */
+ public int getNumber() {
+ return value;
+ }
+
+ /**
+ * Convert an ordinal value to a TestRunType.
+ *
+ * @param value The orginal value to parse.
+ * @return a TestRunType value.
+ */
+ public static TestRunType fromNumber(int value) {
+ if (value == 1) {
+ return TestRunType.PRESUBMIT;
+ } else if (value == 2) {
+ return TestRunType.POSTSUBMIT;
+ } else {
+ return TestRunType.OTHER;
+ }
+ }
+
+ /**
+ * Determine the test run type based on the build ID.
+ *
+ * Postsubmit runs are expected to have integer build IDs, while presubmit runs are integers
+ * prefixed by the character P. All other runs (e.g. local builds) are classified as OTHER.
+ *
+ * @param buildId The build ID.
+ * @return the TestRunType.
+ */
+ public static TestRunType fromBuildId(String buildId) {
+ try {
+ Integer.parseInt(buildId);
+ return TestRunType.POSTSUBMIT;
+ } catch (NumberFormatException e) {
+ // Not an integer
+ }
+ if (Character.toLowerCase(buildId.charAt(0)) == 'p') {
+ try {
+ Integer.parseInt(buildId.substring(1));
+ return TestRunType.PRESUBMIT;
+ } catch (NumberFormatException e) {
+ // Not an integer
+ }
+ }
+ return TestRunType.OTHER;
+ }
+ }
+
+ public static final String KIND = "TestRun";
+
+ // Property keys
+ public static final String TEST_NAME = "testName";
+ public static final String TYPE = "type";
+ public static final String START_TIMESTAMP = "startTimestamp";
+ public static final String END_TIMESTAMP = "endTimestamp";
+ public static final String TEST_BUILD_ID = "testBuildId";
+ public static final String HOST_NAME = "hostName";
+ public static final String PASS_COUNT = "passCount";
+ public static final String FAIL_COUNT = "failCount";
+ public static final String TEST_CASE_IDS = "testCaseIds";
+ public static final String LOG_LINKS = "logLinks";
+ public static final String HAS_COVERAGE = "hasCoverage";
+ public static final String TOTAL_LINE_COUNT = "totalLineCount";
+ public static final String COVERED_LINE_COUNT = "coveredLineCount";
+
+ public final Key key;
+ public final TestRunType type;
+ public final long startTimestamp;
+ public final long endTimestamp;
+ public final String testBuildId;
+ public final String hostName;
+ public final long passCount;
+ public final long failCount;
+ public final boolean hasCoverage;
+ public final long coveredLineCount;
+ public final long totalLineCount;
+ public final List<Long> testCaseIds;
+ public final List<String> logLinks;
+
+ /**
+ * Create a TestRunEntity object describing a test run.
+ *
+ * @param parentKey The key to the parent TestEntity.
+ * @param type The test run type (e.g. presubmit, postsubmit, other)
+ * @param startTimestamp The time in microseconds when the test run started.
+ * @param endTimestamp The time in microseconds when the test run ended.
+ * @param testBuildId The build ID of the VTS test build.
+ * @param hostName The name of host machine.
+ * @param passCount The number of passing test cases in the run.
+ * @param failCount The number of failing test cases in the run.
+ * @param testCaseIds A list of key IDs to the TestCaseRunEntity objects for the test run.
+ * @param logLinks A list of links to log files for the test run, or null if there aren't any.
+ * @param coveredLineCount The number of lines covered by the test run.
+ * @param totalLineCount The total number of executable lines by the test in the test run.
+ */
+ public TestRunEntity(Key parentKey, TestRunType type, long startTimestamp, long endTimestamp,
+ String testBuildId, String hostName, long passCount, long failCount,
+ List<Long> testCaseIds, List<String> logLinks, long coveredLineCount,
+ long totalLineCount) {
+ this.key = KeyFactory.createKey(parentKey, KIND, startTimestamp);
+ this.type = type;
+ this.startTimestamp = startTimestamp;
+ this.endTimestamp = endTimestamp;
+ this.testBuildId = testBuildId;
+ this.hostName = hostName;
+ this.passCount = passCount;
+ this.failCount = failCount;
+ this.testCaseIds = testCaseIds;
+ this.logLinks = logLinks;
+ this.coveredLineCount = coveredLineCount;
+ this.totalLineCount = totalLineCount;
+ this.hasCoverage = totalLineCount > 0;
+ }
+
+ /**
+ * Create a TestRunEntity object describing a test run.
+ *
+ * @param parentKey The key to the parent TestEntity.
+ * @param type The test run type (e.g. presubmit, postsubmit, other)
+ * @param startTimestamp The time in microseconds when the test run started.
+ * @param endTimestamp The time in microseconds when the test run ended.
+ * @param testBuildId The build ID of the VTS test build.
+ * @param hostName The name of host machine.
+ * @param passCount The number of passing test cases in the run.
+ * @param failCount The number of failing test cases in the run.
+ * @param testCaseIds A list of key IDs to the TestCaseRunEntity objects for the test run.
+ * @param logLinks A list of links to log files for the test run, or null if there aren't any.
+ */
+ public TestRunEntity(Key parentKey, TestRunType type, long startTimestamp, long endTimestamp,
+ String testBuildId, String hostName, long passCount, long failCount,
+ List<Long> testCaseIds, List<String> logLinks) {
+ this(parentKey, type, startTimestamp, endTimestamp, testBuildId, hostName, passCount,
+ failCount, testCaseIds, logLinks, 0, 0);
+ }
+
+ @Override
+ public Entity toEntity() {
+ Entity testRunEntity = new Entity(this.key);
+ testRunEntity.setProperty(TEST_NAME, this.key.getParent().getName());
+ testRunEntity.setProperty(TYPE, this.type.getNumber());
+ testRunEntity.setProperty(START_TIMESTAMP, this.startTimestamp);
+ testRunEntity.setUnindexedProperty(END_TIMESTAMP, this.endTimestamp);
+ testRunEntity.setProperty(TEST_BUILD_ID, this.testBuildId.toLowerCase());
+ testRunEntity.setProperty(HOST_NAME, this.hostName.toLowerCase());
+ testRunEntity.setProperty(PASS_COUNT, this.passCount);
+ testRunEntity.setProperty(FAIL_COUNT, this.failCount);
+ testRunEntity.setUnindexedProperty(TEST_CASE_IDS, this.testCaseIds);
+ boolean hasCoverage = this.totalLineCount > 0 && this.coveredLineCount >= 0;
+ testRunEntity.setProperty(HAS_COVERAGE, hasCoverage);
+ if (hasCoverage) {
+ testRunEntity.setProperty(COVERED_LINE_COUNT, this.coveredLineCount);
+ testRunEntity.setProperty(TOTAL_LINE_COUNT, this.totalLineCount);
+ }
+ if (this.logLinks != null && this.logLinks.size() > 0) {
+ testRunEntity.setUnindexedProperty(LOG_LINKS, this.logLinks);
+ }
+ return testRunEntity;
+ }
+
+ /**
+ * Convert an Entity object to a TestRunEntity.
+ *
+ * @param e The entity to process.
+ * @return TestRunEntity object with the properties from e processed, or null if incompatible.
+ */
+ @SuppressWarnings("unchecked")
+ public static TestRunEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND) || !e.hasProperty(TYPE) || !e.hasProperty(START_TIMESTAMP)
+ || !e.hasProperty(END_TIMESTAMP) || !e.hasProperty(TEST_BUILD_ID)
+ || !e.hasProperty(HOST_NAME) || !e.hasProperty(PASS_COUNT)
+ || !e.hasProperty(FAIL_COUNT) || !e.hasProperty(TEST_CASE_IDS)) {
+ logger.log(Level.WARNING, "Missing test run attributes in entity: " + e.toString());
+ return null;
+ }
+ try {
+ TestRunType type = TestRunType.fromNumber((int) (long) e.getProperty(TYPE));
+ long startTimestamp = (long) e.getProperty(START_TIMESTAMP);
+ long endTimestamp = (long) e.getProperty(END_TIMESTAMP);
+ String testBuildId = (String) e.getProperty(TEST_BUILD_ID);
+ String hostName = (String) e.getProperty(HOST_NAME);
+ long passCount = (long) e.getProperty(PASS_COUNT);
+ long failCount = (long) e.getProperty(FAIL_COUNT);
+ List<Long> testCaseIds = (List<Long>) e.getProperty(TEST_CASE_IDS);
+ List<String> logLinks = null;
+ long coveredLineCount = 0;
+ long totalLineCount = 0;
+ if (e.hasProperty(TOTAL_LINE_COUNT) && e.hasProperty(COVERED_LINE_COUNT)) {
+ coveredLineCount = (long) e.getProperty(COVERED_LINE_COUNT);
+ totalLineCount = (long) e.getProperty(TOTAL_LINE_COUNT);
+ }
+ if (e.hasProperty(LOG_LINKS)) {
+ logLinks = (List<String>) e.getProperty(LOG_LINKS);
+ }
+ return new TestRunEntity(e.getKey().getParent(), type, startTimestamp, endTimestamp,
+ testBuildId, hostName, passCount, failCount, testCaseIds, logLinks,
+ coveredLineCount, totalLineCount);
+ } catch (ClassCastException exception) {
+ // Invalid cast
+ logger.log(Level.WARNING, "Error parsing test run entity.", exception);
+ }
+ return null;
+ }
+
+ public JsonObject toJson() {
+ JsonObject json = new JsonObject();
+ json.add(TEST_NAME, new JsonPrimitive(this.key.getParent().getName()));
+ json.add(TEST_BUILD_ID, new JsonPrimitive(this.testBuildId));
+ json.add(HOST_NAME, new JsonPrimitive(this.hostName));
+ json.add(PASS_COUNT, new JsonPrimitive(this.passCount));
+ json.add(FAIL_COUNT, new JsonPrimitive(this.failCount));
+ json.add(START_TIMESTAMP, new JsonPrimitive(this.startTimestamp));
+ json.add(END_TIMESTAMP, new JsonPrimitive(this.endTimestamp));
+ if (this.totalLineCount > 0 && this.coveredLineCount >= 0) {
+ json.add(COVERED_LINE_COUNT, new JsonPrimitive(this.coveredLineCount));
+ json.add(TOTAL_LINE_COUNT, new JsonPrimitive(this.totalLineCount));
+ }
+ if (this.logLinks != null && this.logLinks.size() > 0) {
+ List<JsonElement> links = new ArrayList<>();
+ for (String rawUrl : this.logLinks) {
+ LinkDisplay validatedLink = UrlUtil.processUrl(rawUrl);
+ if (validatedLink == null) {
+ logger.log(Level.WARNING, "Invalid logging URL : " + rawUrl);
+ continue;
+ }
+ String[] logInfo = new String[] {validatedLink.name, validatedLink.url};
+ links.add(new Gson().toJsonTree(logInfo));
+ }
+ if (links.size() > 0) {
+ json.add(LOG_LINKS, new Gson().toJsonTree(links));
+ }
+ }
+ return json;
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/UserFavoriteEntity.java b/src/main/java/com/android/vts/entity/UserFavoriteEntity.java
new file mode 100644
index 0000000..a2820a6
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/UserFavoriteEntity.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.entity;
+
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.users.User;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Entity describing subscriptions between a user and a test. */
+public class UserFavoriteEntity implements DashboardEntity {
+ protected static final Logger logger = Logger.getLogger(UserFavoriteEntity.class.getName());
+
+ public static final String KIND = "UserFavorite";
+
+ // Property keys
+ public static final String USER = "user";
+ public static final String TEST_KEY = "testKey";
+
+ public final User user;
+ public final Key testKey;
+
+ /**
+ * Create a user favorite relationship.
+ *
+ * @param user The User object for the subscribing user.
+ * @param testKey The key of the TestEntity object describing the test.
+ */
+ public UserFavoriteEntity(User user, Key testKey) {
+ this.user = user;
+ this.testKey = testKey;
+ }
+
+ @Override
+ public Entity toEntity() {
+ Entity favoriteEntity = new Entity(KIND);
+ favoriteEntity.setProperty(USER, this.user);
+ favoriteEntity.setProperty(TEST_KEY, this.testKey);
+ return favoriteEntity;
+ }
+
+ /**
+ * Convert an Entity object to a UserFavoriteEntity.
+ *
+ * @param e The entity to process.
+ * @return UserFavoriteEntity object with the properties from e, or null if incompatible.
+ */
+ public static UserFavoriteEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND) || !e.hasProperty(USER) || !e.hasProperty(TEST_KEY)) {
+ logger.log(
+ Level.WARNING, "Missing user favorite attributes in entity: " + e.toString());
+ return null;
+ }
+ try {
+ User user = (User) e.getProperty(USER);
+ Key testKey = (Key) e.getProperty(TEST_KEY);
+ return new UserFavoriteEntity(user, testKey);
+ } catch (ClassCastException exception) {
+ // Invalid cast
+ logger.log(Level.WARNING, "Error parsing user favorite entity.", exception);
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/android/vts/proto/VtsReportMessage.java b/src/main/java/com/android/vts/proto/VtsReportMessage.java
new file mode 100644
index 0000000..ac80e86
--- /dev/null
+++ b/src/main/java/com/android/vts/proto/VtsReportMessage.java
@@ -0,0 +1,18604 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: proto/VtsReportMessage.proto
+
+package com.android.vts.proto;
+
+public final class VtsReportMessage {
+ private VtsReportMessage() {}
+ public static void registerAllExtensions(
+ com.google.protobuf.ExtensionRegistry registry) {
+ }
+ /**
+ * Protobuf enum {@code android.vts.TestCaseResult}
+ *
+ * <pre>
+ * To specify test case execution result.
+ * </pre>
+ */
+ public enum TestCaseResult
+ implements com.google.protobuf.ProtocolMessageEnum {
+ /**
+ * <code>UNKNOWN_RESULT = 0;</code>
+ */
+ UNKNOWN_RESULT(0, 0),
+ /**
+ * <code>TEST_CASE_RESULT_PASS = 1;</code>
+ */
+ TEST_CASE_RESULT_PASS(1, 1),
+ /**
+ * <code>TEST_CASE_RESULT_FAIL = 2;</code>
+ */
+ TEST_CASE_RESULT_FAIL(2, 2),
+ /**
+ * <code>TEST_CASE_RESULT_SKIP = 3;</code>
+ */
+ TEST_CASE_RESULT_SKIP(3, 3),
+ /**
+ * <code>TEST_CASE_RESULT_EXCEPTION = 4;</code>
+ */
+ TEST_CASE_RESULT_EXCEPTION(4, 4),
+ /**
+ * <code>TEST_CASE_RESULT_TIMEOUT = 5;</code>
+ */
+ TEST_CASE_RESULT_TIMEOUT(5, 5),
+ ;
+
+ /**
+ * <code>UNKNOWN_RESULT = 0;</code>
+ */
+ public static final int UNKNOWN_RESULT_VALUE = 0;
+ /**
+ * <code>TEST_CASE_RESULT_PASS = 1;</code>
+ */
+ public static final int TEST_CASE_RESULT_PASS_VALUE = 1;
+ /**
+ * <code>TEST_CASE_RESULT_FAIL = 2;</code>
+ */
+ public static final int TEST_CASE_RESULT_FAIL_VALUE = 2;
+ /**
+ * <code>TEST_CASE_RESULT_SKIP = 3;</code>
+ */
+ public static final int TEST_CASE_RESULT_SKIP_VALUE = 3;
+ /**
+ * <code>TEST_CASE_RESULT_EXCEPTION = 4;</code>
+ */
+ public static final int TEST_CASE_RESULT_EXCEPTION_VALUE = 4;
+ /**
+ * <code>TEST_CASE_RESULT_TIMEOUT = 5;</code>
+ */
+ public static final int TEST_CASE_RESULT_TIMEOUT_VALUE = 5;
+
+
+ public final int getNumber() { return value; }
+
+ public static TestCaseResult valueOf(int value) {
+ switch (value) {
+ case 0: return UNKNOWN_RESULT;
+ case 1: return TEST_CASE_RESULT_PASS;
+ case 2: return TEST_CASE_RESULT_FAIL;
+ case 3: return TEST_CASE_RESULT_SKIP;
+ case 4: return TEST_CASE_RESULT_EXCEPTION;
+ case 5: return TEST_CASE_RESULT_TIMEOUT;
+ default: return null;
+ }
+ }
+
+ public static com.google.protobuf.Internal.EnumLiteMap<TestCaseResult>
+ internalGetValueMap() {
+ return internalValueMap;
+ }
+ private static com.google.protobuf.Internal.EnumLiteMap<TestCaseResult>
+ internalValueMap =
+ new com.google.protobuf.Internal.EnumLiteMap<TestCaseResult>() {
+ public TestCaseResult findValueByNumber(int number) {
+ return TestCaseResult.valueOf(number);
+ }
+ };
+
+ public final com.google.protobuf.Descriptors.EnumValueDescriptor
+ getValueDescriptor() {
+ return getDescriptor().getValues().get(index);
+ }
+ public final com.google.protobuf.Descriptors.EnumDescriptor
+ getDescriptorForType() {
+ return getDescriptor();
+ }
+ public static final com.google.protobuf.Descriptors.EnumDescriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.getDescriptor().getEnumTypes().get(0);
+ }
+
+ private static final TestCaseResult[] VALUES = values();
+
+ public static TestCaseResult valueOf(
+ com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+ if (desc.getType() != getDescriptor()) {
+ throw new java.lang.IllegalArgumentException(
+ "EnumValueDescriptor is not for this type.");
+ }
+ return VALUES[desc.getIndex()];
+ }
+
+ private final int index;
+ private final int value;
+
+ private TestCaseResult(int index, int value) {
+ this.index = index;
+ this.value = value;
+ }
+
+ // @@protoc_insertion_point(enum_scope:android.vts.TestCaseResult)
+ }
+
+ /**
+ * Protobuf enum {@code android.vts.VtsTestType}
+ *
+ * <pre>
+ * To specify the VTS test type.
+ * </pre>
+ */
+ public enum VtsTestType
+ implements com.google.protobuf.ProtocolMessageEnum {
+ /**
+ * <code>UNKNOWN_VTS_TESTTYPE = 0;</code>
+ */
+ UNKNOWN_VTS_TESTTYPE(0, 0),
+ /**
+ * <code>VTS_HOST_DRIVEN_STRUCTURAL = 1;</code>
+ */
+ VTS_HOST_DRIVEN_STRUCTURAL(1, 1),
+ /**
+ * <code>VTS_HOST_DRIVEN_FUZZING = 2;</code>
+ */
+ VTS_HOST_DRIVEN_FUZZING(2, 2),
+ /**
+ * <code>VTS_TARGET_SIDE_GTEST = 3;</code>
+ */
+ VTS_TARGET_SIDE_GTEST(3, 3),
+ /**
+ * <code>VTS_TARGET_SIDE_FUZZING = 4;</code>
+ */
+ VTS_TARGET_SIDE_FUZZING(4, 4),
+ ;
+
+ /**
+ * <code>UNKNOWN_VTS_TESTTYPE = 0;</code>
+ */
+ public static final int UNKNOWN_VTS_TESTTYPE_VALUE = 0;
+ /**
+ * <code>VTS_HOST_DRIVEN_STRUCTURAL = 1;</code>
+ */
+ public static final int VTS_HOST_DRIVEN_STRUCTURAL_VALUE = 1;
+ /**
+ * <code>VTS_HOST_DRIVEN_FUZZING = 2;</code>
+ */
+ public static final int VTS_HOST_DRIVEN_FUZZING_VALUE = 2;
+ /**
+ * <code>VTS_TARGET_SIDE_GTEST = 3;</code>
+ */
+ public static final int VTS_TARGET_SIDE_GTEST_VALUE = 3;
+ /**
+ * <code>VTS_TARGET_SIDE_FUZZING = 4;</code>
+ */
+ public static final int VTS_TARGET_SIDE_FUZZING_VALUE = 4;
+
+
+ public final int getNumber() { return value; }
+
+ public static VtsTestType valueOf(int value) {
+ switch (value) {
+ case 0: return UNKNOWN_VTS_TESTTYPE;
+ case 1: return VTS_HOST_DRIVEN_STRUCTURAL;
+ case 2: return VTS_HOST_DRIVEN_FUZZING;
+ case 3: return VTS_TARGET_SIDE_GTEST;
+ case 4: return VTS_TARGET_SIDE_FUZZING;
+ default: return null;
+ }
+ }
+
+ public static com.google.protobuf.Internal.EnumLiteMap<VtsTestType>
+ internalGetValueMap() {
+ return internalValueMap;
+ }
+ private static com.google.protobuf.Internal.EnumLiteMap<VtsTestType>
+ internalValueMap =
+ new com.google.protobuf.Internal.EnumLiteMap<VtsTestType>() {
+ public VtsTestType findValueByNumber(int number) {
+ return VtsTestType.valueOf(number);
+ }
+ };
+
+ public final com.google.protobuf.Descriptors.EnumValueDescriptor
+ getValueDescriptor() {
+ return getDescriptor().getValues().get(index);
+ }
+ public final com.google.protobuf.Descriptors.EnumDescriptor
+ getDescriptorForType() {
+ return getDescriptor();
+ }
+ public static final com.google.protobuf.Descriptors.EnumDescriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.getDescriptor().getEnumTypes().get(1);
+ }
+
+ private static final VtsTestType[] VALUES = values();
+
+ public static VtsTestType valueOf(
+ com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+ if (desc.getType() != getDescriptor()) {
+ throw new java.lang.IllegalArgumentException(
+ "EnumValueDescriptor is not for this type.");
+ }
+ return VALUES[desc.getIndex()];
+ }
+
+ private final int index;
+ private final int value;
+
+ private VtsTestType(int index, int value) {
+ this.index = index;
+ this.value = value;
+ }
+
+ // @@protoc_insertion_point(enum_scope:android.vts.VtsTestType)
+ }
+
+ /**
+ * Protobuf enum {@code android.vts.VtsProfilingRegressionMode}
+ */
+ public enum VtsProfilingRegressionMode
+ implements com.google.protobuf.ProtocolMessageEnum {
+ /**
+ * <code>UNKNOWN_REGRESSION_MODE = 0;</code>
+ */
+ UNKNOWN_REGRESSION_MODE(0, 0),
+ /**
+ * <code>VTS_REGRESSION_MODE_DISABLED = 1;</code>
+ *
+ * <pre>
+ * disable analysis
+ * </pre>
+ */
+ VTS_REGRESSION_MODE_DISABLED(1, 1),
+ /**
+ * <code>VTS_REGRESSION_MODE_INCREASING = 2;</code>
+ *
+ * <pre>
+ * interpret increases in values as regression
+ * </pre>
+ */
+ VTS_REGRESSION_MODE_INCREASING(2, 2),
+ /**
+ * <code>VTS_REGRESSION_MODE_DECREASING = 3;</code>
+ *
+ * <pre>
+ * interpret decreases in values as regression
+ * </pre>
+ */
+ VTS_REGRESSION_MODE_DECREASING(3, 3),
+ ;
+
+ /**
+ * <code>UNKNOWN_REGRESSION_MODE = 0;</code>
+ */
+ public static final int UNKNOWN_REGRESSION_MODE_VALUE = 0;
+ /**
+ * <code>VTS_REGRESSION_MODE_DISABLED = 1;</code>
+ *
+ * <pre>
+ * disable analysis
+ * </pre>
+ */
+ public static final int VTS_REGRESSION_MODE_DISABLED_VALUE = 1;
+ /**
+ * <code>VTS_REGRESSION_MODE_INCREASING = 2;</code>
+ *
+ * <pre>
+ * interpret increases in values as regression
+ * </pre>
+ */
+ public static final int VTS_REGRESSION_MODE_INCREASING_VALUE = 2;
+ /**
+ * <code>VTS_REGRESSION_MODE_DECREASING = 3;</code>
+ *
+ * <pre>
+ * interpret decreases in values as regression
+ * </pre>
+ */
+ public static final int VTS_REGRESSION_MODE_DECREASING_VALUE = 3;
+
+
+ public final int getNumber() { return value; }
+
+ public static VtsProfilingRegressionMode valueOf(int value) {
+ switch (value) {
+ case 0: return UNKNOWN_REGRESSION_MODE;
+ case 1: return VTS_REGRESSION_MODE_DISABLED;
+ case 2: return VTS_REGRESSION_MODE_INCREASING;
+ case 3: return VTS_REGRESSION_MODE_DECREASING;
+ default: return null;
+ }
+ }
+
+ public static com.google.protobuf.Internal.EnumLiteMap<VtsProfilingRegressionMode>
+ internalGetValueMap() {
+ return internalValueMap;
+ }
+ private static com.google.protobuf.Internal.EnumLiteMap<VtsProfilingRegressionMode>
+ internalValueMap =
+ new com.google.protobuf.Internal.EnumLiteMap<VtsProfilingRegressionMode>() {
+ public VtsProfilingRegressionMode findValueByNumber(int number) {
+ return VtsProfilingRegressionMode.valueOf(number);
+ }
+ };
+
+ public final com.google.protobuf.Descriptors.EnumValueDescriptor
+ getValueDescriptor() {
+ return getDescriptor().getValues().get(index);
+ }
+ public final com.google.protobuf.Descriptors.EnumDescriptor
+ getDescriptorForType() {
+ return getDescriptor();
+ }
+ public static final com.google.protobuf.Descriptors.EnumDescriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.getDescriptor().getEnumTypes().get(2);
+ }
+
+ private static final VtsProfilingRegressionMode[] VALUES = values();
+
+ public static VtsProfilingRegressionMode valueOf(
+ com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+ if (desc.getType() != getDescriptor()) {
+ throw new java.lang.IllegalArgumentException(
+ "EnumValueDescriptor is not for this type.");
+ }
+ return VALUES[desc.getIndex()];
+ }
+
+ private final int index;
+ private final int value;
+
+ private VtsProfilingRegressionMode(int index, int value) {
+ this.index = index;
+ this.value = value;
+ }
+
+ // @@protoc_insertion_point(enum_scope:android.vts.VtsProfilingRegressionMode)
+ }
+
+ /**
+ * Protobuf enum {@code android.vts.VtsProfilingType}
+ */
+ public enum VtsProfilingType
+ implements com.google.protobuf.ProtocolMessageEnum {
+ /**
+ * <code>UNKNOWN_VTS_PROFILING_TYPE = 0;</code>
+ */
+ UNKNOWN_VTS_PROFILING_TYPE(0, 0),
+ /**
+ * <code>VTS_PROFILING_TYPE_TIMESTAMP = 1;</code>
+ *
+ * <pre>
+ * for one sample which measures the time between two profiling points.
+ * </pre>
+ */
+ VTS_PROFILING_TYPE_TIMESTAMP(1, 1),
+ /**
+ * <code>VTS_PROFILING_TYPE_LABELED_VECTOR = 2;</code>
+ *
+ * <pre>
+ * for multiple single-type samples with labels.
+ * </pre>
+ */
+ VTS_PROFILING_TYPE_LABELED_VECTOR(2, 2),
+ /**
+ * <code>VTS_PROFILING_TYPE_UNLABELED_VECTOR = 3;</code>
+ *
+ * <pre>
+ * for multiple single-type samples without labels.
+ * </pre>
+ */
+ VTS_PROFILING_TYPE_UNLABELED_VECTOR(3, 3),
+ ;
+
+ /**
+ * <code>UNKNOWN_VTS_PROFILING_TYPE = 0;</code>
+ */
+ public static final int UNKNOWN_VTS_PROFILING_TYPE_VALUE = 0;
+ /**
+ * <code>VTS_PROFILING_TYPE_TIMESTAMP = 1;</code>
+ *
+ * <pre>
+ * for one sample which measures the time between two profiling points.
+ * </pre>
+ */
+ public static final int VTS_PROFILING_TYPE_TIMESTAMP_VALUE = 1;
+ /**
+ * <code>VTS_PROFILING_TYPE_LABELED_VECTOR = 2;</code>
+ *
+ * <pre>
+ * for multiple single-type samples with labels.
+ * </pre>
+ */
+ public static final int VTS_PROFILING_TYPE_LABELED_VECTOR_VALUE = 2;
+ /**
+ * <code>VTS_PROFILING_TYPE_UNLABELED_VECTOR = 3;</code>
+ *
+ * <pre>
+ * for multiple single-type samples without labels.
+ * </pre>
+ */
+ public static final int VTS_PROFILING_TYPE_UNLABELED_VECTOR_VALUE = 3;
+
+
+ public final int getNumber() { return value; }
+
+ public static VtsProfilingType valueOf(int value) {
+ switch (value) {
+ case 0: return UNKNOWN_VTS_PROFILING_TYPE;
+ case 1: return VTS_PROFILING_TYPE_TIMESTAMP;
+ case 2: return VTS_PROFILING_TYPE_LABELED_VECTOR;
+ case 3: return VTS_PROFILING_TYPE_UNLABELED_VECTOR;
+ default: return null;
+ }
+ }
+
+ public static com.google.protobuf.Internal.EnumLiteMap<VtsProfilingType>
+ internalGetValueMap() {
+ return internalValueMap;
+ }
+ private static com.google.protobuf.Internal.EnumLiteMap<VtsProfilingType>
+ internalValueMap =
+ new com.google.protobuf.Internal.EnumLiteMap<VtsProfilingType>() {
+ public VtsProfilingType findValueByNumber(int number) {
+ return VtsProfilingType.valueOf(number);
+ }
+ };
+
+ public final com.google.protobuf.Descriptors.EnumValueDescriptor
+ getValueDescriptor() {
+ return getDescriptor().getValues().get(index);
+ }
+ public final com.google.protobuf.Descriptors.EnumDescriptor
+ getDescriptorForType() {
+ return getDescriptor();
+ }
+ public static final com.google.protobuf.Descriptors.EnumDescriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.getDescriptor().getEnumTypes().get(3);
+ }
+
+ private static final VtsProfilingType[] VALUES = values();
+
+ public static VtsProfilingType valueOf(
+ com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+ if (desc.getType() != getDescriptor()) {
+ throw new java.lang.IllegalArgumentException(
+ "EnumValueDescriptor is not for this type.");
+ }
+ return VALUES[desc.getIndex()];
+ }
+
+ private final int index;
+ private final int value;
+
+ private VtsProfilingType(int index, int value) {
+ this.index = index;
+ this.value = value;
+ }
+
+ // @@protoc_insertion_point(enum_scope:android.vts.VtsProfilingType)
+ }
+
+ public interface AndroidDeviceInfoMessageOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional bytes product_type = 1;
+ /**
+ * <code>optional bytes product_type = 1;</code>
+ *
+ * <pre>
+ * product type (e.g., bullhead).
+ * </pre>
+ */
+ boolean hasProductType();
+ /**
+ * <code>optional bytes product_type = 1;</code>
+ *
+ * <pre>
+ * product type (e.g., bullhead).
+ * </pre>
+ */
+ com.google.protobuf.ByteString getProductType();
+
+ // optional bytes product_variant = 2;
+ /**
+ * <code>optional bytes product_variant = 2;</code>
+ *
+ * <pre>
+ * product type variant (e.g., still bullhead or another name).
+ * </pre>
+ */
+ boolean hasProductVariant();
+ /**
+ * <code>optional bytes product_variant = 2;</code>
+ *
+ * <pre>
+ * product type variant (e.g., still bullhead or another name).
+ * </pre>
+ */
+ com.google.protobuf.ByteString getProductVariant();
+
+ // optional bytes build_flavor = 11;
+ /**
+ * <code>optional bytes build_flavor = 11;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug).
+ * </pre>
+ */
+ boolean hasBuildFlavor();
+ /**
+ * <code>optional bytes build_flavor = 11;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug).
+ * </pre>
+ */
+ com.google.protobuf.ByteString getBuildFlavor();
+
+ // optional bytes build_id = 12;
+ /**
+ * <code>optional bytes build_id = 12;</code>
+ *
+ * <pre>
+ * Android Build ID.
+ * </pre>
+ */
+ boolean hasBuildId();
+ /**
+ * <code>optional bytes build_id = 12;</code>
+ *
+ * <pre>
+ * Android Build ID.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getBuildId();
+
+ // optional bytes branch = 21;
+ /**
+ * <code>optional bytes branch = 21;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev).
+ * </pre>
+ */
+ boolean hasBranch();
+ /**
+ * <code>optional bytes branch = 21;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev).
+ * </pre>
+ */
+ com.google.protobuf.ByteString getBranch();
+
+ // optional bytes build_alias = 22;
+ /**
+ * <code>optional bytes build_alias = 22;</code>
+ *
+ * <pre>
+ * build alias implies the branch name.
+ * </pre>
+ */
+ boolean hasBuildAlias();
+ /**
+ * <code>optional bytes build_alias = 22;</code>
+ *
+ * <pre>
+ * build alias implies the branch name.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getBuildAlias();
+
+ // optional bytes api_level = 31;
+ /**
+ * <code>optional bytes api_level = 31;</code>
+ *
+ * <pre>
+ * API level
+ * </pre>
+ */
+ boolean hasApiLevel();
+ /**
+ * <code>optional bytes api_level = 31;</code>
+ *
+ * <pre>
+ * API level
+ * </pre>
+ */
+ com.google.protobuf.ByteString getApiLevel();
+
+ // optional bytes abi_name = 51;
+ /**
+ * <code>optional bytes abi_name = 51;</code>
+ *
+ * <pre>
+ * ABI name that is current in use for the test
+ * </pre>
+ */
+ boolean hasAbiName();
+ /**
+ * <code>optional bytes abi_name = 51;</code>
+ *
+ * <pre>
+ * ABI name that is current in use for the test
+ * </pre>
+ */
+ com.google.protobuf.ByteString getAbiName();
+
+ // optional bytes abi_bitness = 52;
+ /**
+ * <code>optional bytes abi_bitness = 52;</code>
+ *
+ * <pre>
+ * ABI bitness that is current in use for the test. Example: '32', '64',
+ * </pre>
+ */
+ boolean hasAbiBitness();
+ /**
+ * <code>optional bytes abi_bitness = 52;</code>
+ *
+ * <pre>
+ * ABI bitness that is current in use for the test. Example: '32', '64',
+ * </pre>
+ */
+ com.google.protobuf.ByteString getAbiBitness();
+
+ // optional bytes serial = 101;
+ /**
+ * <code>optional bytes serial = 101;</code>
+ *
+ * <pre>
+ * Device USB serial number
+ * </pre>
+ */
+ boolean hasSerial();
+ /**
+ * <code>optional bytes serial = 101;</code>
+ *
+ * <pre>
+ * Device USB serial number
+ * </pre>
+ */
+ com.google.protobuf.ByteString getSerial();
+ }
+ /**
+ * Protobuf type {@code android.vts.AndroidDeviceInfoMessage}
+ *
+ * <pre>
+ * To specify a call flow event.
+ * </pre>
+ */
+ public static final class AndroidDeviceInfoMessage extends
+ com.google.protobuf.GeneratedMessage
+ implements AndroidDeviceInfoMessageOrBuilder {
+ // Use AndroidDeviceInfoMessage.newBuilder() to construct.
+ private AndroidDeviceInfoMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private AndroidDeviceInfoMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final AndroidDeviceInfoMessage defaultInstance;
+ public static AndroidDeviceInfoMessage getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public AndroidDeviceInfoMessage getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private AndroidDeviceInfoMessage(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ productType_ = input.readBytes();
+ break;
+ }
+ case 18: {
+ bitField0_ |= 0x00000002;
+ productVariant_ = input.readBytes();
+ break;
+ }
+ case 90: {
+ bitField0_ |= 0x00000004;
+ buildFlavor_ = input.readBytes();
+ break;
+ }
+ case 98: {
+ bitField0_ |= 0x00000008;
+ buildId_ = input.readBytes();
+ break;
+ }
+ case 170: {
+ bitField0_ |= 0x00000010;
+ branch_ = input.readBytes();
+ break;
+ }
+ case 178: {
+ bitField0_ |= 0x00000020;
+ buildAlias_ = input.readBytes();
+ break;
+ }
+ case 250: {
+ bitField0_ |= 0x00000040;
+ apiLevel_ = input.readBytes();
+ break;
+ }
+ case 410: {
+ bitField0_ |= 0x00000080;
+ abiName_ = input.readBytes();
+ break;
+ }
+ case 418: {
+ bitField0_ |= 0x00000100;
+ abiBitness_ = input.readBytes();
+ break;
+ }
+ case 810: {
+ bitField0_ |= 0x00000200;
+ serial_ = input.readBytes();
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidDeviceInfoMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidDeviceInfoMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.class, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<AndroidDeviceInfoMessage> PARSER =
+ new com.google.protobuf.AbstractParser<AndroidDeviceInfoMessage>() {
+ public AndroidDeviceInfoMessage parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new AndroidDeviceInfoMessage(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<AndroidDeviceInfoMessage> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional bytes product_type = 1;
+ public static final int PRODUCT_TYPE_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString productType_;
+ /**
+ * <code>optional bytes product_type = 1;</code>
+ *
+ * <pre>
+ * product type (e.g., bullhead).
+ * </pre>
+ */
+ public boolean hasProductType() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes product_type = 1;</code>
+ *
+ * <pre>
+ * product type (e.g., bullhead).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getProductType() {
+ return productType_;
+ }
+
+ // optional bytes product_variant = 2;
+ public static final int PRODUCT_VARIANT_FIELD_NUMBER = 2;
+ private com.google.protobuf.ByteString productVariant_;
+ /**
+ * <code>optional bytes product_variant = 2;</code>
+ *
+ * <pre>
+ * product type variant (e.g., still bullhead or another name).
+ * </pre>
+ */
+ public boolean hasProductVariant() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes product_variant = 2;</code>
+ *
+ * <pre>
+ * product type variant (e.g., still bullhead or another name).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getProductVariant() {
+ return productVariant_;
+ }
+
+ // optional bytes build_flavor = 11;
+ public static final int BUILD_FLAVOR_FIELD_NUMBER = 11;
+ private com.google.protobuf.ByteString buildFlavor_;
+ /**
+ * <code>optional bytes build_flavor = 11;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug).
+ * </pre>
+ */
+ public boolean hasBuildFlavor() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional bytes build_flavor = 11;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBuildFlavor() {
+ return buildFlavor_;
+ }
+
+ // optional bytes build_id = 12;
+ public static final int BUILD_ID_FIELD_NUMBER = 12;
+ private com.google.protobuf.ByteString buildId_;
+ /**
+ * <code>optional bytes build_id = 12;</code>
+ *
+ * <pre>
+ * Android Build ID.
+ * </pre>
+ */
+ public boolean hasBuildId() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional bytes build_id = 12;</code>
+ *
+ * <pre>
+ * Android Build ID.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBuildId() {
+ return buildId_;
+ }
+
+ // optional bytes branch = 21;
+ public static final int BRANCH_FIELD_NUMBER = 21;
+ private com.google.protobuf.ByteString branch_;
+ /**
+ * <code>optional bytes branch = 21;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev).
+ * </pre>
+ */
+ public boolean hasBranch() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * <code>optional bytes branch = 21;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBranch() {
+ return branch_;
+ }
+
+ // optional bytes build_alias = 22;
+ public static final int BUILD_ALIAS_FIELD_NUMBER = 22;
+ private com.google.protobuf.ByteString buildAlias_;
+ /**
+ * <code>optional bytes build_alias = 22;</code>
+ *
+ * <pre>
+ * build alias implies the branch name.
+ * </pre>
+ */
+ public boolean hasBuildAlias() {
+ return ((bitField0_ & 0x00000020) == 0x00000020);
+ }
+ /**
+ * <code>optional bytes build_alias = 22;</code>
+ *
+ * <pre>
+ * build alias implies the branch name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBuildAlias() {
+ return buildAlias_;
+ }
+
+ // optional bytes api_level = 31;
+ public static final int API_LEVEL_FIELD_NUMBER = 31;
+ private com.google.protobuf.ByteString apiLevel_;
+ /**
+ * <code>optional bytes api_level = 31;</code>
+ *
+ * <pre>
+ * API level
+ * </pre>
+ */
+ public boolean hasApiLevel() {
+ return ((bitField0_ & 0x00000040) == 0x00000040);
+ }
+ /**
+ * <code>optional bytes api_level = 31;</code>
+ *
+ * <pre>
+ * API level
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getApiLevel() {
+ return apiLevel_;
+ }
+
+ // optional bytes abi_name = 51;
+ public static final int ABI_NAME_FIELD_NUMBER = 51;
+ private com.google.protobuf.ByteString abiName_;
+ /**
+ * <code>optional bytes abi_name = 51;</code>
+ *
+ * <pre>
+ * ABI name that is current in use for the test
+ * </pre>
+ */
+ public boolean hasAbiName() {
+ return ((bitField0_ & 0x00000080) == 0x00000080);
+ }
+ /**
+ * <code>optional bytes abi_name = 51;</code>
+ *
+ * <pre>
+ * ABI name that is current in use for the test
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getAbiName() {
+ return abiName_;
+ }
+
+ // optional bytes abi_bitness = 52;
+ public static final int ABI_BITNESS_FIELD_NUMBER = 52;
+ private com.google.protobuf.ByteString abiBitness_;
+ /**
+ * <code>optional bytes abi_bitness = 52;</code>
+ *
+ * <pre>
+ * ABI bitness that is current in use for the test. Example: '32', '64',
+ * </pre>
+ */
+ public boolean hasAbiBitness() {
+ return ((bitField0_ & 0x00000100) == 0x00000100);
+ }
+ /**
+ * <code>optional bytes abi_bitness = 52;</code>
+ *
+ * <pre>
+ * ABI bitness that is current in use for the test. Example: '32', '64',
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getAbiBitness() {
+ return abiBitness_;
+ }
+
+ // optional bytes serial = 101;
+ public static final int SERIAL_FIELD_NUMBER = 101;
+ private com.google.protobuf.ByteString serial_;
+ /**
+ * <code>optional bytes serial = 101;</code>
+ *
+ * <pre>
+ * Device USB serial number
+ * </pre>
+ */
+ public boolean hasSerial() {
+ return ((bitField0_ & 0x00000200) == 0x00000200);
+ }
+ /**
+ * <code>optional bytes serial = 101;</code>
+ *
+ * <pre>
+ * Device USB serial number
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getSerial() {
+ return serial_;
+ }
+
+ private void initFields() {
+ productType_ = com.google.protobuf.ByteString.EMPTY;
+ productVariant_ = com.google.protobuf.ByteString.EMPTY;
+ buildFlavor_ = com.google.protobuf.ByteString.EMPTY;
+ buildId_ = com.google.protobuf.ByteString.EMPTY;
+ branch_ = com.google.protobuf.ByteString.EMPTY;
+ buildAlias_ = com.google.protobuf.ByteString.EMPTY;
+ apiLevel_ = com.google.protobuf.ByteString.EMPTY;
+ abiName_ = com.google.protobuf.ByteString.EMPTY;
+ abiBitness_ = com.google.protobuf.ByteString.EMPTY;
+ serial_ = com.google.protobuf.ByteString.EMPTY;
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, productType_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeBytes(2, productVariant_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeBytes(11, buildFlavor_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ output.writeBytes(12, buildId_);
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ output.writeBytes(21, branch_);
+ }
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ output.writeBytes(22, buildAlias_);
+ }
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ output.writeBytes(31, apiLevel_);
+ }
+ if (((bitField0_ & 0x00000080) == 0x00000080)) {
+ output.writeBytes(51, abiName_);
+ }
+ if (((bitField0_ & 0x00000100) == 0x00000100)) {
+ output.writeBytes(52, abiBitness_);
+ }
+ if (((bitField0_ & 0x00000200) == 0x00000200)) {
+ output.writeBytes(101, serial_);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, productType_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(2, productVariant_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(11, buildFlavor_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(12, buildId_);
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(21, branch_);
+ }
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(22, buildAlias_);
+ }
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(31, apiLevel_);
+ }
+ if (((bitField0_ & 0x00000080) == 0x00000080)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(51, abiName_);
+ }
+ if (((bitField0_ & 0x00000100) == 0x00000100)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(52, abiBitness_);
+ }
+ if (((bitField0_ & 0x00000200) == 0x00000200)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(101, serial_);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.AndroidDeviceInfoMessage}
+ *
+ * <pre>
+ * To specify a call flow event.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidDeviceInfoMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidDeviceInfoMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.class, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ productType_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ productVariant_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ buildFlavor_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ buildId_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000008);
+ branch_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000010);
+ buildAlias_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000020);
+ apiLevel_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000040);
+ abiName_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000080);
+ abiBitness_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000100);
+ serial_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000200);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidDeviceInfoMessage_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage build() {
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage buildPartial() {
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage result = new com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.productType_ = productType_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.productVariant_ = productVariant_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.buildFlavor_ = buildFlavor_;
+ if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+ to_bitField0_ |= 0x00000008;
+ }
+ result.buildId_ = buildId_;
+ if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+ to_bitField0_ |= 0x00000010;
+ }
+ result.branch_ = branch_;
+ if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+ to_bitField0_ |= 0x00000020;
+ }
+ result.buildAlias_ = buildAlias_;
+ if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+ to_bitField0_ |= 0x00000040;
+ }
+ result.apiLevel_ = apiLevel_;
+ if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
+ to_bitField0_ |= 0x00000080;
+ }
+ result.abiName_ = abiName_;
+ if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
+ to_bitField0_ |= 0x00000100;
+ }
+ result.abiBitness_ = abiBitness_;
+ if (((from_bitField0_ & 0x00000200) == 0x00000200)) {
+ to_bitField0_ |= 0x00000200;
+ }
+ result.serial_ = serial_;
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage other) {
+ if (other == com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.getDefaultInstance()) return this;
+ if (other.hasProductType()) {
+ setProductType(other.getProductType());
+ }
+ if (other.hasProductVariant()) {
+ setProductVariant(other.getProductVariant());
+ }
+ if (other.hasBuildFlavor()) {
+ setBuildFlavor(other.getBuildFlavor());
+ }
+ if (other.hasBuildId()) {
+ setBuildId(other.getBuildId());
+ }
+ if (other.hasBranch()) {
+ setBranch(other.getBranch());
+ }
+ if (other.hasBuildAlias()) {
+ setBuildAlias(other.getBuildAlias());
+ }
+ if (other.hasApiLevel()) {
+ setApiLevel(other.getApiLevel());
+ }
+ if (other.hasAbiName()) {
+ setAbiName(other.getAbiName());
+ }
+ if (other.hasAbiBitness()) {
+ setAbiBitness(other.getAbiBitness());
+ }
+ if (other.hasSerial()) {
+ setSerial(other.getSerial());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional bytes product_type = 1;
+ private com.google.protobuf.ByteString productType_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes product_type = 1;</code>
+ *
+ * <pre>
+ * product type (e.g., bullhead).
+ * </pre>
+ */
+ public boolean hasProductType() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes product_type = 1;</code>
+ *
+ * <pre>
+ * product type (e.g., bullhead).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getProductType() {
+ return productType_;
+ }
+ /**
+ * <code>optional bytes product_type = 1;</code>
+ *
+ * <pre>
+ * product type (e.g., bullhead).
+ * </pre>
+ */
+ public Builder setProductType(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ productType_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes product_type = 1;</code>
+ *
+ * <pre>
+ * product type (e.g., bullhead).
+ * </pre>
+ */
+ public Builder clearProductType() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ productType_ = getDefaultInstance().getProductType();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes product_variant = 2;
+ private com.google.protobuf.ByteString productVariant_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes product_variant = 2;</code>
+ *
+ * <pre>
+ * product type variant (e.g., still bullhead or another name).
+ * </pre>
+ */
+ public boolean hasProductVariant() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes product_variant = 2;</code>
+ *
+ * <pre>
+ * product type variant (e.g., still bullhead or another name).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getProductVariant() {
+ return productVariant_;
+ }
+ /**
+ * <code>optional bytes product_variant = 2;</code>
+ *
+ * <pre>
+ * product type variant (e.g., still bullhead or another name).
+ * </pre>
+ */
+ public Builder setProductVariant(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000002;
+ productVariant_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes product_variant = 2;</code>
+ *
+ * <pre>
+ * product type variant (e.g., still bullhead or another name).
+ * </pre>
+ */
+ public Builder clearProductVariant() {
+ bitField0_ = (bitField0_ & ~0x00000002);
+ productVariant_ = getDefaultInstance().getProductVariant();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes build_flavor = 11;
+ private com.google.protobuf.ByteString buildFlavor_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes build_flavor = 11;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug).
+ * </pre>
+ */
+ public boolean hasBuildFlavor() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional bytes build_flavor = 11;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBuildFlavor() {
+ return buildFlavor_;
+ }
+ /**
+ * <code>optional bytes build_flavor = 11;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug).
+ * </pre>
+ */
+ public Builder setBuildFlavor(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000004;
+ buildFlavor_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes build_flavor = 11;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug).
+ * </pre>
+ */
+ public Builder clearBuildFlavor() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ buildFlavor_ = getDefaultInstance().getBuildFlavor();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes build_id = 12;
+ private com.google.protobuf.ByteString buildId_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes build_id = 12;</code>
+ *
+ * <pre>
+ * Android Build ID.
+ * </pre>
+ */
+ public boolean hasBuildId() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional bytes build_id = 12;</code>
+ *
+ * <pre>
+ * Android Build ID.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBuildId() {
+ return buildId_;
+ }
+ /**
+ * <code>optional bytes build_id = 12;</code>
+ *
+ * <pre>
+ * Android Build ID.
+ * </pre>
+ */
+ public Builder setBuildId(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000008;
+ buildId_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes build_id = 12;</code>
+ *
+ * <pre>
+ * Android Build ID.
+ * </pre>
+ */
+ public Builder clearBuildId() {
+ bitField0_ = (bitField0_ & ~0x00000008);
+ buildId_ = getDefaultInstance().getBuildId();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes branch = 21;
+ private com.google.protobuf.ByteString branch_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes branch = 21;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev).
+ * </pre>
+ */
+ public boolean hasBranch() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * <code>optional bytes branch = 21;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBranch() {
+ return branch_;
+ }
+ /**
+ * <code>optional bytes branch = 21;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev).
+ * </pre>
+ */
+ public Builder setBranch(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000010;
+ branch_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes branch = 21;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev).
+ * </pre>
+ */
+ public Builder clearBranch() {
+ bitField0_ = (bitField0_ & ~0x00000010);
+ branch_ = getDefaultInstance().getBranch();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes build_alias = 22;
+ private com.google.protobuf.ByteString buildAlias_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes build_alias = 22;</code>
+ *
+ * <pre>
+ * build alias implies the branch name.
+ * </pre>
+ */
+ public boolean hasBuildAlias() {
+ return ((bitField0_ & 0x00000020) == 0x00000020);
+ }
+ /**
+ * <code>optional bytes build_alias = 22;</code>
+ *
+ * <pre>
+ * build alias implies the branch name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBuildAlias() {
+ return buildAlias_;
+ }
+ /**
+ * <code>optional bytes build_alias = 22;</code>
+ *
+ * <pre>
+ * build alias implies the branch name.
+ * </pre>
+ */
+ public Builder setBuildAlias(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000020;
+ buildAlias_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes build_alias = 22;</code>
+ *
+ * <pre>
+ * build alias implies the branch name.
+ * </pre>
+ */
+ public Builder clearBuildAlias() {
+ bitField0_ = (bitField0_ & ~0x00000020);
+ buildAlias_ = getDefaultInstance().getBuildAlias();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes api_level = 31;
+ private com.google.protobuf.ByteString apiLevel_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes api_level = 31;</code>
+ *
+ * <pre>
+ * API level
+ * </pre>
+ */
+ public boolean hasApiLevel() {
+ return ((bitField0_ & 0x00000040) == 0x00000040);
+ }
+ /**
+ * <code>optional bytes api_level = 31;</code>
+ *
+ * <pre>
+ * API level
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getApiLevel() {
+ return apiLevel_;
+ }
+ /**
+ * <code>optional bytes api_level = 31;</code>
+ *
+ * <pre>
+ * API level
+ * </pre>
+ */
+ public Builder setApiLevel(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000040;
+ apiLevel_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes api_level = 31;</code>
+ *
+ * <pre>
+ * API level
+ * </pre>
+ */
+ public Builder clearApiLevel() {
+ bitField0_ = (bitField0_ & ~0x00000040);
+ apiLevel_ = getDefaultInstance().getApiLevel();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes abi_name = 51;
+ private com.google.protobuf.ByteString abiName_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes abi_name = 51;</code>
+ *
+ * <pre>
+ * ABI name that is current in use for the test
+ * </pre>
+ */
+ public boolean hasAbiName() {
+ return ((bitField0_ & 0x00000080) == 0x00000080);
+ }
+ /**
+ * <code>optional bytes abi_name = 51;</code>
+ *
+ * <pre>
+ * ABI name that is current in use for the test
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getAbiName() {
+ return abiName_;
+ }
+ /**
+ * <code>optional bytes abi_name = 51;</code>
+ *
+ * <pre>
+ * ABI name that is current in use for the test
+ * </pre>
+ */
+ public Builder setAbiName(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000080;
+ abiName_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes abi_name = 51;</code>
+ *
+ * <pre>
+ * ABI name that is current in use for the test
+ * </pre>
+ */
+ public Builder clearAbiName() {
+ bitField0_ = (bitField0_ & ~0x00000080);
+ abiName_ = getDefaultInstance().getAbiName();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes abi_bitness = 52;
+ private com.google.protobuf.ByteString abiBitness_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes abi_bitness = 52;</code>
+ *
+ * <pre>
+ * ABI bitness that is current in use for the test. Example: '32', '64',
+ * </pre>
+ */
+ public boolean hasAbiBitness() {
+ return ((bitField0_ & 0x00000100) == 0x00000100);
+ }
+ /**
+ * <code>optional bytes abi_bitness = 52;</code>
+ *
+ * <pre>
+ * ABI bitness that is current in use for the test. Example: '32', '64',
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getAbiBitness() {
+ return abiBitness_;
+ }
+ /**
+ * <code>optional bytes abi_bitness = 52;</code>
+ *
+ * <pre>
+ * ABI bitness that is current in use for the test. Example: '32', '64',
+ * </pre>
+ */
+ public Builder setAbiBitness(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000100;
+ abiBitness_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes abi_bitness = 52;</code>
+ *
+ * <pre>
+ * ABI bitness that is current in use for the test. Example: '32', '64',
+ * </pre>
+ */
+ public Builder clearAbiBitness() {
+ bitField0_ = (bitField0_ & ~0x00000100);
+ abiBitness_ = getDefaultInstance().getAbiBitness();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes serial = 101;
+ private com.google.protobuf.ByteString serial_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes serial = 101;</code>
+ *
+ * <pre>
+ * Device USB serial number
+ * </pre>
+ */
+ public boolean hasSerial() {
+ return ((bitField0_ & 0x00000200) == 0x00000200);
+ }
+ /**
+ * <code>optional bytes serial = 101;</code>
+ *
+ * <pre>
+ * Device USB serial number
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getSerial() {
+ return serial_;
+ }
+ /**
+ * <code>optional bytes serial = 101;</code>
+ *
+ * <pre>
+ * Device USB serial number
+ * </pre>
+ */
+ public Builder setSerial(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000200;
+ serial_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes serial = 101;</code>
+ *
+ * <pre>
+ * Device USB serial number
+ * </pre>
+ */
+ public Builder clearSerial() {
+ bitField0_ = (bitField0_ & ~0x00000200);
+ serial_ = getDefaultInstance().getSerial();
+ onChanged();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.AndroidDeviceInfoMessage)
+ }
+
+ static {
+ defaultInstance = new AndroidDeviceInfoMessage(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.AndroidDeviceInfoMessage)
+ }
+
+ public interface AndroidBuildInfoOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional bytes id = 1;
+ /**
+ * <code>optional bytes id = 1;</code>
+ *
+ * <pre>
+ * build ID.
+ * </pre>
+ */
+ boolean hasId();
+ /**
+ * <code>optional bytes id = 1;</code>
+ *
+ * <pre>
+ * build ID.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getId();
+
+ // optional bytes name = 11;
+ /**
+ * <code>optional bytes name = 11;</code>
+ *
+ * <pre>
+ * device name (e.g., bullhead).
+ * </pre>
+ */
+ boolean hasName();
+ /**
+ * <code>optional bytes name = 11;</code>
+ *
+ * <pre>
+ * device name (e.g., bullhead).
+ * </pre>
+ */
+ com.google.protobuf.ByteString getName();
+
+ // optional bytes build_type = 12;
+ /**
+ * <code>optional bytes build_type = 12;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug)
+ * </pre>
+ */
+ boolean hasBuildType();
+ /**
+ * <code>optional bytes build_type = 12;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug)
+ * </pre>
+ */
+ com.google.protobuf.ByteString getBuildType();
+
+ // optional bytes branch = 13;
+ /**
+ * <code>optional bytes branch = 13;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev)
+ * </pre>
+ */
+ boolean hasBranch();
+ /**
+ * <code>optional bytes branch = 13;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev)
+ * </pre>
+ */
+ com.google.protobuf.ByteString getBranch();
+
+ // optional bytes build_summary = 21;
+ /**
+ * <code>optional bytes build_summary = 21;</code>
+ *
+ * <pre>
+ * indicates the latest commit information of each branch (e.g., xml format).
+ * </pre>
+ */
+ boolean hasBuildSummary();
+ /**
+ * <code>optional bytes build_summary = 21;</code>
+ *
+ * <pre>
+ * indicates the latest commit information of each branch (e.g., xml format).
+ * </pre>
+ */
+ com.google.protobuf.ByteString getBuildSummary();
+ }
+ /**
+ * Protobuf type {@code android.vts.AndroidBuildInfo}
+ *
+ * <pre>
+ * To specify build info.
+ * </pre>
+ */
+ public static final class AndroidBuildInfo extends
+ com.google.protobuf.GeneratedMessage
+ implements AndroidBuildInfoOrBuilder {
+ // Use AndroidBuildInfo.newBuilder() to construct.
+ private AndroidBuildInfo(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private AndroidBuildInfo(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final AndroidBuildInfo defaultInstance;
+ public static AndroidBuildInfo getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public AndroidBuildInfo getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private AndroidBuildInfo(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ id_ = input.readBytes();
+ break;
+ }
+ case 90: {
+ bitField0_ |= 0x00000002;
+ name_ = input.readBytes();
+ break;
+ }
+ case 98: {
+ bitField0_ |= 0x00000004;
+ buildType_ = input.readBytes();
+ break;
+ }
+ case 106: {
+ bitField0_ |= 0x00000008;
+ branch_ = input.readBytes();
+ break;
+ }
+ case 170: {
+ bitField0_ |= 0x00000010;
+ buildSummary_ = input.readBytes();
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidBuildInfo_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidBuildInfo_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.class, com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<AndroidBuildInfo> PARSER =
+ new com.google.protobuf.AbstractParser<AndroidBuildInfo>() {
+ public AndroidBuildInfo parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new AndroidBuildInfo(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<AndroidBuildInfo> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional bytes id = 1;
+ public static final int ID_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString id_;
+ /**
+ * <code>optional bytes id = 1;</code>
+ *
+ * <pre>
+ * build ID.
+ * </pre>
+ */
+ public boolean hasId() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes id = 1;</code>
+ *
+ * <pre>
+ * build ID.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getId() {
+ return id_;
+ }
+
+ // optional bytes name = 11;
+ public static final int NAME_FIELD_NUMBER = 11;
+ private com.google.protobuf.ByteString name_;
+ /**
+ * <code>optional bytes name = 11;</code>
+ *
+ * <pre>
+ * device name (e.g., bullhead).
+ * </pre>
+ */
+ public boolean hasName() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes name = 11;</code>
+ *
+ * <pre>
+ * device name (e.g., bullhead).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getName() {
+ return name_;
+ }
+
+ // optional bytes build_type = 12;
+ public static final int BUILD_TYPE_FIELD_NUMBER = 12;
+ private com.google.protobuf.ByteString buildType_;
+ /**
+ * <code>optional bytes build_type = 12;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug)
+ * </pre>
+ */
+ public boolean hasBuildType() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional bytes build_type = 12;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug)
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBuildType() {
+ return buildType_;
+ }
+
+ // optional bytes branch = 13;
+ public static final int BRANCH_FIELD_NUMBER = 13;
+ private com.google.protobuf.ByteString branch_;
+ /**
+ * <code>optional bytes branch = 13;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev)
+ * </pre>
+ */
+ public boolean hasBranch() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional bytes branch = 13;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev)
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBranch() {
+ return branch_;
+ }
+
+ // optional bytes build_summary = 21;
+ public static final int BUILD_SUMMARY_FIELD_NUMBER = 21;
+ private com.google.protobuf.ByteString buildSummary_;
+ /**
+ * <code>optional bytes build_summary = 21;</code>
+ *
+ * <pre>
+ * indicates the latest commit information of each branch (e.g., xml format).
+ * </pre>
+ */
+ public boolean hasBuildSummary() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * <code>optional bytes build_summary = 21;</code>
+ *
+ * <pre>
+ * indicates the latest commit information of each branch (e.g., xml format).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBuildSummary() {
+ return buildSummary_;
+ }
+
+ private void initFields() {
+ id_ = com.google.protobuf.ByteString.EMPTY;
+ name_ = com.google.protobuf.ByteString.EMPTY;
+ buildType_ = com.google.protobuf.ByteString.EMPTY;
+ branch_ = com.google.protobuf.ByteString.EMPTY;
+ buildSummary_ = com.google.protobuf.ByteString.EMPTY;
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, id_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeBytes(11, name_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeBytes(12, buildType_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ output.writeBytes(13, branch_);
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ output.writeBytes(21, buildSummary_);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, id_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(11, name_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(12, buildType_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(13, branch_);
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(21, buildSummary_);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.AndroidBuildInfo prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.AndroidBuildInfo}
+ *
+ * <pre>
+ * To specify build info.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidBuildInfo_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidBuildInfo_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.class, com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ id_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ name_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ buildType_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ branch_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000008);
+ buildSummary_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000010);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidBuildInfo_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo build() {
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo buildPartial() {
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo result = new com.android.vts.proto.VtsReportMessage.AndroidBuildInfo(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.id_ = id_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.name_ = name_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.buildType_ = buildType_;
+ if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+ to_bitField0_ |= 0x00000008;
+ }
+ result.branch_ = branch_;
+ if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+ to_bitField0_ |= 0x00000010;
+ }
+ result.buildSummary_ = buildSummary_;
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.AndroidBuildInfo) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.AndroidBuildInfo)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.AndroidBuildInfo other) {
+ if (other == com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance()) return this;
+ if (other.hasId()) {
+ setId(other.getId());
+ }
+ if (other.hasName()) {
+ setName(other.getName());
+ }
+ if (other.hasBuildType()) {
+ setBuildType(other.getBuildType());
+ }
+ if (other.hasBranch()) {
+ setBranch(other.getBranch());
+ }
+ if (other.hasBuildSummary()) {
+ setBuildSummary(other.getBuildSummary());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.AndroidBuildInfo) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional bytes id = 1;
+ private com.google.protobuf.ByteString id_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes id = 1;</code>
+ *
+ * <pre>
+ * build ID.
+ * </pre>
+ */
+ public boolean hasId() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes id = 1;</code>
+ *
+ * <pre>
+ * build ID.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getId() {
+ return id_;
+ }
+ /**
+ * <code>optional bytes id = 1;</code>
+ *
+ * <pre>
+ * build ID.
+ * </pre>
+ */
+ public Builder setId(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ id_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes id = 1;</code>
+ *
+ * <pre>
+ * build ID.
+ * </pre>
+ */
+ public Builder clearId() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ id_ = getDefaultInstance().getId();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes name = 11;
+ private com.google.protobuf.ByteString name_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes name = 11;</code>
+ *
+ * <pre>
+ * device name (e.g., bullhead).
+ * </pre>
+ */
+ public boolean hasName() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes name = 11;</code>
+ *
+ * <pre>
+ * device name (e.g., bullhead).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getName() {
+ return name_;
+ }
+ /**
+ * <code>optional bytes name = 11;</code>
+ *
+ * <pre>
+ * device name (e.g., bullhead).
+ * </pre>
+ */
+ public Builder setName(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000002;
+ name_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes name = 11;</code>
+ *
+ * <pre>
+ * device name (e.g., bullhead).
+ * </pre>
+ */
+ public Builder clearName() {
+ bitField0_ = (bitField0_ & ~0x00000002);
+ name_ = getDefaultInstance().getName();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes build_type = 12;
+ private com.google.protobuf.ByteString buildType_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes build_type = 12;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug)
+ * </pre>
+ */
+ public boolean hasBuildType() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional bytes build_type = 12;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug)
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBuildType() {
+ return buildType_;
+ }
+ /**
+ * <code>optional bytes build_type = 12;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug)
+ * </pre>
+ */
+ public Builder setBuildType(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000004;
+ buildType_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes build_type = 12;</code>
+ *
+ * <pre>
+ * build type (e.g., userdebug)
+ * </pre>
+ */
+ public Builder clearBuildType() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ buildType_ = getDefaultInstance().getBuildType();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes branch = 13;
+ private com.google.protobuf.ByteString branch_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes branch = 13;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev)
+ * </pre>
+ */
+ public boolean hasBranch() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional bytes branch = 13;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev)
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBranch() {
+ return branch_;
+ }
+ /**
+ * <code>optional bytes branch = 13;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev)
+ * </pre>
+ */
+ public Builder setBranch(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000008;
+ branch_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes branch = 13;</code>
+ *
+ * <pre>
+ * branch name (e.g., master or nyc-dev)
+ * </pre>
+ */
+ public Builder clearBranch() {
+ bitField0_ = (bitField0_ & ~0x00000008);
+ branch_ = getDefaultInstance().getBranch();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes build_summary = 21;
+ private com.google.protobuf.ByteString buildSummary_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes build_summary = 21;</code>
+ *
+ * <pre>
+ * indicates the latest commit information of each branch (e.g., xml format).
+ * </pre>
+ */
+ public boolean hasBuildSummary() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * <code>optional bytes build_summary = 21;</code>
+ *
+ * <pre>
+ * indicates the latest commit information of each branch (e.g., xml format).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getBuildSummary() {
+ return buildSummary_;
+ }
+ /**
+ * <code>optional bytes build_summary = 21;</code>
+ *
+ * <pre>
+ * indicates the latest commit information of each branch (e.g., xml format).
+ * </pre>
+ */
+ public Builder setBuildSummary(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000010;
+ buildSummary_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes build_summary = 21;</code>
+ *
+ * <pre>
+ * indicates the latest commit information of each branch (e.g., xml format).
+ * </pre>
+ */
+ public Builder clearBuildSummary() {
+ bitField0_ = (bitField0_ & ~0x00000010);
+ buildSummary_ = getDefaultInstance().getBuildSummary();
+ onChanged();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.AndroidBuildInfo)
+ }
+
+ static {
+ defaultInstance = new AndroidBuildInfo(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.AndroidBuildInfo)
+ }
+
+ public interface VtsHostInfoOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional bytes hostname = 1;
+ /**
+ * <code>optional bytes hostname = 1;</code>
+ *
+ * <pre>
+ * the host name (i.e., full domain name).
+ * </pre>
+ */
+ boolean hasHostname();
+ /**
+ * <code>optional bytes hostname = 1;</code>
+ *
+ * <pre>
+ * the host name (i.e., full domain name).
+ * </pre>
+ */
+ com.google.protobuf.ByteString getHostname();
+ }
+ /**
+ * Protobuf type {@code android.vts.VtsHostInfo}
+ *
+ * <pre>
+ * To specify the information about a host node.
+ * </pre>
+ */
+ public static final class VtsHostInfo extends
+ com.google.protobuf.GeneratedMessage
+ implements VtsHostInfoOrBuilder {
+ // Use VtsHostInfo.newBuilder() to construct.
+ private VtsHostInfo(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private VtsHostInfo(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final VtsHostInfo defaultInstance;
+ public static VtsHostInfo getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public VtsHostInfo getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private VtsHostInfo(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ hostname_ = input.readBytes();
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_VtsHostInfo_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_VtsHostInfo_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo.class, com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<VtsHostInfo> PARSER =
+ new com.google.protobuf.AbstractParser<VtsHostInfo>() {
+ public VtsHostInfo parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new VtsHostInfo(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<VtsHostInfo> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional bytes hostname = 1;
+ public static final int HOSTNAME_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString hostname_;
+ /**
+ * <code>optional bytes hostname = 1;</code>
+ *
+ * <pre>
+ * the host name (i.e., full domain name).
+ * </pre>
+ */
+ public boolean hasHostname() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes hostname = 1;</code>
+ *
+ * <pre>
+ * the host name (i.e., full domain name).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getHostname() {
+ return hostname_;
+ }
+
+ private void initFields() {
+ hostname_ = com.google.protobuf.ByteString.EMPTY;
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, hostname_);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, hostname_);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.VtsHostInfo prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.VtsHostInfo}
+ *
+ * <pre>
+ * To specify the information about a host node.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_VtsHostInfo_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_VtsHostInfo_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo.class, com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.VtsHostInfo.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ hostname_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_VtsHostInfo_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.VtsHostInfo getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.VtsHostInfo build() {
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.VtsHostInfo buildPartial() {
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo result = new com.android.vts.proto.VtsReportMessage.VtsHostInfo(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.hostname_ = hostname_;
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.VtsHostInfo) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.VtsHostInfo)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.VtsHostInfo other) {
+ if (other == com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance()) return this;
+ if (other.hasHostname()) {
+ setHostname(other.getHostname());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.VtsHostInfo) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional bytes hostname = 1;
+ private com.google.protobuf.ByteString hostname_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes hostname = 1;</code>
+ *
+ * <pre>
+ * the host name (i.e., full domain name).
+ * </pre>
+ */
+ public boolean hasHostname() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes hostname = 1;</code>
+ *
+ * <pre>
+ * the host name (i.e., full domain name).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getHostname() {
+ return hostname_;
+ }
+ /**
+ * <code>optional bytes hostname = 1;</code>
+ *
+ * <pre>
+ * the host name (i.e., full domain name).
+ * </pre>
+ */
+ public Builder setHostname(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ hostname_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes hostname = 1;</code>
+ *
+ * <pre>
+ * the host name (i.e., full domain name).
+ * </pre>
+ */
+ public Builder clearHostname() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ hostname_ = getDefaultInstance().getHostname();
+ onChanged();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.VtsHostInfo)
+ }
+
+ static {
+ defaultInstance = new VtsHostInfo(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.VtsHostInfo)
+ }
+
+ public interface TestCaseReportMessageOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional bytes name = 1;
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the test case name.
+ * </pre>
+ */
+ boolean hasName();
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the test case name.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getName();
+
+ // optional .android.vts.TestCaseResult test_result = 11;
+ /**
+ * <code>optional .android.vts.TestCaseResult test_result = 11;</code>
+ *
+ * <pre>
+ * the test result.
+ * </pre>
+ */
+ boolean hasTestResult();
+ /**
+ * <code>optional .android.vts.TestCaseResult test_result = 11;</code>
+ *
+ * <pre>
+ * the test result.
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.TestCaseResult getTestResult();
+
+ // optional int64 start_timestamp = 21;
+ /**
+ * <code>optional int64 start_timestamp = 21;</code>
+ *
+ * <pre>
+ * execution start and end time stamp.
+ * </pre>
+ */
+ boolean hasStartTimestamp();
+ /**
+ * <code>optional int64 start_timestamp = 21;</code>
+ *
+ * <pre>
+ * execution start and end time stamp.
+ * </pre>
+ */
+ long getStartTimestamp();
+
+ // optional int64 end_timestamp = 22;
+ /**
+ * <code>optional int64 end_timestamp = 22;</code>
+ */
+ boolean hasEndTimestamp();
+ /**
+ * <code>optional int64 end_timestamp = 22;</code>
+ */
+ long getEndTimestamp();
+
+ // repeated .android.vts.CoverageReportMessage coverage = 31;
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage>
+ getCoverageList();
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index);
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ int getCoverageCount();
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>
+ getCoverageOrBuilderList();
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder(
+ int index);
+
+ // repeated .android.vts.ProfilingReportMessage profiling = 41;
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage>
+ getProfilingList();
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index);
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ int getProfilingCount();
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>
+ getProfilingOrBuilderList();
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder(
+ int index);
+
+ // repeated .android.vts.SystraceReportMessage systrace = 42;
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage>
+ getSystraceList();
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index);
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ int getSystraceCount();
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>
+ getSystraceOrBuilderList();
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder(
+ int index);
+
+ // repeated .android.vts.LogMessage log = 101;
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage>
+ getLogList();
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index);
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ int getLogCount();
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>
+ getLogOrBuilderList();
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder(
+ int index);
+ }
+ /**
+ * Protobuf type {@code android.vts.TestCaseReportMessage}
+ *
+ * <pre>
+ * To specify a test case execution report.
+ * </pre>
+ */
+ public static final class TestCaseReportMessage extends
+ com.google.protobuf.GeneratedMessage
+ implements TestCaseReportMessageOrBuilder {
+ // Use TestCaseReportMessage.newBuilder() to construct.
+ private TestCaseReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private TestCaseReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final TestCaseReportMessage defaultInstance;
+ public static TestCaseReportMessage getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public TestCaseReportMessage getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private TestCaseReportMessage(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ name_ = input.readBytes();
+ break;
+ }
+ case 88: {
+ int rawValue = input.readEnum();
+ com.android.vts.proto.VtsReportMessage.TestCaseResult value = com.android.vts.proto.VtsReportMessage.TestCaseResult.valueOf(rawValue);
+ if (value == null) {
+ unknownFields.mergeVarintField(11, rawValue);
+ } else {
+ bitField0_ |= 0x00000002;
+ testResult_ = value;
+ }
+ break;
+ }
+ case 168: {
+ bitField0_ |= 0x00000004;
+ startTimestamp_ = input.readInt64();
+ break;
+ }
+ case 176: {
+ bitField0_ |= 0x00000008;
+ endTimestamp_ = input.readInt64();
+ break;
+ }
+ case 250: {
+ if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+ coverage_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.CoverageReportMessage>();
+ mutable_bitField0_ |= 0x00000010;
+ }
+ coverage_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.CoverageReportMessage.PARSER, extensionRegistry));
+ break;
+ }
+ case 330: {
+ if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+ profiling_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage>();
+ mutable_bitField0_ |= 0x00000020;
+ }
+ profiling_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.PARSER, extensionRegistry));
+ break;
+ }
+ case 338: {
+ if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
+ systrace_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.SystraceReportMessage>();
+ mutable_bitField0_ |= 0x00000040;
+ }
+ systrace_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.SystraceReportMessage.PARSER, extensionRegistry));
+ break;
+ }
+ case 810: {
+ if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
+ log_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.LogMessage>();
+ mutable_bitField0_ |= 0x00000080;
+ }
+ log_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.LogMessage.PARSER, extensionRegistry));
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+ coverage_ = java.util.Collections.unmodifiableList(coverage_);
+ }
+ if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+ profiling_ = java.util.Collections.unmodifiableList(profiling_);
+ }
+ if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
+ systrace_ = java.util.Collections.unmodifiableList(systrace_);
+ }
+ if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
+ log_ = java.util.Collections.unmodifiableList(log_);
+ }
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestCaseReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestCaseReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.class, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<TestCaseReportMessage> PARSER =
+ new com.google.protobuf.AbstractParser<TestCaseReportMessage>() {
+ public TestCaseReportMessage parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new TestCaseReportMessage(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<TestCaseReportMessage> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional bytes name = 1;
+ public static final int NAME_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString name_;
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the test case name.
+ * </pre>
+ */
+ public boolean hasName() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the test case name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getName() {
+ return name_;
+ }
+
+ // optional .android.vts.TestCaseResult test_result = 11;
+ public static final int TEST_RESULT_FIELD_NUMBER = 11;
+ private com.android.vts.proto.VtsReportMessage.TestCaseResult testResult_;
+ /**
+ * <code>optional .android.vts.TestCaseResult test_result = 11;</code>
+ *
+ * <pre>
+ * the test result.
+ * </pre>
+ */
+ public boolean hasTestResult() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional .android.vts.TestCaseResult test_result = 11;</code>
+ *
+ * <pre>
+ * the test result.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestCaseResult getTestResult() {
+ return testResult_;
+ }
+
+ // optional int64 start_timestamp = 21;
+ public static final int START_TIMESTAMP_FIELD_NUMBER = 21;
+ private long startTimestamp_;
+ /**
+ * <code>optional int64 start_timestamp = 21;</code>
+ *
+ * <pre>
+ * execution start and end time stamp.
+ * </pre>
+ */
+ public boolean hasStartTimestamp() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional int64 start_timestamp = 21;</code>
+ *
+ * <pre>
+ * execution start and end time stamp.
+ * </pre>
+ */
+ public long getStartTimestamp() {
+ return startTimestamp_;
+ }
+
+ // optional int64 end_timestamp = 22;
+ public static final int END_TIMESTAMP_FIELD_NUMBER = 22;
+ private long endTimestamp_;
+ /**
+ * <code>optional int64 end_timestamp = 22;</code>
+ */
+ public boolean hasEndTimestamp() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional int64 end_timestamp = 22;</code>
+ */
+ public long getEndTimestamp() {
+ return endTimestamp_;
+ }
+
+ // repeated .android.vts.CoverageReportMessage coverage = 31;
+ public static final int COVERAGE_FIELD_NUMBER = 31;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> coverage_;
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> getCoverageList() {
+ return coverage_;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>
+ getCoverageOrBuilderList() {
+ return coverage_;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public int getCoverageCount() {
+ return coverage_.size();
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index) {
+ return coverage_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder(
+ int index) {
+ return coverage_.get(index);
+ }
+
+ // repeated .android.vts.ProfilingReportMessage profiling = 41;
+ public static final int PROFILING_FIELD_NUMBER = 41;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> profiling_;
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> getProfilingList() {
+ return profiling_;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>
+ getProfilingOrBuilderList() {
+ return profiling_;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public int getProfilingCount() {
+ return profiling_.size();
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index) {
+ return profiling_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder(
+ int index) {
+ return profiling_.get(index);
+ }
+
+ // repeated .android.vts.SystraceReportMessage systrace = 42;
+ public static final int SYSTRACE_FIELD_NUMBER = 42;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> systrace_;
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> getSystraceList() {
+ return systrace_;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>
+ getSystraceOrBuilderList() {
+ return systrace_;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public int getSystraceCount() {
+ return systrace_.size();
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index) {
+ return systrace_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder(
+ int index) {
+ return systrace_.get(index);
+ }
+
+ // repeated .android.vts.LogMessage log = 101;
+ public static final int LOG_FIELD_NUMBER = 101;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> log_;
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> getLogList() {
+ return log_;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>
+ getLogOrBuilderList() {
+ return log_;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public int getLogCount() {
+ return log_.size();
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index) {
+ return log_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder(
+ int index) {
+ return log_.get(index);
+ }
+
+ private void initFields() {
+ name_ = com.google.protobuf.ByteString.EMPTY;
+ testResult_ = com.android.vts.proto.VtsReportMessage.TestCaseResult.UNKNOWN_RESULT;
+ startTimestamp_ = 0L;
+ endTimestamp_ = 0L;
+ coverage_ = java.util.Collections.emptyList();
+ profiling_ = java.util.Collections.emptyList();
+ systrace_ = java.util.Collections.emptyList();
+ log_ = java.util.Collections.emptyList();
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, name_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeEnum(11, testResult_.getNumber());
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeInt64(21, startTimestamp_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ output.writeInt64(22, endTimestamp_);
+ }
+ for (int i = 0; i < coverage_.size(); i++) {
+ output.writeMessage(31, coverage_.get(i));
+ }
+ for (int i = 0; i < profiling_.size(); i++) {
+ output.writeMessage(41, profiling_.get(i));
+ }
+ for (int i = 0; i < systrace_.size(); i++) {
+ output.writeMessage(42, systrace_.get(i));
+ }
+ for (int i = 0; i < log_.size(); i++) {
+ output.writeMessage(101, log_.get(i));
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, name_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeEnumSize(11, testResult_.getNumber());
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt64Size(21, startTimestamp_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt64Size(22, endTimestamp_);
+ }
+ for (int i = 0; i < coverage_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(31, coverage_.get(i));
+ }
+ for (int i = 0; i < profiling_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(41, profiling_.get(i));
+ }
+ for (int i = 0; i < systrace_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(42, systrace_.get(i));
+ }
+ for (int i = 0; i < log_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(101, log_.get(i));
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.TestCaseReportMessage prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.TestCaseReportMessage}
+ *
+ * <pre>
+ * To specify a test case execution report.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestCaseReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestCaseReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.class, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ getCoverageFieldBuilder();
+ getProfilingFieldBuilder();
+ getSystraceFieldBuilder();
+ getLogFieldBuilder();
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ name_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ testResult_ = com.android.vts.proto.VtsReportMessage.TestCaseResult.UNKNOWN_RESULT;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ startTimestamp_ = 0L;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ endTimestamp_ = 0L;
+ bitField0_ = (bitField0_ & ~0x00000008);
+ if (coverageBuilder_ == null) {
+ coverage_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000010);
+ } else {
+ coverageBuilder_.clear();
+ }
+ if (profilingBuilder_ == null) {
+ profiling_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000020);
+ } else {
+ profilingBuilder_.clear();
+ }
+ if (systraceBuilder_ == null) {
+ systrace_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000040);
+ } else {
+ systraceBuilder_.clear();
+ }
+ if (logBuilder_ == null) {
+ log_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000080);
+ } else {
+ logBuilder_.clear();
+ }
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestCaseReportMessage_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage build() {
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage buildPartial() {
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage result = new com.android.vts.proto.VtsReportMessage.TestCaseReportMessage(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.name_ = name_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.testResult_ = testResult_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.startTimestamp_ = startTimestamp_;
+ if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+ to_bitField0_ |= 0x00000008;
+ }
+ result.endTimestamp_ = endTimestamp_;
+ if (coverageBuilder_ == null) {
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ coverage_ = java.util.Collections.unmodifiableList(coverage_);
+ bitField0_ = (bitField0_ & ~0x00000010);
+ }
+ result.coverage_ = coverage_;
+ } else {
+ result.coverage_ = coverageBuilder_.build();
+ }
+ if (profilingBuilder_ == null) {
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ profiling_ = java.util.Collections.unmodifiableList(profiling_);
+ bitField0_ = (bitField0_ & ~0x00000020);
+ }
+ result.profiling_ = profiling_;
+ } else {
+ result.profiling_ = profilingBuilder_.build();
+ }
+ if (systraceBuilder_ == null) {
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ systrace_ = java.util.Collections.unmodifiableList(systrace_);
+ bitField0_ = (bitField0_ & ~0x00000040);
+ }
+ result.systrace_ = systrace_;
+ } else {
+ result.systrace_ = systraceBuilder_.build();
+ }
+ if (logBuilder_ == null) {
+ if (((bitField0_ & 0x00000080) == 0x00000080)) {
+ log_ = java.util.Collections.unmodifiableList(log_);
+ bitField0_ = (bitField0_ & ~0x00000080);
+ }
+ result.log_ = log_;
+ } else {
+ result.log_ = logBuilder_.build();
+ }
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.TestCaseReportMessage) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.TestCaseReportMessage)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.TestCaseReportMessage other) {
+ if (other == com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.getDefaultInstance()) return this;
+ if (other.hasName()) {
+ setName(other.getName());
+ }
+ if (other.hasTestResult()) {
+ setTestResult(other.getTestResult());
+ }
+ if (other.hasStartTimestamp()) {
+ setStartTimestamp(other.getStartTimestamp());
+ }
+ if (other.hasEndTimestamp()) {
+ setEndTimestamp(other.getEndTimestamp());
+ }
+ if (coverageBuilder_ == null) {
+ if (!other.coverage_.isEmpty()) {
+ if (coverage_.isEmpty()) {
+ coverage_ = other.coverage_;
+ bitField0_ = (bitField0_ & ~0x00000010);
+ } else {
+ ensureCoverageIsMutable();
+ coverage_.addAll(other.coverage_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.coverage_.isEmpty()) {
+ if (coverageBuilder_.isEmpty()) {
+ coverageBuilder_.dispose();
+ coverageBuilder_ = null;
+ coverage_ = other.coverage_;
+ bitField0_ = (bitField0_ & ~0x00000010);
+ coverageBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getCoverageFieldBuilder() : null;
+ } else {
+ coverageBuilder_.addAllMessages(other.coverage_);
+ }
+ }
+ }
+ if (profilingBuilder_ == null) {
+ if (!other.profiling_.isEmpty()) {
+ if (profiling_.isEmpty()) {
+ profiling_ = other.profiling_;
+ bitField0_ = (bitField0_ & ~0x00000020);
+ } else {
+ ensureProfilingIsMutable();
+ profiling_.addAll(other.profiling_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.profiling_.isEmpty()) {
+ if (profilingBuilder_.isEmpty()) {
+ profilingBuilder_.dispose();
+ profilingBuilder_ = null;
+ profiling_ = other.profiling_;
+ bitField0_ = (bitField0_ & ~0x00000020);
+ profilingBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getProfilingFieldBuilder() : null;
+ } else {
+ profilingBuilder_.addAllMessages(other.profiling_);
+ }
+ }
+ }
+ if (systraceBuilder_ == null) {
+ if (!other.systrace_.isEmpty()) {
+ if (systrace_.isEmpty()) {
+ systrace_ = other.systrace_;
+ bitField0_ = (bitField0_ & ~0x00000040);
+ } else {
+ ensureSystraceIsMutable();
+ systrace_.addAll(other.systrace_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.systrace_.isEmpty()) {
+ if (systraceBuilder_.isEmpty()) {
+ systraceBuilder_.dispose();
+ systraceBuilder_ = null;
+ systrace_ = other.systrace_;
+ bitField0_ = (bitField0_ & ~0x00000040);
+ systraceBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getSystraceFieldBuilder() : null;
+ } else {
+ systraceBuilder_.addAllMessages(other.systrace_);
+ }
+ }
+ }
+ if (logBuilder_ == null) {
+ if (!other.log_.isEmpty()) {
+ if (log_.isEmpty()) {
+ log_ = other.log_;
+ bitField0_ = (bitField0_ & ~0x00000080);
+ } else {
+ ensureLogIsMutable();
+ log_.addAll(other.log_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.log_.isEmpty()) {
+ if (logBuilder_.isEmpty()) {
+ logBuilder_.dispose();
+ logBuilder_ = null;
+ log_ = other.log_;
+ bitField0_ = (bitField0_ & ~0x00000080);
+ logBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getLogFieldBuilder() : null;
+ } else {
+ logBuilder_.addAllMessages(other.log_);
+ }
+ }
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.TestCaseReportMessage) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional bytes name = 1;
+ private com.google.protobuf.ByteString name_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the test case name.
+ * </pre>
+ */
+ public boolean hasName() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the test case name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getName() {
+ return name_;
+ }
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the test case name.
+ * </pre>
+ */
+ public Builder setName(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ name_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the test case name.
+ * </pre>
+ */
+ public Builder clearName() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ name_ = getDefaultInstance().getName();
+ onChanged();
+ return this;
+ }
+
+ // optional .android.vts.TestCaseResult test_result = 11;
+ private com.android.vts.proto.VtsReportMessage.TestCaseResult testResult_ = com.android.vts.proto.VtsReportMessage.TestCaseResult.UNKNOWN_RESULT;
+ /**
+ * <code>optional .android.vts.TestCaseResult test_result = 11;</code>
+ *
+ * <pre>
+ * the test result.
+ * </pre>
+ */
+ public boolean hasTestResult() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional .android.vts.TestCaseResult test_result = 11;</code>
+ *
+ * <pre>
+ * the test result.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestCaseResult getTestResult() {
+ return testResult_;
+ }
+ /**
+ * <code>optional .android.vts.TestCaseResult test_result = 11;</code>
+ *
+ * <pre>
+ * the test result.
+ * </pre>
+ */
+ public Builder setTestResult(com.android.vts.proto.VtsReportMessage.TestCaseResult value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000002;
+ testResult_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.TestCaseResult test_result = 11;</code>
+ *
+ * <pre>
+ * the test result.
+ * </pre>
+ */
+ public Builder clearTestResult() {
+ bitField0_ = (bitField0_ & ~0x00000002);
+ testResult_ = com.android.vts.proto.VtsReportMessage.TestCaseResult.UNKNOWN_RESULT;
+ onChanged();
+ return this;
+ }
+
+ // optional int64 start_timestamp = 21;
+ private long startTimestamp_ ;
+ /**
+ * <code>optional int64 start_timestamp = 21;</code>
+ *
+ * <pre>
+ * execution start and end time stamp.
+ * </pre>
+ */
+ public boolean hasStartTimestamp() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional int64 start_timestamp = 21;</code>
+ *
+ * <pre>
+ * execution start and end time stamp.
+ * </pre>
+ */
+ public long getStartTimestamp() {
+ return startTimestamp_;
+ }
+ /**
+ * <code>optional int64 start_timestamp = 21;</code>
+ *
+ * <pre>
+ * execution start and end time stamp.
+ * </pre>
+ */
+ public Builder setStartTimestamp(long value) {
+ bitField0_ |= 0x00000004;
+ startTimestamp_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional int64 start_timestamp = 21;</code>
+ *
+ * <pre>
+ * execution start and end time stamp.
+ * </pre>
+ */
+ public Builder clearStartTimestamp() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ startTimestamp_ = 0L;
+ onChanged();
+ return this;
+ }
+
+ // optional int64 end_timestamp = 22;
+ private long endTimestamp_ ;
+ /**
+ * <code>optional int64 end_timestamp = 22;</code>
+ */
+ public boolean hasEndTimestamp() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional int64 end_timestamp = 22;</code>
+ */
+ public long getEndTimestamp() {
+ return endTimestamp_;
+ }
+ /**
+ * <code>optional int64 end_timestamp = 22;</code>
+ */
+ public Builder setEndTimestamp(long value) {
+ bitField0_ |= 0x00000008;
+ endTimestamp_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional int64 end_timestamp = 22;</code>
+ */
+ public Builder clearEndTimestamp() {
+ bitField0_ = (bitField0_ & ~0x00000008);
+ endTimestamp_ = 0L;
+ onChanged();
+ return this;
+ }
+
+ // repeated .android.vts.CoverageReportMessage coverage = 31;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> coverage_ =
+ java.util.Collections.emptyList();
+ private void ensureCoverageIsMutable() {
+ if (!((bitField0_ & 0x00000010) == 0x00000010)) {
+ coverage_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.CoverageReportMessage>(coverage_);
+ bitField0_ |= 0x00000010;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> coverageBuilder_;
+
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> getCoverageList() {
+ if (coverageBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(coverage_);
+ } else {
+ return coverageBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public int getCoverageCount() {
+ if (coverageBuilder_ == null) {
+ return coverage_.size();
+ } else {
+ return coverageBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index) {
+ if (coverageBuilder_ == null) {
+ return coverage_.get(index);
+ } else {
+ return coverageBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public Builder setCoverage(
+ int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) {
+ if (coverageBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureCoverageIsMutable();
+ coverage_.set(index, value);
+ onChanged();
+ } else {
+ coverageBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public Builder setCoverage(
+ int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) {
+ if (coverageBuilder_ == null) {
+ ensureCoverageIsMutable();
+ coverage_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ coverageBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public Builder addCoverage(com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) {
+ if (coverageBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureCoverageIsMutable();
+ coverage_.add(value);
+ onChanged();
+ } else {
+ coverageBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public Builder addCoverage(
+ int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) {
+ if (coverageBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureCoverageIsMutable();
+ coverage_.add(index, value);
+ onChanged();
+ } else {
+ coverageBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public Builder addCoverage(
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) {
+ if (coverageBuilder_ == null) {
+ ensureCoverageIsMutable();
+ coverage_.add(builderForValue.build());
+ onChanged();
+ } else {
+ coverageBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public Builder addCoverage(
+ int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) {
+ if (coverageBuilder_ == null) {
+ ensureCoverageIsMutable();
+ coverage_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ coverageBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public Builder addAllCoverage(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessage> values) {
+ if (coverageBuilder_ == null) {
+ ensureCoverageIsMutable();
+ super.addAll(values, coverage_);
+ onChanged();
+ } else {
+ coverageBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public Builder clearCoverage() {
+ if (coverageBuilder_ == null) {
+ coverage_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000010);
+ onChanged();
+ } else {
+ coverageBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public Builder removeCoverage(int index) {
+ if (coverageBuilder_ == null) {
+ ensureCoverageIsMutable();
+ coverage_.remove(index);
+ onChanged();
+ } else {
+ coverageBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder getCoverageBuilder(
+ int index) {
+ return getCoverageFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder(
+ int index) {
+ if (coverageBuilder_ == null) {
+ return coverage_.get(index); } else {
+ return coverageBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>
+ getCoverageOrBuilderList() {
+ if (coverageBuilder_ != null) {
+ return coverageBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(coverage_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder addCoverageBuilder() {
+ return getCoverageFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder addCoverageBuilder(
+ int index) {
+ return getCoverageFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code>
+ *
+ * <pre>
+ * coverage report per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder>
+ getCoverageBuilderList() {
+ return getCoverageFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>
+ getCoverageFieldBuilder() {
+ if (coverageBuilder_ == null) {
+ coverageBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>(
+ coverage_,
+ ((bitField0_ & 0x00000010) == 0x00000010),
+ getParentForChildren(),
+ isClean());
+ coverage_ = null;
+ }
+ return coverageBuilder_;
+ }
+
+ // repeated .android.vts.ProfilingReportMessage profiling = 41;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> profiling_ =
+ java.util.Collections.emptyList();
+ private void ensureProfilingIsMutable() {
+ if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+ profiling_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage>(profiling_);
+ bitField0_ |= 0x00000020;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> profilingBuilder_;
+
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> getProfilingList() {
+ if (profilingBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(profiling_);
+ } else {
+ return profilingBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public int getProfilingCount() {
+ if (profilingBuilder_ == null) {
+ return profiling_.size();
+ } else {
+ return profilingBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index) {
+ if (profilingBuilder_ == null) {
+ return profiling_.get(index);
+ } else {
+ return profilingBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public Builder setProfiling(
+ int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) {
+ if (profilingBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureProfilingIsMutable();
+ profiling_.set(index, value);
+ onChanged();
+ } else {
+ profilingBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public Builder setProfiling(
+ int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) {
+ if (profilingBuilder_ == null) {
+ ensureProfilingIsMutable();
+ profiling_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ profilingBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public Builder addProfiling(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) {
+ if (profilingBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureProfilingIsMutable();
+ profiling_.add(value);
+ onChanged();
+ } else {
+ profilingBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public Builder addProfiling(
+ int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) {
+ if (profilingBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureProfilingIsMutable();
+ profiling_.add(index, value);
+ onChanged();
+ } else {
+ profilingBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public Builder addProfiling(
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) {
+ if (profilingBuilder_ == null) {
+ ensureProfilingIsMutable();
+ profiling_.add(builderForValue.build());
+ onChanged();
+ } else {
+ profilingBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public Builder addProfiling(
+ int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) {
+ if (profilingBuilder_ == null) {
+ ensureProfilingIsMutable();
+ profiling_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ profilingBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public Builder addAllProfiling(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> values) {
+ if (profilingBuilder_ == null) {
+ ensureProfilingIsMutable();
+ super.addAll(values, profiling_);
+ onChanged();
+ } else {
+ profilingBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public Builder clearProfiling() {
+ if (profilingBuilder_ == null) {
+ profiling_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000020);
+ onChanged();
+ } else {
+ profilingBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public Builder removeProfiling(int index) {
+ if (profilingBuilder_ == null) {
+ ensureProfilingIsMutable();
+ profiling_.remove(index);
+ onChanged();
+ } else {
+ profilingBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder getProfilingBuilder(
+ int index) {
+ return getProfilingFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder(
+ int index) {
+ if (profilingBuilder_ == null) {
+ return profiling_.get(index); } else {
+ return profilingBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>
+ getProfilingOrBuilderList() {
+ if (profilingBuilder_ != null) {
+ return profilingBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(profiling_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder addProfilingBuilder() {
+ return getProfilingFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder addProfilingBuilder(
+ int index) {
+ return getProfilingFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code>
+ *
+ * <pre>
+ * profiling reports
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder>
+ getProfilingBuilderList() {
+ return getProfilingFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>
+ getProfilingFieldBuilder() {
+ if (profilingBuilder_ == null) {
+ profilingBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>(
+ profiling_,
+ ((bitField0_ & 0x00000020) == 0x00000020),
+ getParentForChildren(),
+ isClean());
+ profiling_ = null;
+ }
+ return profilingBuilder_;
+ }
+
+ // repeated .android.vts.SystraceReportMessage systrace = 42;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> systrace_ =
+ java.util.Collections.emptyList();
+ private void ensureSystraceIsMutable() {
+ if (!((bitField0_ & 0x00000040) == 0x00000040)) {
+ systrace_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.SystraceReportMessage>(systrace_);
+ bitField0_ |= 0x00000040;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> systraceBuilder_;
+
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> getSystraceList() {
+ if (systraceBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(systrace_);
+ } else {
+ return systraceBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public int getSystraceCount() {
+ if (systraceBuilder_ == null) {
+ return systrace_.size();
+ } else {
+ return systraceBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index) {
+ if (systraceBuilder_ == null) {
+ return systrace_.get(index);
+ } else {
+ return systraceBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public Builder setSystrace(
+ int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) {
+ if (systraceBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureSystraceIsMutable();
+ systrace_.set(index, value);
+ onChanged();
+ } else {
+ systraceBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public Builder setSystrace(
+ int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) {
+ if (systraceBuilder_ == null) {
+ ensureSystraceIsMutable();
+ systrace_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ systraceBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public Builder addSystrace(com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) {
+ if (systraceBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureSystraceIsMutable();
+ systrace_.add(value);
+ onChanged();
+ } else {
+ systraceBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public Builder addSystrace(
+ int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) {
+ if (systraceBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureSystraceIsMutable();
+ systrace_.add(index, value);
+ onChanged();
+ } else {
+ systraceBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public Builder addSystrace(
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) {
+ if (systraceBuilder_ == null) {
+ ensureSystraceIsMutable();
+ systrace_.add(builderForValue.build());
+ onChanged();
+ } else {
+ systraceBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public Builder addSystrace(
+ int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) {
+ if (systraceBuilder_ == null) {
+ ensureSystraceIsMutable();
+ systrace_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ systraceBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public Builder addAllSystrace(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessage> values) {
+ if (systraceBuilder_ == null) {
+ ensureSystraceIsMutable();
+ super.addAll(values, systrace_);
+ onChanged();
+ } else {
+ systraceBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public Builder clearSystrace() {
+ if (systraceBuilder_ == null) {
+ systrace_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000040);
+ onChanged();
+ } else {
+ systraceBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public Builder removeSystrace(int index) {
+ if (systraceBuilder_ == null) {
+ ensureSystraceIsMutable();
+ systrace_.remove(index);
+ onChanged();
+ } else {
+ systraceBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder getSystraceBuilder(
+ int index) {
+ return getSystraceFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder(
+ int index) {
+ if (systraceBuilder_ == null) {
+ return systrace_.get(index); } else {
+ return systraceBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>
+ getSystraceOrBuilderList() {
+ if (systraceBuilder_ != null) {
+ return systraceBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(systrace_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder addSystraceBuilder() {
+ return getSystraceFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder addSystraceBuilder(
+ int index) {
+ return getSystraceFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code>
+ *
+ * <pre>
+ * systrace report message per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder>
+ getSystraceBuilderList() {
+ return getSystraceFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>
+ getSystraceFieldBuilder() {
+ if (systraceBuilder_ == null) {
+ systraceBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>(
+ systrace_,
+ ((bitField0_ & 0x00000040) == 0x00000040),
+ getParentForChildren(),
+ isClean());
+ systrace_ = null;
+ }
+ return systraceBuilder_;
+ }
+
+ // repeated .android.vts.LogMessage log = 101;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> log_ =
+ java.util.Collections.emptyList();
+ private void ensureLogIsMutable() {
+ if (!((bitField0_ & 0x00000080) == 0x00000080)) {
+ log_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.LogMessage>(log_);
+ bitField0_ |= 0x00000080;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> logBuilder_;
+
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> getLogList() {
+ if (logBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(log_);
+ } else {
+ return logBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public int getLogCount() {
+ if (logBuilder_ == null) {
+ return log_.size();
+ } else {
+ return logBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index) {
+ if (logBuilder_ == null) {
+ return log_.get(index);
+ } else {
+ return logBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder setLog(
+ int index, com.android.vts.proto.VtsReportMessage.LogMessage value) {
+ if (logBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureLogIsMutable();
+ log_.set(index, value);
+ onChanged();
+ } else {
+ logBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder setLog(
+ int index, com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) {
+ if (logBuilder_ == null) {
+ ensureLogIsMutable();
+ log_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ logBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder addLog(com.android.vts.proto.VtsReportMessage.LogMessage value) {
+ if (logBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureLogIsMutable();
+ log_.add(value);
+ onChanged();
+ } else {
+ logBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder addLog(
+ int index, com.android.vts.proto.VtsReportMessage.LogMessage value) {
+ if (logBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureLogIsMutable();
+ log_.add(index, value);
+ onChanged();
+ } else {
+ logBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder addLog(
+ com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) {
+ if (logBuilder_ == null) {
+ ensureLogIsMutable();
+ log_.add(builderForValue.build());
+ onChanged();
+ } else {
+ logBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder addLog(
+ int index, com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) {
+ if (logBuilder_ == null) {
+ ensureLogIsMutable();
+ log_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ logBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder addAllLog(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.LogMessage> values) {
+ if (logBuilder_ == null) {
+ ensureLogIsMutable();
+ super.addAll(values, log_);
+ onChanged();
+ } else {
+ logBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder clearLog() {
+ if (logBuilder_ == null) {
+ log_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000080);
+ onChanged();
+ } else {
+ logBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder removeLog(int index) {
+ if (logBuilder_ == null) {
+ ensureLogIsMutable();
+ log_.remove(index);
+ onChanged();
+ } else {
+ logBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessage.Builder getLogBuilder(
+ int index) {
+ return getLogFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder(
+ int index) {
+ if (logBuilder_ == null) {
+ return log_.get(index); } else {
+ return logBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>
+ getLogOrBuilderList() {
+ if (logBuilder_ != null) {
+ return logBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(log_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessage.Builder addLogBuilder() {
+ return getLogFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessage.Builder addLogBuilder(
+ int index) {
+ return getLogFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 101;</code>
+ *
+ * <pre>
+ * log for each test case. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage.Builder>
+ getLogBuilderList() {
+ return getLogFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>
+ getLogFieldBuilder() {
+ if (logBuilder_ == null) {
+ logBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>(
+ log_,
+ ((bitField0_ & 0x00000080) == 0x00000080),
+ getParentForChildren(),
+ isClean());
+ log_ = null;
+ }
+ return logBuilder_;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.TestCaseReportMessage)
+ }
+
+ static {
+ defaultInstance = new TestCaseReportMessage(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.TestCaseReportMessage)
+ }
+
+ public interface ProfilingReportMessageOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional bytes name = 1;
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the instrumentation point name.
+ * </pre>
+ */
+ boolean hasName();
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the instrumentation point name.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getName();
+
+ // optional .android.vts.VtsProfilingType type = 2;
+ /**
+ * <code>optional .android.vts.VtsProfilingType type = 2;</code>
+ */
+ boolean hasType();
+ /**
+ * <code>optional .android.vts.VtsProfilingType type = 2;</code>
+ */
+ com.android.vts.proto.VtsReportMessage.VtsProfilingType getType();
+
+ // optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;
+ /**
+ * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code>
+ */
+ boolean hasRegressionMode();
+ /**
+ * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code>
+ */
+ com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode getRegressionMode();
+
+ // optional int64 start_timestamp = 11;
+ /**
+ * <code>optional int64 start_timestamp = 11;</code>
+ *
+ * <pre>
+ * profiling start and end time stamp (for performance).
+ * </pre>
+ */
+ boolean hasStartTimestamp();
+ /**
+ * <code>optional int64 start_timestamp = 11;</code>
+ *
+ * <pre>
+ * profiling start and end time stamp (for performance).
+ * </pre>
+ */
+ long getStartTimestamp();
+
+ // optional int64 end_timestamp = 12;
+ /**
+ * <code>optional int64 end_timestamp = 12;</code>
+ */
+ boolean hasEndTimestamp();
+ /**
+ * <code>optional int64 end_timestamp = 12;</code>
+ */
+ long getEndTimestamp();
+
+ // repeated bytes label = 21;
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ java.util.List<com.google.protobuf.ByteString> getLabelList();
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ int getLabelCount();
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ com.google.protobuf.ByteString getLabel(int index);
+
+ // repeated int64 value = 22;
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ java.util.List<java.lang.Long> getValueList();
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ int getValueCount();
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ long getValue(int index);
+
+ // optional bytes x_axis_label = 31;
+ /**
+ * <code>optional bytes x_axis_label = 31;</code>
+ *
+ * <pre>
+ * x-axis and y-axis title labels when displaying the data as a graph
+ * </pre>
+ */
+ boolean hasXAxisLabel();
+ /**
+ * <code>optional bytes x_axis_label = 31;</code>
+ *
+ * <pre>
+ * x-axis and y-axis title labels when displaying the data as a graph
+ * </pre>
+ */
+ com.google.protobuf.ByteString getXAxisLabel();
+
+ // optional bytes y_axis_label = 32;
+ /**
+ * <code>optional bytes y_axis_label = 32;</code>
+ */
+ boolean hasYAxisLabel();
+ /**
+ * <code>optional bytes y_axis_label = 32;</code>
+ */
+ com.google.protobuf.ByteString getYAxisLabel();
+
+ // repeated bytes options = 41;
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ java.util.List<com.google.protobuf.ByteString> getOptionsList();
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ int getOptionsCount();
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ com.google.protobuf.ByteString getOptions(int index);
+ }
+ /**
+ * Protobuf type {@code android.vts.ProfilingReportMessage}
+ *
+ * <pre>
+ * To specify a profiling report.
+ * </pre>
+ */
+ public static final class ProfilingReportMessage extends
+ com.google.protobuf.GeneratedMessage
+ implements ProfilingReportMessageOrBuilder {
+ // Use ProfilingReportMessage.newBuilder() to construct.
+ private ProfilingReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private ProfilingReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final ProfilingReportMessage defaultInstance;
+ public static ProfilingReportMessage getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public ProfilingReportMessage getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private ProfilingReportMessage(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ name_ = input.readBytes();
+ break;
+ }
+ case 16: {
+ int rawValue = input.readEnum();
+ com.android.vts.proto.VtsReportMessage.VtsProfilingType value = com.android.vts.proto.VtsReportMessage.VtsProfilingType.valueOf(rawValue);
+ if (value == null) {
+ unknownFields.mergeVarintField(2, rawValue);
+ } else {
+ bitField0_ |= 0x00000002;
+ type_ = value;
+ }
+ break;
+ }
+ case 24: {
+ int rawValue = input.readEnum();
+ com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode value = com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode.valueOf(rawValue);
+ if (value == null) {
+ unknownFields.mergeVarintField(3, rawValue);
+ } else {
+ bitField0_ |= 0x00000004;
+ regressionMode_ = value;
+ }
+ break;
+ }
+ case 88: {
+ bitField0_ |= 0x00000008;
+ startTimestamp_ = input.readInt64();
+ break;
+ }
+ case 96: {
+ bitField0_ |= 0x00000010;
+ endTimestamp_ = input.readInt64();
+ break;
+ }
+ case 170: {
+ if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+ label_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
+ mutable_bitField0_ |= 0x00000020;
+ }
+ label_.add(input.readBytes());
+ break;
+ }
+ case 176: {
+ if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
+ value_ = new java.util.ArrayList<java.lang.Long>();
+ mutable_bitField0_ |= 0x00000040;
+ }
+ value_.add(input.readInt64());
+ break;
+ }
+ case 178: {
+ int length = input.readRawVarint32();
+ int limit = input.pushLimit(length);
+ if (!((mutable_bitField0_ & 0x00000040) == 0x00000040) && input.getBytesUntilLimit() > 0) {
+ value_ = new java.util.ArrayList<java.lang.Long>();
+ mutable_bitField0_ |= 0x00000040;
+ }
+ while (input.getBytesUntilLimit() > 0) {
+ value_.add(input.readInt64());
+ }
+ input.popLimit(limit);
+ break;
+ }
+ case 250: {
+ bitField0_ |= 0x00000020;
+ xAxisLabel_ = input.readBytes();
+ break;
+ }
+ case 258: {
+ bitField0_ |= 0x00000040;
+ yAxisLabel_ = input.readBytes();
+ break;
+ }
+ case 330: {
+ if (!((mutable_bitField0_ & 0x00000200) == 0x00000200)) {
+ options_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
+ mutable_bitField0_ |= 0x00000200;
+ }
+ options_.add(input.readBytes());
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+ label_ = java.util.Collections.unmodifiableList(label_);
+ }
+ if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
+ value_ = java.util.Collections.unmodifiableList(value_);
+ }
+ if (((mutable_bitField0_ & 0x00000200) == 0x00000200)) {
+ options_ = java.util.Collections.unmodifiableList(options_);
+ }
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_ProfilingReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_ProfilingReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.class, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<ProfilingReportMessage> PARSER =
+ new com.google.protobuf.AbstractParser<ProfilingReportMessage>() {
+ public ProfilingReportMessage parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new ProfilingReportMessage(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<ProfilingReportMessage> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional bytes name = 1;
+ public static final int NAME_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString name_;
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the instrumentation point name.
+ * </pre>
+ */
+ public boolean hasName() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the instrumentation point name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getName() {
+ return name_;
+ }
+
+ // optional .android.vts.VtsProfilingType type = 2;
+ public static final int TYPE_FIELD_NUMBER = 2;
+ private com.android.vts.proto.VtsReportMessage.VtsProfilingType type_;
+ /**
+ * <code>optional .android.vts.VtsProfilingType type = 2;</code>
+ */
+ public boolean hasType() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional .android.vts.VtsProfilingType type = 2;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsProfilingType getType() {
+ return type_;
+ }
+
+ // optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;
+ public static final int REGRESSION_MODE_FIELD_NUMBER = 3;
+ private com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode regressionMode_;
+ /**
+ * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code>
+ */
+ public boolean hasRegressionMode() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode getRegressionMode() {
+ return regressionMode_;
+ }
+
+ // optional int64 start_timestamp = 11;
+ public static final int START_TIMESTAMP_FIELD_NUMBER = 11;
+ private long startTimestamp_;
+ /**
+ * <code>optional int64 start_timestamp = 11;</code>
+ *
+ * <pre>
+ * profiling start and end time stamp (for performance).
+ * </pre>
+ */
+ public boolean hasStartTimestamp() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional int64 start_timestamp = 11;</code>
+ *
+ * <pre>
+ * profiling start and end time stamp (for performance).
+ * </pre>
+ */
+ public long getStartTimestamp() {
+ return startTimestamp_;
+ }
+
+ // optional int64 end_timestamp = 12;
+ public static final int END_TIMESTAMP_FIELD_NUMBER = 12;
+ private long endTimestamp_;
+ /**
+ * <code>optional int64 end_timestamp = 12;</code>
+ */
+ public boolean hasEndTimestamp() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * <code>optional int64 end_timestamp = 12;</code>
+ */
+ public long getEndTimestamp() {
+ return endTimestamp_;
+ }
+
+ // repeated bytes label = 21;
+ public static final int LABEL_FIELD_NUMBER = 21;
+ private java.util.List<com.google.protobuf.ByteString> label_;
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ public java.util.List<com.google.protobuf.ByteString>
+ getLabelList() {
+ return label_;
+ }
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ public int getLabelCount() {
+ return label_.size();
+ }
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ public com.google.protobuf.ByteString getLabel(int index) {
+ return label_.get(index);
+ }
+
+ // repeated int64 value = 22;
+ public static final int VALUE_FIELD_NUMBER = 22;
+ private java.util.List<java.lang.Long> value_;
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ public java.util.List<java.lang.Long>
+ getValueList() {
+ return value_;
+ }
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ public int getValueCount() {
+ return value_.size();
+ }
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ public long getValue(int index) {
+ return value_.get(index);
+ }
+
+ // optional bytes x_axis_label = 31;
+ public static final int X_AXIS_LABEL_FIELD_NUMBER = 31;
+ private com.google.protobuf.ByteString xAxisLabel_;
+ /**
+ * <code>optional bytes x_axis_label = 31;</code>
+ *
+ * <pre>
+ * x-axis and y-axis title labels when displaying the data as a graph
+ * </pre>
+ */
+ public boolean hasXAxisLabel() {
+ return ((bitField0_ & 0x00000020) == 0x00000020);
+ }
+ /**
+ * <code>optional bytes x_axis_label = 31;</code>
+ *
+ * <pre>
+ * x-axis and y-axis title labels when displaying the data as a graph
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getXAxisLabel() {
+ return xAxisLabel_;
+ }
+
+ // optional bytes y_axis_label = 32;
+ public static final int Y_AXIS_LABEL_FIELD_NUMBER = 32;
+ private com.google.protobuf.ByteString yAxisLabel_;
+ /**
+ * <code>optional bytes y_axis_label = 32;</code>
+ */
+ public boolean hasYAxisLabel() {
+ return ((bitField0_ & 0x00000040) == 0x00000040);
+ }
+ /**
+ * <code>optional bytes y_axis_label = 32;</code>
+ */
+ public com.google.protobuf.ByteString getYAxisLabel() {
+ return yAxisLabel_;
+ }
+
+ // repeated bytes options = 41;
+ public static final int OPTIONS_FIELD_NUMBER = 41;
+ private java.util.List<com.google.protobuf.ByteString> options_;
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ public java.util.List<com.google.protobuf.ByteString>
+ getOptionsList() {
+ return options_;
+ }
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ public int getOptionsCount() {
+ return options_.size();
+ }
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getOptions(int index) {
+ return options_.get(index);
+ }
+
+ private void initFields() {
+ name_ = com.google.protobuf.ByteString.EMPTY;
+ type_ = com.android.vts.proto.VtsReportMessage.VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE;
+ regressionMode_ = com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode.UNKNOWN_REGRESSION_MODE;
+ startTimestamp_ = 0L;
+ endTimestamp_ = 0L;
+ label_ = java.util.Collections.emptyList();
+ value_ = java.util.Collections.emptyList();
+ xAxisLabel_ = com.google.protobuf.ByteString.EMPTY;
+ yAxisLabel_ = com.google.protobuf.ByteString.EMPTY;
+ options_ = java.util.Collections.emptyList();
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, name_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeEnum(2, type_.getNumber());
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeEnum(3, regressionMode_.getNumber());
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ output.writeInt64(11, startTimestamp_);
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ output.writeInt64(12, endTimestamp_);
+ }
+ for (int i = 0; i < label_.size(); i++) {
+ output.writeBytes(21, label_.get(i));
+ }
+ for (int i = 0; i < value_.size(); i++) {
+ output.writeInt64(22, value_.get(i));
+ }
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ output.writeBytes(31, xAxisLabel_);
+ }
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ output.writeBytes(32, yAxisLabel_);
+ }
+ for (int i = 0; i < options_.size(); i++) {
+ output.writeBytes(41, options_.get(i));
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, name_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeEnumSize(2, type_.getNumber());
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeEnumSize(3, regressionMode_.getNumber());
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt64Size(11, startTimestamp_);
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt64Size(12, endTimestamp_);
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < label_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeBytesSizeNoTag(label_.get(i));
+ }
+ size += dataSize;
+ size += 2 * getLabelList().size();
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < value_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeInt64SizeNoTag(value_.get(i));
+ }
+ size += dataSize;
+ size += 2 * getValueList().size();
+ }
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(31, xAxisLabel_);
+ }
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(32, yAxisLabel_);
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < options_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeBytesSizeNoTag(options_.get(i));
+ }
+ size += dataSize;
+ size += 2 * getOptionsList().size();
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.ProfilingReportMessage}
+ *
+ * <pre>
+ * To specify a profiling report.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_ProfilingReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_ProfilingReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.class, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ name_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ type_ = com.android.vts.proto.VtsReportMessage.VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ regressionMode_ = com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode.UNKNOWN_REGRESSION_MODE;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ startTimestamp_ = 0L;
+ bitField0_ = (bitField0_ & ~0x00000008);
+ endTimestamp_ = 0L;
+ bitField0_ = (bitField0_ & ~0x00000010);
+ label_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000020);
+ value_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000040);
+ xAxisLabel_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000080);
+ yAxisLabel_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000100);
+ options_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000200);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_ProfilingReportMessage_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage build() {
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage buildPartial() {
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage result = new com.android.vts.proto.VtsReportMessage.ProfilingReportMessage(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.name_ = name_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.type_ = type_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.regressionMode_ = regressionMode_;
+ if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+ to_bitField0_ |= 0x00000008;
+ }
+ result.startTimestamp_ = startTimestamp_;
+ if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+ to_bitField0_ |= 0x00000010;
+ }
+ result.endTimestamp_ = endTimestamp_;
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ label_ = java.util.Collections.unmodifiableList(label_);
+ bitField0_ = (bitField0_ & ~0x00000020);
+ }
+ result.label_ = label_;
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ value_ = java.util.Collections.unmodifiableList(value_);
+ bitField0_ = (bitField0_ & ~0x00000040);
+ }
+ result.value_ = value_;
+ if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
+ to_bitField0_ |= 0x00000020;
+ }
+ result.xAxisLabel_ = xAxisLabel_;
+ if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
+ to_bitField0_ |= 0x00000040;
+ }
+ result.yAxisLabel_ = yAxisLabel_;
+ if (((bitField0_ & 0x00000200) == 0x00000200)) {
+ options_ = java.util.Collections.unmodifiableList(options_);
+ bitField0_ = (bitField0_ & ~0x00000200);
+ }
+ result.options_ = options_;
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.ProfilingReportMessage) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.ProfilingReportMessage)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage other) {
+ if (other == com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance()) return this;
+ if (other.hasName()) {
+ setName(other.getName());
+ }
+ if (other.hasType()) {
+ setType(other.getType());
+ }
+ if (other.hasRegressionMode()) {
+ setRegressionMode(other.getRegressionMode());
+ }
+ if (other.hasStartTimestamp()) {
+ setStartTimestamp(other.getStartTimestamp());
+ }
+ if (other.hasEndTimestamp()) {
+ setEndTimestamp(other.getEndTimestamp());
+ }
+ if (!other.label_.isEmpty()) {
+ if (label_.isEmpty()) {
+ label_ = other.label_;
+ bitField0_ = (bitField0_ & ~0x00000020);
+ } else {
+ ensureLabelIsMutable();
+ label_.addAll(other.label_);
+ }
+ onChanged();
+ }
+ if (!other.value_.isEmpty()) {
+ if (value_.isEmpty()) {
+ value_ = other.value_;
+ bitField0_ = (bitField0_ & ~0x00000040);
+ } else {
+ ensureValueIsMutable();
+ value_.addAll(other.value_);
+ }
+ onChanged();
+ }
+ if (other.hasXAxisLabel()) {
+ setXAxisLabel(other.getXAxisLabel());
+ }
+ if (other.hasYAxisLabel()) {
+ setYAxisLabel(other.getYAxisLabel());
+ }
+ if (!other.options_.isEmpty()) {
+ if (options_.isEmpty()) {
+ options_ = other.options_;
+ bitField0_ = (bitField0_ & ~0x00000200);
+ } else {
+ ensureOptionsIsMutable();
+ options_.addAll(other.options_);
+ }
+ onChanged();
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.ProfilingReportMessage) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional bytes name = 1;
+ private com.google.protobuf.ByteString name_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the instrumentation point name.
+ * </pre>
+ */
+ public boolean hasName() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the instrumentation point name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getName() {
+ return name_;
+ }
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the instrumentation point name.
+ * </pre>
+ */
+ public Builder setName(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ name_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes name = 1;</code>
+ *
+ * <pre>
+ * the instrumentation point name.
+ * </pre>
+ */
+ public Builder clearName() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ name_ = getDefaultInstance().getName();
+ onChanged();
+ return this;
+ }
+
+ // optional .android.vts.VtsProfilingType type = 2;
+ private com.android.vts.proto.VtsReportMessage.VtsProfilingType type_ = com.android.vts.proto.VtsReportMessage.VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE;
+ /**
+ * <code>optional .android.vts.VtsProfilingType type = 2;</code>
+ */
+ public boolean hasType() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional .android.vts.VtsProfilingType type = 2;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsProfilingType getType() {
+ return type_;
+ }
+ /**
+ * <code>optional .android.vts.VtsProfilingType type = 2;</code>
+ */
+ public Builder setType(com.android.vts.proto.VtsReportMessage.VtsProfilingType value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000002;
+ type_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.VtsProfilingType type = 2;</code>
+ */
+ public Builder clearType() {
+ bitField0_ = (bitField0_ & ~0x00000002);
+ type_ = com.android.vts.proto.VtsReportMessage.VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE;
+ onChanged();
+ return this;
+ }
+
+ // optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;
+ private com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode regressionMode_ = com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode.UNKNOWN_REGRESSION_MODE;
+ /**
+ * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code>
+ */
+ public boolean hasRegressionMode() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode getRegressionMode() {
+ return regressionMode_;
+ }
+ /**
+ * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code>
+ */
+ public Builder setRegressionMode(com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000004;
+ regressionMode_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code>
+ */
+ public Builder clearRegressionMode() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ regressionMode_ = com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode.UNKNOWN_REGRESSION_MODE;
+ onChanged();
+ return this;
+ }
+
+ // optional int64 start_timestamp = 11;
+ private long startTimestamp_ ;
+ /**
+ * <code>optional int64 start_timestamp = 11;</code>
+ *
+ * <pre>
+ * profiling start and end time stamp (for performance).
+ * </pre>
+ */
+ public boolean hasStartTimestamp() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional int64 start_timestamp = 11;</code>
+ *
+ * <pre>
+ * profiling start and end time stamp (for performance).
+ * </pre>
+ */
+ public long getStartTimestamp() {
+ return startTimestamp_;
+ }
+ /**
+ * <code>optional int64 start_timestamp = 11;</code>
+ *
+ * <pre>
+ * profiling start and end time stamp (for performance).
+ * </pre>
+ */
+ public Builder setStartTimestamp(long value) {
+ bitField0_ |= 0x00000008;
+ startTimestamp_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional int64 start_timestamp = 11;</code>
+ *
+ * <pre>
+ * profiling start and end time stamp (for performance).
+ * </pre>
+ */
+ public Builder clearStartTimestamp() {
+ bitField0_ = (bitField0_ & ~0x00000008);
+ startTimestamp_ = 0L;
+ onChanged();
+ return this;
+ }
+
+ // optional int64 end_timestamp = 12;
+ private long endTimestamp_ ;
+ /**
+ * <code>optional int64 end_timestamp = 12;</code>
+ */
+ public boolean hasEndTimestamp() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * <code>optional int64 end_timestamp = 12;</code>
+ */
+ public long getEndTimestamp() {
+ return endTimestamp_;
+ }
+ /**
+ * <code>optional int64 end_timestamp = 12;</code>
+ */
+ public Builder setEndTimestamp(long value) {
+ bitField0_ |= 0x00000010;
+ endTimestamp_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional int64 end_timestamp = 12;</code>
+ */
+ public Builder clearEndTimestamp() {
+ bitField0_ = (bitField0_ & ~0x00000010);
+ endTimestamp_ = 0L;
+ onChanged();
+ return this;
+ }
+
+ // repeated bytes label = 21;
+ private java.util.List<com.google.protobuf.ByteString> label_ = java.util.Collections.emptyList();
+ private void ensureLabelIsMutable() {
+ if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+ label_ = new java.util.ArrayList<com.google.protobuf.ByteString>(label_);
+ bitField0_ |= 0x00000020;
+ }
+ }
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ public java.util.List<com.google.protobuf.ByteString>
+ getLabelList() {
+ return java.util.Collections.unmodifiableList(label_);
+ }
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ public int getLabelCount() {
+ return label_.size();
+ }
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ public com.google.protobuf.ByteString getLabel(int index) {
+ return label_.get(index);
+ }
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ public Builder setLabel(
+ int index, com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureLabelIsMutable();
+ label_.set(index, value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ public Builder addLabel(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureLabelIsMutable();
+ label_.add(value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ public Builder addAllLabel(
+ java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
+ ensureLabelIsMutable();
+ super.addAll(values, label_);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes label = 21;</code>
+ */
+ public Builder clearLabel() {
+ label_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000020);
+ onChanged();
+ return this;
+ }
+
+ // repeated int64 value = 22;
+ private java.util.List<java.lang.Long> value_ = java.util.Collections.emptyList();
+ private void ensureValueIsMutable() {
+ if (!((bitField0_ & 0x00000040) == 0x00000040)) {
+ value_ = new java.util.ArrayList<java.lang.Long>(value_);
+ bitField0_ |= 0x00000040;
+ }
+ }
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ public java.util.List<java.lang.Long>
+ getValueList() {
+ return java.util.Collections.unmodifiableList(value_);
+ }
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ public int getValueCount() {
+ return value_.size();
+ }
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ public long getValue(int index) {
+ return value_.get(index);
+ }
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ public Builder setValue(
+ int index, long value) {
+ ensureValueIsMutable();
+ value_.set(index, value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ public Builder addValue(long value) {
+ ensureValueIsMutable();
+ value_.add(value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ public Builder addAllValue(
+ java.lang.Iterable<? extends java.lang.Long> values) {
+ ensureValueIsMutable();
+ super.addAll(values, value_);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated int64 value = 22;</code>
+ */
+ public Builder clearValue() {
+ value_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000040);
+ onChanged();
+ return this;
+ }
+
+ // optional bytes x_axis_label = 31;
+ private com.google.protobuf.ByteString xAxisLabel_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes x_axis_label = 31;</code>
+ *
+ * <pre>
+ * x-axis and y-axis title labels when displaying the data as a graph
+ * </pre>
+ */
+ public boolean hasXAxisLabel() {
+ return ((bitField0_ & 0x00000080) == 0x00000080);
+ }
+ /**
+ * <code>optional bytes x_axis_label = 31;</code>
+ *
+ * <pre>
+ * x-axis and y-axis title labels when displaying the data as a graph
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getXAxisLabel() {
+ return xAxisLabel_;
+ }
+ /**
+ * <code>optional bytes x_axis_label = 31;</code>
+ *
+ * <pre>
+ * x-axis and y-axis title labels when displaying the data as a graph
+ * </pre>
+ */
+ public Builder setXAxisLabel(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000080;
+ xAxisLabel_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes x_axis_label = 31;</code>
+ *
+ * <pre>
+ * x-axis and y-axis title labels when displaying the data as a graph
+ * </pre>
+ */
+ public Builder clearXAxisLabel() {
+ bitField0_ = (bitField0_ & ~0x00000080);
+ xAxisLabel_ = getDefaultInstance().getXAxisLabel();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes y_axis_label = 32;
+ private com.google.protobuf.ByteString yAxisLabel_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes y_axis_label = 32;</code>
+ */
+ public boolean hasYAxisLabel() {
+ return ((bitField0_ & 0x00000100) == 0x00000100);
+ }
+ /**
+ * <code>optional bytes y_axis_label = 32;</code>
+ */
+ public com.google.protobuf.ByteString getYAxisLabel() {
+ return yAxisLabel_;
+ }
+ /**
+ * <code>optional bytes y_axis_label = 32;</code>
+ */
+ public Builder setYAxisLabel(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000100;
+ yAxisLabel_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes y_axis_label = 32;</code>
+ */
+ public Builder clearYAxisLabel() {
+ bitField0_ = (bitField0_ & ~0x00000100);
+ yAxisLabel_ = getDefaultInstance().getYAxisLabel();
+ onChanged();
+ return this;
+ }
+
+ // repeated bytes options = 41;
+ private java.util.List<com.google.protobuf.ByteString> options_ = java.util.Collections.emptyList();
+ private void ensureOptionsIsMutable() {
+ if (!((bitField0_ & 0x00000200) == 0x00000200)) {
+ options_ = new java.util.ArrayList<com.google.protobuf.ByteString>(options_);
+ bitField0_ |= 0x00000200;
+ }
+ }
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ public java.util.List<com.google.protobuf.ByteString>
+ getOptionsList() {
+ return java.util.Collections.unmodifiableList(options_);
+ }
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ public int getOptionsCount() {
+ return options_.size();
+ }
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getOptions(int index) {
+ return options_.get(index);
+ }
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ public Builder setOptions(
+ int index, com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureOptionsIsMutable();
+ options_.set(index, value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ public Builder addOptions(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureOptionsIsMutable();
+ options_.add(value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ public Builder addAllOptions(
+ java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
+ ensureOptionsIsMutable();
+ super.addAll(values, options_);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes options = 41;</code>
+ *
+ * <pre>
+ * a list of strings where each string has the form of 'key=value'.
+ * used to tell certain properties of the data (e.g., passthrough vs.
+ * binderized).
+ * </pre>
+ */
+ public Builder clearOptions() {
+ options_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000200);
+ onChanged();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.ProfilingReportMessage)
+ }
+
+ static {
+ defaultInstance = new ProfilingReportMessage(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.ProfilingReportMessage)
+ }
+
+ public interface SystraceReportMessageOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional bytes process_name = 1;
+ /**
+ * <code>optional bytes process_name = 1;</code>
+ *
+ * <pre>
+ * the target process name used by systrace
+ * </pre>
+ */
+ boolean hasProcessName();
+ /**
+ * <code>optional bytes process_name = 1;</code>
+ *
+ * <pre>
+ * the target process name used by systrace
+ * </pre>
+ */
+ com.google.protobuf.ByteString getProcessName();
+
+ // repeated bytes html = 11;
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ java.util.List<com.google.protobuf.ByteString> getHtmlList();
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ int getHtmlCount();
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ com.google.protobuf.ByteString getHtml(int index);
+
+ // repeated bytes url = 21;
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ java.util.List<com.google.protobuf.ByteString> getUrlList();
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ int getUrlCount();
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ com.google.protobuf.ByteString getUrl(int index);
+ }
+ /**
+ * Protobuf type {@code android.vts.SystraceReportMessage}
+ *
+ * <pre>
+ * To specify a systrace report.
+ * </pre>
+ */
+ public static final class SystraceReportMessage extends
+ com.google.protobuf.GeneratedMessage
+ implements SystraceReportMessageOrBuilder {
+ // Use SystraceReportMessage.newBuilder() to construct.
+ private SystraceReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private SystraceReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final SystraceReportMessage defaultInstance;
+ public static SystraceReportMessage getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public SystraceReportMessage getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private SystraceReportMessage(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ processName_ = input.readBytes();
+ break;
+ }
+ case 90: {
+ if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+ html_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
+ mutable_bitField0_ |= 0x00000002;
+ }
+ html_.add(input.readBytes());
+ break;
+ }
+ case 170: {
+ if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+ url_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
+ mutable_bitField0_ |= 0x00000004;
+ }
+ url_.add(input.readBytes());
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+ html_ = java.util.Collections.unmodifiableList(html_);
+ }
+ if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+ url_ = java.util.Collections.unmodifiableList(url_);
+ }
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_SystraceReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_SystraceReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage.class, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<SystraceReportMessage> PARSER =
+ new com.google.protobuf.AbstractParser<SystraceReportMessage>() {
+ public SystraceReportMessage parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new SystraceReportMessage(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<SystraceReportMessage> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional bytes process_name = 1;
+ public static final int PROCESS_NAME_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString processName_;
+ /**
+ * <code>optional bytes process_name = 1;</code>
+ *
+ * <pre>
+ * the target process name used by systrace
+ * </pre>
+ */
+ public boolean hasProcessName() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes process_name = 1;</code>
+ *
+ * <pre>
+ * the target process name used by systrace
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getProcessName() {
+ return processName_;
+ }
+
+ // repeated bytes html = 11;
+ public static final int HTML_FIELD_NUMBER = 11;
+ private java.util.List<com.google.protobuf.ByteString> html_;
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ public java.util.List<com.google.protobuf.ByteString>
+ getHtmlList() {
+ return html_;
+ }
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ public int getHtmlCount() {
+ return html_.size();
+ }
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getHtml(int index) {
+ return html_.get(index);
+ }
+
+ // repeated bytes url = 21;
+ public static final int URL_FIELD_NUMBER = 21;
+ private java.util.List<com.google.protobuf.ByteString> url_;
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ public java.util.List<com.google.protobuf.ByteString>
+ getUrlList() {
+ return url_;
+ }
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ public int getUrlCount() {
+ return url_.size();
+ }
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getUrl(int index) {
+ return url_.get(index);
+ }
+
+ private void initFields() {
+ processName_ = com.google.protobuf.ByteString.EMPTY;
+ html_ = java.util.Collections.emptyList();
+ url_ = java.util.Collections.emptyList();
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, processName_);
+ }
+ for (int i = 0; i < html_.size(); i++) {
+ output.writeBytes(11, html_.get(i));
+ }
+ for (int i = 0; i < url_.size(); i++) {
+ output.writeBytes(21, url_.get(i));
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, processName_);
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < html_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeBytesSizeNoTag(html_.get(i));
+ }
+ size += dataSize;
+ size += 1 * getHtmlList().size();
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < url_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeBytesSizeNoTag(url_.get(i));
+ }
+ size += dataSize;
+ size += 2 * getUrlList().size();
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.SystraceReportMessage prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.SystraceReportMessage}
+ *
+ * <pre>
+ * To specify a systrace report.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_SystraceReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_SystraceReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage.class, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.SystraceReportMessage.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ processName_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ html_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000002);
+ url_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000004);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_SystraceReportMessage_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage build() {
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage buildPartial() {
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage result = new com.android.vts.proto.VtsReportMessage.SystraceReportMessage(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.processName_ = processName_;
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ html_ = java.util.Collections.unmodifiableList(html_);
+ bitField0_ = (bitField0_ & ~0x00000002);
+ }
+ result.html_ = html_;
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ url_ = java.util.Collections.unmodifiableList(url_);
+ bitField0_ = (bitField0_ & ~0x00000004);
+ }
+ result.url_ = url_;
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.SystraceReportMessage) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.SystraceReportMessage)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.SystraceReportMessage other) {
+ if (other == com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance()) return this;
+ if (other.hasProcessName()) {
+ setProcessName(other.getProcessName());
+ }
+ if (!other.html_.isEmpty()) {
+ if (html_.isEmpty()) {
+ html_ = other.html_;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ } else {
+ ensureHtmlIsMutable();
+ html_.addAll(other.html_);
+ }
+ onChanged();
+ }
+ if (!other.url_.isEmpty()) {
+ if (url_.isEmpty()) {
+ url_ = other.url_;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ } else {
+ ensureUrlIsMutable();
+ url_.addAll(other.url_);
+ }
+ onChanged();
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.SystraceReportMessage) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional bytes process_name = 1;
+ private com.google.protobuf.ByteString processName_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes process_name = 1;</code>
+ *
+ * <pre>
+ * the target process name used by systrace
+ * </pre>
+ */
+ public boolean hasProcessName() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes process_name = 1;</code>
+ *
+ * <pre>
+ * the target process name used by systrace
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getProcessName() {
+ return processName_;
+ }
+ /**
+ * <code>optional bytes process_name = 1;</code>
+ *
+ * <pre>
+ * the target process name used by systrace
+ * </pre>
+ */
+ public Builder setProcessName(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ processName_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes process_name = 1;</code>
+ *
+ * <pre>
+ * the target process name used by systrace
+ * </pre>
+ */
+ public Builder clearProcessName() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ processName_ = getDefaultInstance().getProcessName();
+ onChanged();
+ return this;
+ }
+
+ // repeated bytes html = 11;
+ private java.util.List<com.google.protobuf.ByteString> html_ = java.util.Collections.emptyList();
+ private void ensureHtmlIsMutable() {
+ if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+ html_ = new java.util.ArrayList<com.google.protobuf.ByteString>(html_);
+ bitField0_ |= 0x00000002;
+ }
+ }
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ public java.util.List<com.google.protobuf.ByteString>
+ getHtmlList() {
+ return java.util.Collections.unmodifiableList(html_);
+ }
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ public int getHtmlCount() {
+ return html_.size();
+ }
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getHtml(int index) {
+ return html_.get(index);
+ }
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ public Builder setHtml(
+ int index, com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureHtmlIsMutable();
+ html_.set(index, value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ public Builder addHtml(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureHtmlIsMutable();
+ html_.add(value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ public Builder addAllHtml(
+ java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
+ ensureHtmlIsMutable();
+ super.addAll(values, html_);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes html = 11;</code>
+ *
+ * <pre>
+ * the produced html report
+ * </pre>
+ */
+ public Builder clearHtml() {
+ html_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000002);
+ onChanged();
+ return this;
+ }
+
+ // repeated bytes url = 21;
+ private java.util.List<com.google.protobuf.ByteString> url_ = java.util.Collections.emptyList();
+ private void ensureUrlIsMutable() {
+ if (!((bitField0_ & 0x00000004) == 0x00000004)) {
+ url_ = new java.util.ArrayList<com.google.protobuf.ByteString>(url_);
+ bitField0_ |= 0x00000004;
+ }
+ }
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ public java.util.List<com.google.protobuf.ByteString>
+ getUrlList() {
+ return java.util.Collections.unmodifiableList(url_);
+ }
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ public int getUrlCount() {
+ return url_.size();
+ }
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getUrl(int index) {
+ return url_.get(index);
+ }
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ public Builder setUrl(
+ int index, com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureUrlIsMutable();
+ url_.set(index, value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ public Builder addUrl(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureUrlIsMutable();
+ url_.add(value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ public Builder addAllUrl(
+ java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
+ ensureUrlIsMutable();
+ super.addAll(values, url_);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes url = 21;</code>
+ *
+ * <pre>
+ * URLs of the produced html reports
+ * </pre>
+ */
+ public Builder clearUrl() {
+ url_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000004);
+ onChanged();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.SystraceReportMessage)
+ }
+
+ static {
+ defaultInstance = new SystraceReportMessage(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.SystraceReportMessage)
+ }
+
+ public interface CoverageReportMessageOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional bytes file_path = 11;
+ /**
+ * <code>optional bytes file_path = 11;</code>
+ *
+ * <pre>
+ * the path to the source file from the project root.
+ * </pre>
+ */
+ boolean hasFilePath();
+ /**
+ * <code>optional bytes file_path = 11;</code>
+ *
+ * <pre>
+ * the path to the source file from the project root.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getFilePath();
+
+ // optional bytes project_name = 12;
+ /**
+ * <code>optional bytes project_name = 12;</code>
+ *
+ * <pre>
+ * the name of the project where the file can be found
+ * </pre>
+ */
+ boolean hasProjectName();
+ /**
+ * <code>optional bytes project_name = 12;</code>
+ *
+ * <pre>
+ * the name of the project where the file can be found
+ * </pre>
+ */
+ com.google.protobuf.ByteString getProjectName();
+
+ // optional bytes revision = 13;
+ /**
+ * <code>optional bytes revision = 13;</code>
+ *
+ * <pre>
+ * the commit ID identifying the code revision
+ * </pre>
+ */
+ boolean hasRevision();
+ /**
+ * <code>optional bytes revision = 13;</code>
+ *
+ * <pre>
+ * the commit ID identifying the code revision
+ * </pre>
+ */
+ com.google.protobuf.ByteString getRevision();
+
+ // repeated int32 line_coverage_vector = 23;
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ java.util.List<java.lang.Integer> getLineCoverageVectorList();
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ int getLineCoverageVectorCount();
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ int getLineCoverageVector(int index);
+
+ // optional int32 total_line_count = 101;
+ /**
+ * <code>optional int32 total_line_count = 101;</code>
+ *
+ * <pre>
+ * the number of source code lines that are instrumented for code coverage
+ * measurement.
+ * </pre>
+ */
+ boolean hasTotalLineCount();
+ /**
+ * <code>optional int32 total_line_count = 101;</code>
+ *
+ * <pre>
+ * the number of source code lines that are instrumented for code coverage
+ * measurement.
+ * </pre>
+ */
+ int getTotalLineCount();
+
+ // optional int32 covered_line_count = 102;
+ /**
+ * <code>optional int32 covered_line_count = 102;</code>
+ *
+ * <pre>
+ * the number of source code lines that are executed.
+ * </pre>
+ */
+ boolean hasCoveredLineCount();
+ /**
+ * <code>optional int32 covered_line_count = 102;</code>
+ *
+ * <pre>
+ * the number of source code lines that are executed.
+ * </pre>
+ */
+ int getCoveredLineCount();
+
+ // optional bytes dir_path = 1 [deprecated = true];
+ /**
+ * <code>optional bytes dir_path = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the directory path of a source file.
+ * </pre>
+ */
+ @java.lang.Deprecated boolean hasDirPath();
+ /**
+ * <code>optional bytes dir_path = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the directory path of a source file.
+ * </pre>
+ */
+ @java.lang.Deprecated com.google.protobuf.ByteString getDirPath();
+
+ // optional bytes file_name = 2 [deprecated = true];
+ /**
+ * <code>optional bytes file_name = 2 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the name of the source file.
+ * </pre>
+ */
+ @java.lang.Deprecated boolean hasFileName();
+ /**
+ * <code>optional bytes file_name = 2 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the name of the source file.
+ * </pre>
+ */
+ @java.lang.Deprecated com.google.protobuf.ByteString getFileName();
+
+ // optional bytes html = 3 [deprecated = true];
+ /**
+ * <code>optional bytes html = 3 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * produced html report.
+ * </pre>
+ */
+ @java.lang.Deprecated boolean hasHtml();
+ /**
+ * <code>optional bytes html = 3 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * produced html report.
+ * </pre>
+ */
+ @java.lang.Deprecated com.google.protobuf.ByteString getHtml();
+ }
+ /**
+ * Protobuf type {@code android.vts.CoverageReportMessage}
+ *
+ * <pre>
+ * To specify a coverage report.
+ * </pre>
+ */
+ public static final class CoverageReportMessage extends
+ com.google.protobuf.GeneratedMessage
+ implements CoverageReportMessageOrBuilder {
+ // Use CoverageReportMessage.newBuilder() to construct.
+ private CoverageReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private CoverageReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final CoverageReportMessage defaultInstance;
+ public static CoverageReportMessage getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public CoverageReportMessage getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private CoverageReportMessage(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000020;
+ dirPath_ = input.readBytes();
+ break;
+ }
+ case 18: {
+ bitField0_ |= 0x00000040;
+ fileName_ = input.readBytes();
+ break;
+ }
+ case 26: {
+ bitField0_ |= 0x00000080;
+ html_ = input.readBytes();
+ break;
+ }
+ case 90: {
+ bitField0_ |= 0x00000001;
+ filePath_ = input.readBytes();
+ break;
+ }
+ case 98: {
+ bitField0_ |= 0x00000002;
+ projectName_ = input.readBytes();
+ break;
+ }
+ case 106: {
+ bitField0_ |= 0x00000004;
+ revision_ = input.readBytes();
+ break;
+ }
+ case 184: {
+ if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+ lineCoverageVector_ = new java.util.ArrayList<java.lang.Integer>();
+ mutable_bitField0_ |= 0x00000008;
+ }
+ lineCoverageVector_.add(input.readInt32());
+ break;
+ }
+ case 186: {
+ int length = input.readRawVarint32();
+ int limit = input.pushLimit(length);
+ if (!((mutable_bitField0_ & 0x00000008) == 0x00000008) && input.getBytesUntilLimit() > 0) {
+ lineCoverageVector_ = new java.util.ArrayList<java.lang.Integer>();
+ mutable_bitField0_ |= 0x00000008;
+ }
+ while (input.getBytesUntilLimit() > 0) {
+ lineCoverageVector_.add(input.readInt32());
+ }
+ input.popLimit(limit);
+ break;
+ }
+ case 808: {
+ bitField0_ |= 0x00000008;
+ totalLineCount_ = input.readInt32();
+ break;
+ }
+ case 816: {
+ bitField0_ |= 0x00000010;
+ coveredLineCount_ = input.readInt32();
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+ lineCoverageVector_ = java.util.Collections.unmodifiableList(lineCoverageVector_);
+ }
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_CoverageReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_CoverageReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage.class, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<CoverageReportMessage> PARSER =
+ new com.google.protobuf.AbstractParser<CoverageReportMessage>() {
+ public CoverageReportMessage parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new CoverageReportMessage(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<CoverageReportMessage> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional bytes file_path = 11;
+ public static final int FILE_PATH_FIELD_NUMBER = 11;
+ private com.google.protobuf.ByteString filePath_;
+ /**
+ * <code>optional bytes file_path = 11;</code>
+ *
+ * <pre>
+ * the path to the source file from the project root.
+ * </pre>
+ */
+ public boolean hasFilePath() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes file_path = 11;</code>
+ *
+ * <pre>
+ * the path to the source file from the project root.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getFilePath() {
+ return filePath_;
+ }
+
+ // optional bytes project_name = 12;
+ public static final int PROJECT_NAME_FIELD_NUMBER = 12;
+ private com.google.protobuf.ByteString projectName_;
+ /**
+ * <code>optional bytes project_name = 12;</code>
+ *
+ * <pre>
+ * the name of the project where the file can be found
+ * </pre>
+ */
+ public boolean hasProjectName() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes project_name = 12;</code>
+ *
+ * <pre>
+ * the name of the project where the file can be found
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getProjectName() {
+ return projectName_;
+ }
+
+ // optional bytes revision = 13;
+ public static final int REVISION_FIELD_NUMBER = 13;
+ private com.google.protobuf.ByteString revision_;
+ /**
+ * <code>optional bytes revision = 13;</code>
+ *
+ * <pre>
+ * the commit ID identifying the code revision
+ * </pre>
+ */
+ public boolean hasRevision() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional bytes revision = 13;</code>
+ *
+ * <pre>
+ * the commit ID identifying the code revision
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getRevision() {
+ return revision_;
+ }
+
+ // repeated int32 line_coverage_vector = 23;
+ public static final int LINE_COVERAGE_VECTOR_FIELD_NUMBER = 23;
+ private java.util.List<java.lang.Integer> lineCoverageVector_;
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ public java.util.List<java.lang.Integer>
+ getLineCoverageVectorList() {
+ return lineCoverageVector_;
+ }
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ public int getLineCoverageVectorCount() {
+ return lineCoverageVector_.size();
+ }
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ public int getLineCoverageVector(int index) {
+ return lineCoverageVector_.get(index);
+ }
+
+ // optional int32 total_line_count = 101;
+ public static final int TOTAL_LINE_COUNT_FIELD_NUMBER = 101;
+ private int totalLineCount_;
+ /**
+ * <code>optional int32 total_line_count = 101;</code>
+ *
+ * <pre>
+ * the number of source code lines that are instrumented for code coverage
+ * measurement.
+ * </pre>
+ */
+ public boolean hasTotalLineCount() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional int32 total_line_count = 101;</code>
+ *
+ * <pre>
+ * the number of source code lines that are instrumented for code coverage
+ * measurement.
+ * </pre>
+ */
+ public int getTotalLineCount() {
+ return totalLineCount_;
+ }
+
+ // optional int32 covered_line_count = 102;
+ public static final int COVERED_LINE_COUNT_FIELD_NUMBER = 102;
+ private int coveredLineCount_;
+ /**
+ * <code>optional int32 covered_line_count = 102;</code>
+ *
+ * <pre>
+ * the number of source code lines that are executed.
+ * </pre>
+ */
+ public boolean hasCoveredLineCount() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * <code>optional int32 covered_line_count = 102;</code>
+ *
+ * <pre>
+ * the number of source code lines that are executed.
+ * </pre>
+ */
+ public int getCoveredLineCount() {
+ return coveredLineCount_;
+ }
+
+ // optional bytes dir_path = 1 [deprecated = true];
+ public static final int DIR_PATH_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString dirPath_;
+ /**
+ * <code>optional bytes dir_path = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the directory path of a source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public boolean hasDirPath() {
+ return ((bitField0_ & 0x00000020) == 0x00000020);
+ }
+ /**
+ * <code>optional bytes dir_path = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the directory path of a source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public com.google.protobuf.ByteString getDirPath() {
+ return dirPath_;
+ }
+
+ // optional bytes file_name = 2 [deprecated = true];
+ public static final int FILE_NAME_FIELD_NUMBER = 2;
+ private com.google.protobuf.ByteString fileName_;
+ /**
+ * <code>optional bytes file_name = 2 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the name of the source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public boolean hasFileName() {
+ return ((bitField0_ & 0x00000040) == 0x00000040);
+ }
+ /**
+ * <code>optional bytes file_name = 2 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the name of the source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public com.google.protobuf.ByteString getFileName() {
+ return fileName_;
+ }
+
+ // optional bytes html = 3 [deprecated = true];
+ public static final int HTML_FIELD_NUMBER = 3;
+ private com.google.protobuf.ByteString html_;
+ /**
+ * <code>optional bytes html = 3 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * produced html report.
+ * </pre>
+ */
+ @java.lang.Deprecated public boolean hasHtml() {
+ return ((bitField0_ & 0x00000080) == 0x00000080);
+ }
+ /**
+ * <code>optional bytes html = 3 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * produced html report.
+ * </pre>
+ */
+ @java.lang.Deprecated public com.google.protobuf.ByteString getHtml() {
+ return html_;
+ }
+
+ private void initFields() {
+ filePath_ = com.google.protobuf.ByteString.EMPTY;
+ projectName_ = com.google.protobuf.ByteString.EMPTY;
+ revision_ = com.google.protobuf.ByteString.EMPTY;
+ lineCoverageVector_ = java.util.Collections.emptyList();
+ totalLineCount_ = 0;
+ coveredLineCount_ = 0;
+ dirPath_ = com.google.protobuf.ByteString.EMPTY;
+ fileName_ = com.google.protobuf.ByteString.EMPTY;
+ html_ = com.google.protobuf.ByteString.EMPTY;
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ output.writeBytes(1, dirPath_);
+ }
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ output.writeBytes(2, fileName_);
+ }
+ if (((bitField0_ & 0x00000080) == 0x00000080)) {
+ output.writeBytes(3, html_);
+ }
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(11, filePath_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeBytes(12, projectName_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeBytes(13, revision_);
+ }
+ for (int i = 0; i < lineCoverageVector_.size(); i++) {
+ output.writeInt32(23, lineCoverageVector_.get(i));
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ output.writeInt32(101, totalLineCount_);
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ output.writeInt32(102, coveredLineCount_);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, dirPath_);
+ }
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(2, fileName_);
+ }
+ if (((bitField0_ & 0x00000080) == 0x00000080)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(3, html_);
+ }
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(11, filePath_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(12, projectName_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(13, revision_);
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < lineCoverageVector_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeInt32SizeNoTag(lineCoverageVector_.get(i));
+ }
+ size += dataSize;
+ size += 2 * getLineCoverageVectorList().size();
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt32Size(101, totalLineCount_);
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt32Size(102, coveredLineCount_);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.CoverageReportMessage prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.CoverageReportMessage}
+ *
+ * <pre>
+ * To specify a coverage report.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_CoverageReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_CoverageReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage.class, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.CoverageReportMessage.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ filePath_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ projectName_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ revision_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ lineCoverageVector_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000008);
+ totalLineCount_ = 0;
+ bitField0_ = (bitField0_ & ~0x00000010);
+ coveredLineCount_ = 0;
+ bitField0_ = (bitField0_ & ~0x00000020);
+ dirPath_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000040);
+ fileName_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000080);
+ html_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000100);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_CoverageReportMessage_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage build() {
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage buildPartial() {
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage result = new com.android.vts.proto.VtsReportMessage.CoverageReportMessage(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.filePath_ = filePath_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.projectName_ = projectName_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.revision_ = revision_;
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ lineCoverageVector_ = java.util.Collections.unmodifiableList(lineCoverageVector_);
+ bitField0_ = (bitField0_ & ~0x00000008);
+ }
+ result.lineCoverageVector_ = lineCoverageVector_;
+ if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+ to_bitField0_ |= 0x00000008;
+ }
+ result.totalLineCount_ = totalLineCount_;
+ if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+ to_bitField0_ |= 0x00000010;
+ }
+ result.coveredLineCount_ = coveredLineCount_;
+ if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+ to_bitField0_ |= 0x00000020;
+ }
+ result.dirPath_ = dirPath_;
+ if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
+ to_bitField0_ |= 0x00000040;
+ }
+ result.fileName_ = fileName_;
+ if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
+ to_bitField0_ |= 0x00000080;
+ }
+ result.html_ = html_;
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.CoverageReportMessage) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.CoverageReportMessage)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.CoverageReportMessage other) {
+ if (other == com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance()) return this;
+ if (other.hasFilePath()) {
+ setFilePath(other.getFilePath());
+ }
+ if (other.hasProjectName()) {
+ setProjectName(other.getProjectName());
+ }
+ if (other.hasRevision()) {
+ setRevision(other.getRevision());
+ }
+ if (!other.lineCoverageVector_.isEmpty()) {
+ if (lineCoverageVector_.isEmpty()) {
+ lineCoverageVector_ = other.lineCoverageVector_;
+ bitField0_ = (bitField0_ & ~0x00000008);
+ } else {
+ ensureLineCoverageVectorIsMutable();
+ lineCoverageVector_.addAll(other.lineCoverageVector_);
+ }
+ onChanged();
+ }
+ if (other.hasTotalLineCount()) {
+ setTotalLineCount(other.getTotalLineCount());
+ }
+ if (other.hasCoveredLineCount()) {
+ setCoveredLineCount(other.getCoveredLineCount());
+ }
+ if (other.hasDirPath()) {
+ setDirPath(other.getDirPath());
+ }
+ if (other.hasFileName()) {
+ setFileName(other.getFileName());
+ }
+ if (other.hasHtml()) {
+ setHtml(other.getHtml());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.CoverageReportMessage) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional bytes file_path = 11;
+ private com.google.protobuf.ByteString filePath_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes file_path = 11;</code>
+ *
+ * <pre>
+ * the path to the source file from the project root.
+ * </pre>
+ */
+ public boolean hasFilePath() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes file_path = 11;</code>
+ *
+ * <pre>
+ * the path to the source file from the project root.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getFilePath() {
+ return filePath_;
+ }
+ /**
+ * <code>optional bytes file_path = 11;</code>
+ *
+ * <pre>
+ * the path to the source file from the project root.
+ * </pre>
+ */
+ public Builder setFilePath(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ filePath_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes file_path = 11;</code>
+ *
+ * <pre>
+ * the path to the source file from the project root.
+ * </pre>
+ */
+ public Builder clearFilePath() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ filePath_ = getDefaultInstance().getFilePath();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes project_name = 12;
+ private com.google.protobuf.ByteString projectName_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes project_name = 12;</code>
+ *
+ * <pre>
+ * the name of the project where the file can be found
+ * </pre>
+ */
+ public boolean hasProjectName() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes project_name = 12;</code>
+ *
+ * <pre>
+ * the name of the project where the file can be found
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getProjectName() {
+ return projectName_;
+ }
+ /**
+ * <code>optional bytes project_name = 12;</code>
+ *
+ * <pre>
+ * the name of the project where the file can be found
+ * </pre>
+ */
+ public Builder setProjectName(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000002;
+ projectName_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes project_name = 12;</code>
+ *
+ * <pre>
+ * the name of the project where the file can be found
+ * </pre>
+ */
+ public Builder clearProjectName() {
+ bitField0_ = (bitField0_ & ~0x00000002);
+ projectName_ = getDefaultInstance().getProjectName();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes revision = 13;
+ private com.google.protobuf.ByteString revision_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes revision = 13;</code>
+ *
+ * <pre>
+ * the commit ID identifying the code revision
+ * </pre>
+ */
+ public boolean hasRevision() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional bytes revision = 13;</code>
+ *
+ * <pre>
+ * the commit ID identifying the code revision
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getRevision() {
+ return revision_;
+ }
+ /**
+ * <code>optional bytes revision = 13;</code>
+ *
+ * <pre>
+ * the commit ID identifying the code revision
+ * </pre>
+ */
+ public Builder setRevision(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000004;
+ revision_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes revision = 13;</code>
+ *
+ * <pre>
+ * the commit ID identifying the code revision
+ * </pre>
+ */
+ public Builder clearRevision() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ revision_ = getDefaultInstance().getRevision();
+ onChanged();
+ return this;
+ }
+
+ // repeated int32 line_coverage_vector = 23;
+ private java.util.List<java.lang.Integer> lineCoverageVector_ = java.util.Collections.emptyList();
+ private void ensureLineCoverageVectorIsMutable() {
+ if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+ lineCoverageVector_ = new java.util.ArrayList<java.lang.Integer>(lineCoverageVector_);
+ bitField0_ |= 0x00000008;
+ }
+ }
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ public java.util.List<java.lang.Integer>
+ getLineCoverageVectorList() {
+ return java.util.Collections.unmodifiableList(lineCoverageVector_);
+ }
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ public int getLineCoverageVectorCount() {
+ return lineCoverageVector_.size();
+ }
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ public int getLineCoverageVector(int index) {
+ return lineCoverageVector_.get(index);
+ }
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ public Builder setLineCoverageVector(
+ int index, int value) {
+ ensureLineCoverageVectorIsMutable();
+ lineCoverageVector_.set(index, value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ public Builder addLineCoverageVector(int value) {
+ ensureLineCoverageVectorIsMutable();
+ lineCoverageVector_.add(value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ public Builder addAllLineCoverageVector(
+ java.lang.Iterable<? extends java.lang.Integer> values) {
+ ensureLineCoverageVectorIsMutable();
+ super.addAll(values, lineCoverageVector_);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated int32 line_coverage_vector = 23;</code>
+ *
+ * <pre>
+ * i-th element gives the number of times i-th line is executed.
+ * </pre>
+ */
+ public Builder clearLineCoverageVector() {
+ lineCoverageVector_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000008);
+ onChanged();
+ return this;
+ }
+
+ // optional int32 total_line_count = 101;
+ private int totalLineCount_ ;
+ /**
+ * <code>optional int32 total_line_count = 101;</code>
+ *
+ * <pre>
+ * the number of source code lines that are instrumented for code coverage
+ * measurement.
+ * </pre>
+ */
+ public boolean hasTotalLineCount() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * <code>optional int32 total_line_count = 101;</code>
+ *
+ * <pre>
+ * the number of source code lines that are instrumented for code coverage
+ * measurement.
+ * </pre>
+ */
+ public int getTotalLineCount() {
+ return totalLineCount_;
+ }
+ /**
+ * <code>optional int32 total_line_count = 101;</code>
+ *
+ * <pre>
+ * the number of source code lines that are instrumented for code coverage
+ * measurement.
+ * </pre>
+ */
+ public Builder setTotalLineCount(int value) {
+ bitField0_ |= 0x00000010;
+ totalLineCount_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional int32 total_line_count = 101;</code>
+ *
+ * <pre>
+ * the number of source code lines that are instrumented for code coverage
+ * measurement.
+ * </pre>
+ */
+ public Builder clearTotalLineCount() {
+ bitField0_ = (bitField0_ & ~0x00000010);
+ totalLineCount_ = 0;
+ onChanged();
+ return this;
+ }
+
+ // optional int32 covered_line_count = 102;
+ private int coveredLineCount_ ;
+ /**
+ * <code>optional int32 covered_line_count = 102;</code>
+ *
+ * <pre>
+ * the number of source code lines that are executed.
+ * </pre>
+ */
+ public boolean hasCoveredLineCount() {
+ return ((bitField0_ & 0x00000020) == 0x00000020);
+ }
+ /**
+ * <code>optional int32 covered_line_count = 102;</code>
+ *
+ * <pre>
+ * the number of source code lines that are executed.
+ * </pre>
+ */
+ public int getCoveredLineCount() {
+ return coveredLineCount_;
+ }
+ /**
+ * <code>optional int32 covered_line_count = 102;</code>
+ *
+ * <pre>
+ * the number of source code lines that are executed.
+ * </pre>
+ */
+ public Builder setCoveredLineCount(int value) {
+ bitField0_ |= 0x00000020;
+ coveredLineCount_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional int32 covered_line_count = 102;</code>
+ *
+ * <pre>
+ * the number of source code lines that are executed.
+ * </pre>
+ */
+ public Builder clearCoveredLineCount() {
+ bitField0_ = (bitField0_ & ~0x00000020);
+ coveredLineCount_ = 0;
+ onChanged();
+ return this;
+ }
+
+ // optional bytes dir_path = 1 [deprecated = true];
+ private com.google.protobuf.ByteString dirPath_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes dir_path = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the directory path of a source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public boolean hasDirPath() {
+ return ((bitField0_ & 0x00000040) == 0x00000040);
+ }
+ /**
+ * <code>optional bytes dir_path = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the directory path of a source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public com.google.protobuf.ByteString getDirPath() {
+ return dirPath_;
+ }
+ /**
+ * <code>optional bytes dir_path = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the directory path of a source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public Builder setDirPath(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000040;
+ dirPath_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes dir_path = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the directory path of a source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public Builder clearDirPath() {
+ bitField0_ = (bitField0_ & ~0x00000040);
+ dirPath_ = getDefaultInstance().getDirPath();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes file_name = 2 [deprecated = true];
+ private com.google.protobuf.ByteString fileName_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes file_name = 2 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the name of the source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public boolean hasFileName() {
+ return ((bitField0_ & 0x00000080) == 0x00000080);
+ }
+ /**
+ * <code>optional bytes file_name = 2 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the name of the source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public com.google.protobuf.ByteString getFileName() {
+ return fileName_;
+ }
+ /**
+ * <code>optional bytes file_name = 2 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the name of the source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public Builder setFileName(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000080;
+ fileName_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes file_name = 2 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * the name of the source file.
+ * </pre>
+ */
+ @java.lang.Deprecated public Builder clearFileName() {
+ bitField0_ = (bitField0_ & ~0x00000080);
+ fileName_ = getDefaultInstance().getFileName();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes html = 3 [deprecated = true];
+ private com.google.protobuf.ByteString html_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes html = 3 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * produced html report.
+ * </pre>
+ */
+ @java.lang.Deprecated public boolean hasHtml() {
+ return ((bitField0_ & 0x00000100) == 0x00000100);
+ }
+ /**
+ * <code>optional bytes html = 3 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * produced html report.
+ * </pre>
+ */
+ @java.lang.Deprecated public com.google.protobuf.ByteString getHtml() {
+ return html_;
+ }
+ /**
+ * <code>optional bytes html = 3 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * produced html report.
+ * </pre>
+ */
+ @java.lang.Deprecated public Builder setHtml(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000100;
+ html_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes html = 3 [deprecated = true];</code>
+ *
+ * <pre>
+ * TODO(ryanjcampbell@) delete deprecated field
+ * produced html report.
+ * </pre>
+ */
+ @java.lang.Deprecated public Builder clearHtml() {
+ bitField0_ = (bitField0_ & ~0x00000100);
+ html_ = getDefaultInstance().getHtml();
+ onChanged();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.CoverageReportMessage)
+ }
+
+ static {
+ defaultInstance = new CoverageReportMessage(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.CoverageReportMessage)
+ }
+
+ public interface LogMessageOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional bytes url = 1;
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a produced log file (e.g., stdout, stderr).
+ * </pre>
+ */
+ boolean hasUrl();
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a produced log file (e.g., stdout, stderr).
+ * </pre>
+ */
+ com.google.protobuf.ByteString getUrl();
+
+ // optional bytes name = 2;
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a log file.
+ * </pre>
+ */
+ boolean hasName();
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a log file.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getName();
+
+ // optional bytes content = 3;
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Content of log. Caution: do not put too much log in protobuf message,
+ * as BigTable for example recommends &lt; 10 MB for each record cell.
+ * </pre>
+ */
+ boolean hasContent();
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Content of log. Caution: do not put too much log in protobuf message,
+ * as BigTable for example recommends &lt; 10 MB for each record cell.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getContent();
+ }
+ /**
+ * Protobuf type {@code android.vts.LogMessage}
+ *
+ * <pre>
+ * To specify log report. This can be used either for per-test-module
+ * log message or per-test-case log message.
+ * </pre>
+ */
+ public static final class LogMessage extends
+ com.google.protobuf.GeneratedMessage
+ implements LogMessageOrBuilder {
+ // Use LogMessage.newBuilder() to construct.
+ private LogMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private LogMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final LogMessage defaultInstance;
+ public static LogMessage getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public LogMessage getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private LogMessage(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ url_ = input.readBytes();
+ break;
+ }
+ case 18: {
+ bitField0_ |= 0x00000002;
+ name_ = input.readBytes();
+ break;
+ }
+ case 26: {
+ bitField0_ |= 0x00000004;
+ content_ = input.readBytes();
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_LogMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_LogMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.LogMessage.class, com.android.vts.proto.VtsReportMessage.LogMessage.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<LogMessage> PARSER =
+ new com.google.protobuf.AbstractParser<LogMessage>() {
+ public LogMessage parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new LogMessage(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<LogMessage> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional bytes url = 1;
+ public static final int URL_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString url_;
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a produced log file (e.g., stdout, stderr).
+ * </pre>
+ */
+ public boolean hasUrl() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a produced log file (e.g., stdout, stderr).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getUrl() {
+ return url_;
+ }
+
+ // optional bytes name = 2;
+ public static final int NAME_FIELD_NUMBER = 2;
+ private com.google.protobuf.ByteString name_;
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a log file.
+ * </pre>
+ */
+ public boolean hasName() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a log file.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getName() {
+ return name_;
+ }
+
+ // optional bytes content = 3;
+ public static final int CONTENT_FIELD_NUMBER = 3;
+ private com.google.protobuf.ByteString content_;
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Content of log. Caution: do not put too much log in protobuf message,
+ * as BigTable for example recommends &lt; 10 MB for each record cell.
+ * </pre>
+ */
+ public boolean hasContent() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Content of log. Caution: do not put too much log in protobuf message,
+ * as BigTable for example recommends &lt; 10 MB for each record cell.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getContent() {
+ return content_;
+ }
+
+ private void initFields() {
+ url_ = com.google.protobuf.ByteString.EMPTY;
+ name_ = com.google.protobuf.ByteString.EMPTY;
+ content_ = com.google.protobuf.ByteString.EMPTY;
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, url_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeBytes(2, name_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeBytes(3, content_);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, url_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(2, name_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(3, content_);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.LogMessage parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.LogMessage parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.LogMessage prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.LogMessage}
+ *
+ * <pre>
+ * To specify log report. This can be used either for per-test-module
+ * log message or per-test-case log message.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_LogMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_LogMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.LogMessage.class, com.android.vts.proto.VtsReportMessage.LogMessage.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.LogMessage.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ url_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ name_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ content_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_LogMessage_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.LogMessage getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.LogMessage build() {
+ com.android.vts.proto.VtsReportMessage.LogMessage result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.LogMessage buildPartial() {
+ com.android.vts.proto.VtsReportMessage.LogMessage result = new com.android.vts.proto.VtsReportMessage.LogMessage(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.url_ = url_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.name_ = name_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.content_ = content_;
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.LogMessage) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.LogMessage)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.LogMessage other) {
+ if (other == com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance()) return this;
+ if (other.hasUrl()) {
+ setUrl(other.getUrl());
+ }
+ if (other.hasName()) {
+ setName(other.getName());
+ }
+ if (other.hasContent()) {
+ setContent(other.getContent());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.LogMessage parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.LogMessage) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional bytes url = 1;
+ private com.google.protobuf.ByteString url_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a produced log file (e.g., stdout, stderr).
+ * </pre>
+ */
+ public boolean hasUrl() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a produced log file (e.g., stdout, stderr).
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getUrl() {
+ return url_;
+ }
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a produced log file (e.g., stdout, stderr).
+ * </pre>
+ */
+ public Builder setUrl(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ url_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a produced log file (e.g., stdout, stderr).
+ * </pre>
+ */
+ public Builder clearUrl() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ url_ = getDefaultInstance().getUrl();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes name = 2;
+ private com.google.protobuf.ByteString name_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a log file.
+ * </pre>
+ */
+ public boolean hasName() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a log file.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getName() {
+ return name_;
+ }
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a log file.
+ * </pre>
+ */
+ public Builder setName(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000002;
+ name_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a log file.
+ * </pre>
+ */
+ public Builder clearName() {
+ bitField0_ = (bitField0_ & ~0x00000002);
+ name_ = getDefaultInstance().getName();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes content = 3;
+ private com.google.protobuf.ByteString content_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Content of log. Caution: do not put too much log in protobuf message,
+ * as BigTable for example recommends &lt; 10 MB for each record cell.
+ * </pre>
+ */
+ public boolean hasContent() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Content of log. Caution: do not put too much log in protobuf message,
+ * as BigTable for example recommends &lt; 10 MB for each record cell.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getContent() {
+ return content_;
+ }
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Content of log. Caution: do not put too much log in protobuf message,
+ * as BigTable for example recommends &lt; 10 MB for each record cell.
+ * </pre>
+ */
+ public Builder setContent(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000004;
+ content_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Content of log. Caution: do not put too much log in protobuf message,
+ * as BigTable for example recommends &lt; 10 MB for each record cell.
+ * </pre>
+ */
+ public Builder clearContent() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ content_ = getDefaultInstance().getContent();
+ onChanged();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.LogMessage)
+ }
+
+ static {
+ defaultInstance = new LogMessage(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.LogMessage)
+ }
+
+ public interface UrlResourceMessageOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional bytes url = 1;
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a resource file.
+ * </pre>
+ */
+ boolean hasUrl();
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a resource file.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getUrl();
+
+ // optional bytes name = 2;
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a resource file representing its type and does not have to be
+ * the same as the exact file name.
+ * </pre>
+ */
+ boolean hasName();
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a resource file representing its type and does not have to be
+ * the same as the exact file name.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getName();
+
+ // optional bytes content = 3;
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Raw content of a resource file. Used if the file is small.
+ * </pre>
+ */
+ boolean hasContent();
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Raw content of a resource file. Used if the file is small.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getContent();
+ }
+ /**
+ * Protobuf type {@code android.vts.UrlResourceMessage}
+ *
+ * <pre>
+ * To specify a resource object (reachable via a URL or contained in the
+ * message). This can be used to store a log file or an XML (or HTML) report
+ * file kept in a Google Cloud Storage (GCS) bucket or partner's network file
+ * system, or hosted by a HTTP server.
+ * </pre>
+ */
+ public static final class UrlResourceMessage extends
+ com.google.protobuf.GeneratedMessage
+ implements UrlResourceMessageOrBuilder {
+ // Use UrlResourceMessage.newBuilder() to construct.
+ private UrlResourceMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private UrlResourceMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final UrlResourceMessage defaultInstance;
+ public static UrlResourceMessage getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public UrlResourceMessage getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private UrlResourceMessage(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ url_ = input.readBytes();
+ break;
+ }
+ case 18: {
+ bitField0_ |= 0x00000002;
+ name_ = input.readBytes();
+ break;
+ }
+ case 26: {
+ bitField0_ |= 0x00000004;
+ content_ = input.readBytes();
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_UrlResourceMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_UrlResourceMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage.class, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<UrlResourceMessage> PARSER =
+ new com.google.protobuf.AbstractParser<UrlResourceMessage>() {
+ public UrlResourceMessage parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new UrlResourceMessage(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<UrlResourceMessage> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional bytes url = 1;
+ public static final int URL_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString url_;
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a resource file.
+ * </pre>
+ */
+ public boolean hasUrl() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a resource file.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getUrl() {
+ return url_;
+ }
+
+ // optional bytes name = 2;
+ public static final int NAME_FIELD_NUMBER = 2;
+ private com.google.protobuf.ByteString name_;
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a resource file representing its type and does not have to be
+ * the same as the exact file name.
+ * </pre>
+ */
+ public boolean hasName() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a resource file representing its type and does not have to be
+ * the same as the exact file name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getName() {
+ return name_;
+ }
+
+ // optional bytes content = 3;
+ public static final int CONTENT_FIELD_NUMBER = 3;
+ private com.google.protobuf.ByteString content_;
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Raw content of a resource file. Used if the file is small.
+ * </pre>
+ */
+ public boolean hasContent() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Raw content of a resource file. Used if the file is small.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getContent() {
+ return content_;
+ }
+
+ private void initFields() {
+ url_ = com.google.protobuf.ByteString.EMPTY;
+ name_ = com.google.protobuf.ByteString.EMPTY;
+ content_ = com.google.protobuf.ByteString.EMPTY;
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, url_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeBytes(2, name_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeBytes(3, content_);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, url_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(2, name_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(3, content_);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.UrlResourceMessage prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.UrlResourceMessage}
+ *
+ * <pre>
+ * To specify a resource object (reachable via a URL or contained in the
+ * message). This can be used to store a log file or an XML (or HTML) report
+ * file kept in a Google Cloud Storage (GCS) bucket or partner's network file
+ * system, or hosted by a HTTP server.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_UrlResourceMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_UrlResourceMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage.class, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.UrlResourceMessage.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ url_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ name_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ content_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_UrlResourceMessage_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.UrlResourceMessage getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.UrlResourceMessage.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.UrlResourceMessage build() {
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.UrlResourceMessage buildPartial() {
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage result = new com.android.vts.proto.VtsReportMessage.UrlResourceMessage(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.url_ = url_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.name_ = name_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.content_ = content_;
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.UrlResourceMessage) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.UrlResourceMessage)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.UrlResourceMessage other) {
+ if (other == com.android.vts.proto.VtsReportMessage.UrlResourceMessage.getDefaultInstance()) return this;
+ if (other.hasUrl()) {
+ setUrl(other.getUrl());
+ }
+ if (other.hasName()) {
+ setName(other.getName());
+ }
+ if (other.hasContent()) {
+ setContent(other.getContent());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.UrlResourceMessage) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional bytes url = 1;
+ private com.google.protobuf.ByteString url_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a resource file.
+ * </pre>
+ */
+ public boolean hasUrl() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a resource file.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getUrl() {
+ return url_;
+ }
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a resource file.
+ * </pre>
+ */
+ public Builder setUrl(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ url_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes url = 1;</code>
+ *
+ * <pre>
+ * URL of a resource file.
+ * </pre>
+ */
+ public Builder clearUrl() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ url_ = getDefaultInstance().getUrl();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes name = 2;
+ private com.google.protobuf.ByteString name_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a resource file representing its type and does not have to be
+ * the same as the exact file name.
+ * </pre>
+ */
+ public boolean hasName() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a resource file representing its type and does not have to be
+ * the same as the exact file name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getName() {
+ return name_;
+ }
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a resource file representing its type and does not have to be
+ * the same as the exact file name.
+ * </pre>
+ */
+ public Builder setName(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000002;
+ name_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes name = 2;</code>
+ *
+ * <pre>
+ * Name of a resource file representing its type and does not have to be
+ * the same as the exact file name.
+ * </pre>
+ */
+ public Builder clearName() {
+ bitField0_ = (bitField0_ & ~0x00000002);
+ name_ = getDefaultInstance().getName();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes content = 3;
+ private com.google.protobuf.ByteString content_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Raw content of a resource file. Used if the file is small.
+ * </pre>
+ */
+ public boolean hasContent() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Raw content of a resource file. Used if the file is small.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getContent() {
+ return content_;
+ }
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Raw content of a resource file. Used if the file is small.
+ * </pre>
+ */
+ public Builder setContent(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000004;
+ content_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes content = 3;</code>
+ *
+ * <pre>
+ * Raw content of a resource file. Used if the file is small.
+ * </pre>
+ */
+ public Builder clearContent() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ content_ = getDefaultInstance().getContent();
+ onChanged();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.UrlResourceMessage)
+ }
+
+ static {
+ defaultInstance = new UrlResourceMessage(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.UrlResourceMessage)
+ }
+
+ public interface TestReportMessageOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional bytes test_suite = 1 [deprecated = true];
+ /**
+ * <code>optional bytes test_suite = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * The test suite name..
+ * </pre>
+ */
+ @java.lang.Deprecated boolean hasTestSuite();
+ /**
+ * <code>optional bytes test_suite = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * The test suite name..
+ * </pre>
+ */
+ @java.lang.Deprecated com.google.protobuf.ByteString getTestSuite();
+
+ // optional bytes test = 2;
+ /**
+ * <code>optional bytes test = 2;</code>
+ *
+ * <pre>
+ * The test name.
+ * </pre>
+ */
+ boolean hasTest();
+ /**
+ * <code>optional bytes test = 2;</code>
+ *
+ * <pre>
+ * The test name.
+ * </pre>
+ */
+ com.google.protobuf.ByteString getTest();
+
+ // optional .android.vts.VtsTestType test_type = 3;
+ /**
+ * <code>optional .android.vts.VtsTestType test_type = 3;</code>
+ *
+ * <pre>
+ * The test type
+ * </pre>
+ */
+ boolean hasTestType();
+ /**
+ * <code>optional .android.vts.VtsTestType test_type = 3;</code>
+ *
+ * <pre>
+ * The test type
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.VtsTestType getTestType();
+
+ // repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage>
+ getDeviceInfoList();
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage getDeviceInfo(int index);
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ int getDeviceInfoCount();
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder>
+ getDeviceInfoOrBuilderList();
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder getDeviceInfoOrBuilder(
+ int index);
+
+ // optional .android.vts.AndroidBuildInfo build_info = 5;
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ boolean hasBuildInfo();
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo getBuildInfo();
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder getBuildInfoOrBuilder();
+
+ // repeated bytes subscriber_email = 6;
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ java.util.List<com.google.protobuf.ByteString> getSubscriberEmailList();
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ int getSubscriberEmailCount();
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ com.google.protobuf.ByteString getSubscriberEmail(int index);
+
+ // optional .android.vts.VtsHostInfo host_info = 7;
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ boolean hasHostInfo();
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo getHostInfo();
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder getHostInfoOrBuilder();
+
+ // repeated .android.vts.TestCaseReportMessage test_case = 11;
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage>
+ getTestCaseList();
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage getTestCase(int index);
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ int getTestCaseCount();
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder>
+ getTestCaseOrBuilderList();
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder getTestCaseOrBuilder(
+ int index);
+
+ // repeated .android.vts.ProfilingReportMessage profiling = 21;
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage>
+ getProfilingList();
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index);
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ int getProfilingCount();
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>
+ getProfilingOrBuilderList();
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder(
+ int index);
+
+ // repeated .android.vts.SystraceReportMessage systrace = 22;
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage>
+ getSystraceList();
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index);
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ int getSystraceCount();
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>
+ getSystraceOrBuilderList();
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder(
+ int index);
+
+ // optional int64 start_timestamp = 101;
+ /**
+ * <code>optional int64 start_timestamp = 101;</code>
+ *
+ * <pre>
+ * Execution start and end time stamp.
+ * </pre>
+ */
+ boolean hasStartTimestamp();
+ /**
+ * <code>optional int64 start_timestamp = 101;</code>
+ *
+ * <pre>
+ * Execution start and end time stamp.
+ * </pre>
+ */
+ long getStartTimestamp();
+
+ // optional int64 end_timestamp = 102;
+ /**
+ * <code>optional int64 end_timestamp = 102;</code>
+ */
+ boolean hasEndTimestamp();
+ /**
+ * <code>optional int64 end_timestamp = 102;</code>
+ */
+ long getEndTimestamp();
+
+ // repeated .android.vts.CoverageReportMessage coverage = 103;
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage>
+ getCoverageList();
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index);
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ int getCoverageCount();
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>
+ getCoverageOrBuilderList();
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder(
+ int index);
+
+ // repeated .android.vts.LogMessage log = 1001;
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage>
+ getLogList();
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index);
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ int getLogCount();
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>
+ getLogOrBuilderList();
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder(
+ int index);
+ }
+ /**
+ * Protobuf type {@code android.vts.TestReportMessage}
+ *
+ * <pre>
+ * To specify a test execution report.
+ * </pre>
+ */
+ public static final class TestReportMessage extends
+ com.google.protobuf.GeneratedMessage
+ implements TestReportMessageOrBuilder {
+ // Use TestReportMessage.newBuilder() to construct.
+ private TestReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private TestReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final TestReportMessage defaultInstance;
+ public static TestReportMessage getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public TestReportMessage getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private TestReportMessage(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ testSuite_ = input.readBytes();
+ break;
+ }
+ case 18: {
+ bitField0_ |= 0x00000002;
+ test_ = input.readBytes();
+ break;
+ }
+ case 24: {
+ int rawValue = input.readEnum();
+ com.android.vts.proto.VtsReportMessage.VtsTestType value = com.android.vts.proto.VtsReportMessage.VtsTestType.valueOf(rawValue);
+ if (value == null) {
+ unknownFields.mergeVarintField(3, rawValue);
+ } else {
+ bitField0_ |= 0x00000004;
+ testType_ = value;
+ }
+ break;
+ }
+ case 34: {
+ if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+ deviceInfo_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage>();
+ mutable_bitField0_ |= 0x00000008;
+ }
+ deviceInfo_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.PARSER, extensionRegistry));
+ break;
+ }
+ case 42: {
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder subBuilder = null;
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ subBuilder = buildInfo_.toBuilder();
+ }
+ buildInfo_ = input.readMessage(com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.PARSER, extensionRegistry);
+ if (subBuilder != null) {
+ subBuilder.mergeFrom(buildInfo_);
+ buildInfo_ = subBuilder.buildPartial();
+ }
+ bitField0_ |= 0x00000008;
+ break;
+ }
+ case 50: {
+ if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+ subscriberEmail_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
+ mutable_bitField0_ |= 0x00000020;
+ }
+ subscriberEmail_.add(input.readBytes());
+ break;
+ }
+ case 58: {
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder subBuilder = null;
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ subBuilder = hostInfo_.toBuilder();
+ }
+ hostInfo_ = input.readMessage(com.android.vts.proto.VtsReportMessage.VtsHostInfo.PARSER, extensionRegistry);
+ if (subBuilder != null) {
+ subBuilder.mergeFrom(hostInfo_);
+ hostInfo_ = subBuilder.buildPartial();
+ }
+ bitField0_ |= 0x00000010;
+ break;
+ }
+ case 90: {
+ if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
+ testCase_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage>();
+ mutable_bitField0_ |= 0x00000080;
+ }
+ testCase_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.PARSER, extensionRegistry));
+ break;
+ }
+ case 170: {
+ if (!((mutable_bitField0_ & 0x00000100) == 0x00000100)) {
+ profiling_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage>();
+ mutable_bitField0_ |= 0x00000100;
+ }
+ profiling_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.PARSER, extensionRegistry));
+ break;
+ }
+ case 178: {
+ if (!((mutable_bitField0_ & 0x00000200) == 0x00000200)) {
+ systrace_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.SystraceReportMessage>();
+ mutable_bitField0_ |= 0x00000200;
+ }
+ systrace_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.SystraceReportMessage.PARSER, extensionRegistry));
+ break;
+ }
+ case 808: {
+ bitField0_ |= 0x00000020;
+ startTimestamp_ = input.readInt64();
+ break;
+ }
+ case 816: {
+ bitField0_ |= 0x00000040;
+ endTimestamp_ = input.readInt64();
+ break;
+ }
+ case 826: {
+ if (!((mutable_bitField0_ & 0x00001000) == 0x00001000)) {
+ coverage_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.CoverageReportMessage>();
+ mutable_bitField0_ |= 0x00001000;
+ }
+ coverage_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.CoverageReportMessage.PARSER, extensionRegistry));
+ break;
+ }
+ case 8010: {
+ if (!((mutable_bitField0_ & 0x00002000) == 0x00002000)) {
+ log_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.LogMessage>();
+ mutable_bitField0_ |= 0x00002000;
+ }
+ log_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.LogMessage.PARSER, extensionRegistry));
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+ deviceInfo_ = java.util.Collections.unmodifiableList(deviceInfo_);
+ }
+ if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+ subscriberEmail_ = java.util.Collections.unmodifiableList(subscriberEmail_);
+ }
+ if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
+ testCase_ = java.util.Collections.unmodifiableList(testCase_);
+ }
+ if (((mutable_bitField0_ & 0x00000100) == 0x00000100)) {
+ profiling_ = java.util.Collections.unmodifiableList(profiling_);
+ }
+ if (((mutable_bitField0_ & 0x00000200) == 0x00000200)) {
+ systrace_ = java.util.Collections.unmodifiableList(systrace_);
+ }
+ if (((mutable_bitField0_ & 0x00001000) == 0x00001000)) {
+ coverage_ = java.util.Collections.unmodifiableList(coverage_);
+ }
+ if (((mutable_bitField0_ & 0x00002000) == 0x00002000)) {
+ log_ = java.util.Collections.unmodifiableList(log_);
+ }
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.TestReportMessage.class, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<TestReportMessage> PARSER =
+ new com.google.protobuf.AbstractParser<TestReportMessage>() {
+ public TestReportMessage parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new TestReportMessage(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<TestReportMessage> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional bytes test_suite = 1 [deprecated = true];
+ public static final int TEST_SUITE_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString testSuite_;
+ /**
+ * <code>optional bytes test_suite = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * The test suite name..
+ * </pre>
+ */
+ @java.lang.Deprecated public boolean hasTestSuite() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes test_suite = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * The test suite name..
+ * </pre>
+ */
+ @java.lang.Deprecated public com.google.protobuf.ByteString getTestSuite() {
+ return testSuite_;
+ }
+
+ // optional bytes test = 2;
+ public static final int TEST_FIELD_NUMBER = 2;
+ private com.google.protobuf.ByteString test_;
+ /**
+ * <code>optional bytes test = 2;</code>
+ *
+ * <pre>
+ * The test name.
+ * </pre>
+ */
+ public boolean hasTest() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes test = 2;</code>
+ *
+ * <pre>
+ * The test name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getTest() {
+ return test_;
+ }
+
+ // optional .android.vts.VtsTestType test_type = 3;
+ public static final int TEST_TYPE_FIELD_NUMBER = 3;
+ private com.android.vts.proto.VtsReportMessage.VtsTestType testType_;
+ /**
+ * <code>optional .android.vts.VtsTestType test_type = 3;</code>
+ *
+ * <pre>
+ * The test type
+ * </pre>
+ */
+ public boolean hasTestType() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional .android.vts.VtsTestType test_type = 3;</code>
+ *
+ * <pre>
+ * The test type
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsTestType getTestType() {
+ return testType_;
+ }
+
+ // repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;
+ public static final int DEVICE_INFO_FIELD_NUMBER = 4;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> deviceInfo_;
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> getDeviceInfoList() {
+ return deviceInfo_;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder>
+ getDeviceInfoOrBuilderList() {
+ return deviceInfo_;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public int getDeviceInfoCount() {
+ return deviceInfo_.size();
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage getDeviceInfo(int index) {
+ return deviceInfo_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder getDeviceInfoOrBuilder(
+ int index) {
+ return deviceInfo_.get(index);
+ }
+
+ // optional .android.vts.AndroidBuildInfo build_info = 5;
+ public static final int BUILD_INFO_FIELD_NUMBER = 5;
+ private com.android.vts.proto.VtsReportMessage.AndroidBuildInfo buildInfo_;
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public boolean hasBuildInfo() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo getBuildInfo() {
+ return buildInfo_;
+ }
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder getBuildInfoOrBuilder() {
+ return buildInfo_;
+ }
+
+ // repeated bytes subscriber_email = 6;
+ public static final int SUBSCRIBER_EMAIL_FIELD_NUMBER = 6;
+ private java.util.List<com.google.protobuf.ByteString> subscriberEmail_;
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ public java.util.List<com.google.protobuf.ByteString>
+ getSubscriberEmailList() {
+ return subscriberEmail_;
+ }
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ public int getSubscriberEmailCount() {
+ return subscriberEmail_.size();
+ }
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getSubscriberEmail(int index) {
+ return subscriberEmail_.get(index);
+ }
+
+ // optional .android.vts.VtsHostInfo host_info = 7;
+ public static final int HOST_INFO_FIELD_NUMBER = 7;
+ private com.android.vts.proto.VtsReportMessage.VtsHostInfo hostInfo_;
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public boolean hasHostInfo() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsHostInfo getHostInfo() {
+ return hostInfo_;
+ }
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder getHostInfoOrBuilder() {
+ return hostInfo_;
+ }
+
+ // repeated .android.vts.TestCaseReportMessage test_case = 11;
+ public static final int TEST_CASE_FIELD_NUMBER = 11;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> testCase_;
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> getTestCaseList() {
+ return testCase_;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder>
+ getTestCaseOrBuilderList() {
+ return testCase_;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public int getTestCaseCount() {
+ return testCase_.size();
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage getTestCase(int index) {
+ return testCase_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder getTestCaseOrBuilder(
+ int index) {
+ return testCase_.get(index);
+ }
+
+ // repeated .android.vts.ProfilingReportMessage profiling = 21;
+ public static final int PROFILING_FIELD_NUMBER = 21;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> profiling_;
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> getProfilingList() {
+ return profiling_;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>
+ getProfilingOrBuilderList() {
+ return profiling_;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public int getProfilingCount() {
+ return profiling_.size();
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index) {
+ return profiling_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder(
+ int index) {
+ return profiling_.get(index);
+ }
+
+ // repeated .android.vts.SystraceReportMessage systrace = 22;
+ public static final int SYSTRACE_FIELD_NUMBER = 22;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> systrace_;
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> getSystraceList() {
+ return systrace_;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>
+ getSystraceOrBuilderList() {
+ return systrace_;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public int getSystraceCount() {
+ return systrace_.size();
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index) {
+ return systrace_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder(
+ int index) {
+ return systrace_.get(index);
+ }
+
+ // optional int64 start_timestamp = 101;
+ public static final int START_TIMESTAMP_FIELD_NUMBER = 101;
+ private long startTimestamp_;
+ /**
+ * <code>optional int64 start_timestamp = 101;</code>
+ *
+ * <pre>
+ * Execution start and end time stamp.
+ * </pre>
+ */
+ public boolean hasStartTimestamp() {
+ return ((bitField0_ & 0x00000020) == 0x00000020);
+ }
+ /**
+ * <code>optional int64 start_timestamp = 101;</code>
+ *
+ * <pre>
+ * Execution start and end time stamp.
+ * </pre>
+ */
+ public long getStartTimestamp() {
+ return startTimestamp_;
+ }
+
+ // optional int64 end_timestamp = 102;
+ public static final int END_TIMESTAMP_FIELD_NUMBER = 102;
+ private long endTimestamp_;
+ /**
+ * <code>optional int64 end_timestamp = 102;</code>
+ */
+ public boolean hasEndTimestamp() {
+ return ((bitField0_ & 0x00000040) == 0x00000040);
+ }
+ /**
+ * <code>optional int64 end_timestamp = 102;</code>
+ */
+ public long getEndTimestamp() {
+ return endTimestamp_;
+ }
+
+ // repeated .android.vts.CoverageReportMessage coverage = 103;
+ public static final int COVERAGE_FIELD_NUMBER = 103;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> coverage_;
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> getCoverageList() {
+ return coverage_;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>
+ getCoverageOrBuilderList() {
+ return coverage_;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public int getCoverageCount() {
+ return coverage_.size();
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index) {
+ return coverage_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder(
+ int index) {
+ return coverage_.get(index);
+ }
+
+ // repeated .android.vts.LogMessage log = 1001;
+ public static final int LOG_FIELD_NUMBER = 1001;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> log_;
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> getLogList() {
+ return log_;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>
+ getLogOrBuilderList() {
+ return log_;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public int getLogCount() {
+ return log_.size();
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index) {
+ return log_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder(
+ int index) {
+ return log_.get(index);
+ }
+
+ private void initFields() {
+ testSuite_ = com.google.protobuf.ByteString.EMPTY;
+ test_ = com.google.protobuf.ByteString.EMPTY;
+ testType_ = com.android.vts.proto.VtsReportMessage.VtsTestType.UNKNOWN_VTS_TESTTYPE;
+ deviceInfo_ = java.util.Collections.emptyList();
+ buildInfo_ = com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance();
+ subscriberEmail_ = java.util.Collections.emptyList();
+ hostInfo_ = com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance();
+ testCase_ = java.util.Collections.emptyList();
+ profiling_ = java.util.Collections.emptyList();
+ systrace_ = java.util.Collections.emptyList();
+ startTimestamp_ = 0L;
+ endTimestamp_ = 0L;
+ coverage_ = java.util.Collections.emptyList();
+ log_ = java.util.Collections.emptyList();
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, testSuite_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeBytes(2, test_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeEnum(3, testType_.getNumber());
+ }
+ for (int i = 0; i < deviceInfo_.size(); i++) {
+ output.writeMessage(4, deviceInfo_.get(i));
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ output.writeMessage(5, buildInfo_);
+ }
+ for (int i = 0; i < subscriberEmail_.size(); i++) {
+ output.writeBytes(6, subscriberEmail_.get(i));
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ output.writeMessage(7, hostInfo_);
+ }
+ for (int i = 0; i < testCase_.size(); i++) {
+ output.writeMessage(11, testCase_.get(i));
+ }
+ for (int i = 0; i < profiling_.size(); i++) {
+ output.writeMessage(21, profiling_.get(i));
+ }
+ for (int i = 0; i < systrace_.size(); i++) {
+ output.writeMessage(22, systrace_.get(i));
+ }
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ output.writeInt64(101, startTimestamp_);
+ }
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ output.writeInt64(102, endTimestamp_);
+ }
+ for (int i = 0; i < coverage_.size(); i++) {
+ output.writeMessage(103, coverage_.get(i));
+ }
+ for (int i = 0; i < log_.size(); i++) {
+ output.writeMessage(1001, log_.get(i));
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, testSuite_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(2, test_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeEnumSize(3, testType_.getNumber());
+ }
+ for (int i = 0; i < deviceInfo_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(4, deviceInfo_.get(i));
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(5, buildInfo_);
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < subscriberEmail_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeBytesSizeNoTag(subscriberEmail_.get(i));
+ }
+ size += dataSize;
+ size += 1 * getSubscriberEmailList().size();
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(7, hostInfo_);
+ }
+ for (int i = 0; i < testCase_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(11, testCase_.get(i));
+ }
+ for (int i = 0; i < profiling_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(21, profiling_.get(i));
+ }
+ for (int i = 0; i < systrace_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(22, systrace_.get(i));
+ }
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt64Size(101, startTimestamp_);
+ }
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt64Size(102, endTimestamp_);
+ }
+ for (int i = 0; i < coverage_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(103, coverage_.get(i));
+ }
+ for (int i = 0; i < log_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(1001, log_.get(i));
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.TestReportMessage prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.TestReportMessage}
+ *
+ * <pre>
+ * To specify a test execution report.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.TestReportMessage.class, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.TestReportMessage.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ getDeviceInfoFieldBuilder();
+ getBuildInfoFieldBuilder();
+ getHostInfoFieldBuilder();
+ getTestCaseFieldBuilder();
+ getProfilingFieldBuilder();
+ getSystraceFieldBuilder();
+ getCoverageFieldBuilder();
+ getLogFieldBuilder();
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ testSuite_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ test_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ testType_ = com.android.vts.proto.VtsReportMessage.VtsTestType.UNKNOWN_VTS_TESTTYPE;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ if (deviceInfoBuilder_ == null) {
+ deviceInfo_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000008);
+ } else {
+ deviceInfoBuilder_.clear();
+ }
+ if (buildInfoBuilder_ == null) {
+ buildInfo_ = com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance();
+ } else {
+ buildInfoBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000010);
+ subscriberEmail_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000020);
+ if (hostInfoBuilder_ == null) {
+ hostInfo_ = com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance();
+ } else {
+ hostInfoBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000040);
+ if (testCaseBuilder_ == null) {
+ testCase_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000080);
+ } else {
+ testCaseBuilder_.clear();
+ }
+ if (profilingBuilder_ == null) {
+ profiling_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000100);
+ } else {
+ profilingBuilder_.clear();
+ }
+ if (systraceBuilder_ == null) {
+ systrace_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000200);
+ } else {
+ systraceBuilder_.clear();
+ }
+ startTimestamp_ = 0L;
+ bitField0_ = (bitField0_ & ~0x00000400);
+ endTimestamp_ = 0L;
+ bitField0_ = (bitField0_ & ~0x00000800);
+ if (coverageBuilder_ == null) {
+ coverage_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00001000);
+ } else {
+ coverageBuilder_.clear();
+ }
+ if (logBuilder_ == null) {
+ log_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00002000);
+ } else {
+ logBuilder_.clear();
+ }
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestReportMessage_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.TestReportMessage getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.TestReportMessage.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.TestReportMessage build() {
+ com.android.vts.proto.VtsReportMessage.TestReportMessage result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.TestReportMessage buildPartial() {
+ com.android.vts.proto.VtsReportMessage.TestReportMessage result = new com.android.vts.proto.VtsReportMessage.TestReportMessage(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.testSuite_ = testSuite_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.test_ = test_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.testType_ = testType_;
+ if (deviceInfoBuilder_ == null) {
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ deviceInfo_ = java.util.Collections.unmodifiableList(deviceInfo_);
+ bitField0_ = (bitField0_ & ~0x00000008);
+ }
+ result.deviceInfo_ = deviceInfo_;
+ } else {
+ result.deviceInfo_ = deviceInfoBuilder_.build();
+ }
+ if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+ to_bitField0_ |= 0x00000008;
+ }
+ if (buildInfoBuilder_ == null) {
+ result.buildInfo_ = buildInfo_;
+ } else {
+ result.buildInfo_ = buildInfoBuilder_.build();
+ }
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ subscriberEmail_ = java.util.Collections.unmodifiableList(subscriberEmail_);
+ bitField0_ = (bitField0_ & ~0x00000020);
+ }
+ result.subscriberEmail_ = subscriberEmail_;
+ if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+ to_bitField0_ |= 0x00000010;
+ }
+ if (hostInfoBuilder_ == null) {
+ result.hostInfo_ = hostInfo_;
+ } else {
+ result.hostInfo_ = hostInfoBuilder_.build();
+ }
+ if (testCaseBuilder_ == null) {
+ if (((bitField0_ & 0x00000080) == 0x00000080)) {
+ testCase_ = java.util.Collections.unmodifiableList(testCase_);
+ bitField0_ = (bitField0_ & ~0x00000080);
+ }
+ result.testCase_ = testCase_;
+ } else {
+ result.testCase_ = testCaseBuilder_.build();
+ }
+ if (profilingBuilder_ == null) {
+ if (((bitField0_ & 0x00000100) == 0x00000100)) {
+ profiling_ = java.util.Collections.unmodifiableList(profiling_);
+ bitField0_ = (bitField0_ & ~0x00000100);
+ }
+ result.profiling_ = profiling_;
+ } else {
+ result.profiling_ = profilingBuilder_.build();
+ }
+ if (systraceBuilder_ == null) {
+ if (((bitField0_ & 0x00000200) == 0x00000200)) {
+ systrace_ = java.util.Collections.unmodifiableList(systrace_);
+ bitField0_ = (bitField0_ & ~0x00000200);
+ }
+ result.systrace_ = systrace_;
+ } else {
+ result.systrace_ = systraceBuilder_.build();
+ }
+ if (((from_bitField0_ & 0x00000400) == 0x00000400)) {
+ to_bitField0_ |= 0x00000020;
+ }
+ result.startTimestamp_ = startTimestamp_;
+ if (((from_bitField0_ & 0x00000800) == 0x00000800)) {
+ to_bitField0_ |= 0x00000040;
+ }
+ result.endTimestamp_ = endTimestamp_;
+ if (coverageBuilder_ == null) {
+ if (((bitField0_ & 0x00001000) == 0x00001000)) {
+ coverage_ = java.util.Collections.unmodifiableList(coverage_);
+ bitField0_ = (bitField0_ & ~0x00001000);
+ }
+ result.coverage_ = coverage_;
+ } else {
+ result.coverage_ = coverageBuilder_.build();
+ }
+ if (logBuilder_ == null) {
+ if (((bitField0_ & 0x00002000) == 0x00002000)) {
+ log_ = java.util.Collections.unmodifiableList(log_);
+ bitField0_ = (bitField0_ & ~0x00002000);
+ }
+ result.log_ = log_;
+ } else {
+ result.log_ = logBuilder_.build();
+ }
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.TestReportMessage) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.TestReportMessage)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.TestReportMessage other) {
+ if (other == com.android.vts.proto.VtsReportMessage.TestReportMessage.getDefaultInstance()) return this;
+ if (other.hasTestSuite()) {
+ setTestSuite(other.getTestSuite());
+ }
+ if (other.hasTest()) {
+ setTest(other.getTest());
+ }
+ if (other.hasTestType()) {
+ setTestType(other.getTestType());
+ }
+ if (deviceInfoBuilder_ == null) {
+ if (!other.deviceInfo_.isEmpty()) {
+ if (deviceInfo_.isEmpty()) {
+ deviceInfo_ = other.deviceInfo_;
+ bitField0_ = (bitField0_ & ~0x00000008);
+ } else {
+ ensureDeviceInfoIsMutable();
+ deviceInfo_.addAll(other.deviceInfo_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.deviceInfo_.isEmpty()) {
+ if (deviceInfoBuilder_.isEmpty()) {
+ deviceInfoBuilder_.dispose();
+ deviceInfoBuilder_ = null;
+ deviceInfo_ = other.deviceInfo_;
+ bitField0_ = (bitField0_ & ~0x00000008);
+ deviceInfoBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getDeviceInfoFieldBuilder() : null;
+ } else {
+ deviceInfoBuilder_.addAllMessages(other.deviceInfo_);
+ }
+ }
+ }
+ if (other.hasBuildInfo()) {
+ mergeBuildInfo(other.getBuildInfo());
+ }
+ if (!other.subscriberEmail_.isEmpty()) {
+ if (subscriberEmail_.isEmpty()) {
+ subscriberEmail_ = other.subscriberEmail_;
+ bitField0_ = (bitField0_ & ~0x00000020);
+ } else {
+ ensureSubscriberEmailIsMutable();
+ subscriberEmail_.addAll(other.subscriberEmail_);
+ }
+ onChanged();
+ }
+ if (other.hasHostInfo()) {
+ mergeHostInfo(other.getHostInfo());
+ }
+ if (testCaseBuilder_ == null) {
+ if (!other.testCase_.isEmpty()) {
+ if (testCase_.isEmpty()) {
+ testCase_ = other.testCase_;
+ bitField0_ = (bitField0_ & ~0x00000080);
+ } else {
+ ensureTestCaseIsMutable();
+ testCase_.addAll(other.testCase_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.testCase_.isEmpty()) {
+ if (testCaseBuilder_.isEmpty()) {
+ testCaseBuilder_.dispose();
+ testCaseBuilder_ = null;
+ testCase_ = other.testCase_;
+ bitField0_ = (bitField0_ & ~0x00000080);
+ testCaseBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getTestCaseFieldBuilder() : null;
+ } else {
+ testCaseBuilder_.addAllMessages(other.testCase_);
+ }
+ }
+ }
+ if (profilingBuilder_ == null) {
+ if (!other.profiling_.isEmpty()) {
+ if (profiling_.isEmpty()) {
+ profiling_ = other.profiling_;
+ bitField0_ = (bitField0_ & ~0x00000100);
+ } else {
+ ensureProfilingIsMutable();
+ profiling_.addAll(other.profiling_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.profiling_.isEmpty()) {
+ if (profilingBuilder_.isEmpty()) {
+ profilingBuilder_.dispose();
+ profilingBuilder_ = null;
+ profiling_ = other.profiling_;
+ bitField0_ = (bitField0_ & ~0x00000100);
+ profilingBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getProfilingFieldBuilder() : null;
+ } else {
+ profilingBuilder_.addAllMessages(other.profiling_);
+ }
+ }
+ }
+ if (systraceBuilder_ == null) {
+ if (!other.systrace_.isEmpty()) {
+ if (systrace_.isEmpty()) {
+ systrace_ = other.systrace_;
+ bitField0_ = (bitField0_ & ~0x00000200);
+ } else {
+ ensureSystraceIsMutable();
+ systrace_.addAll(other.systrace_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.systrace_.isEmpty()) {
+ if (systraceBuilder_.isEmpty()) {
+ systraceBuilder_.dispose();
+ systraceBuilder_ = null;
+ systrace_ = other.systrace_;
+ bitField0_ = (bitField0_ & ~0x00000200);
+ systraceBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getSystraceFieldBuilder() : null;
+ } else {
+ systraceBuilder_.addAllMessages(other.systrace_);
+ }
+ }
+ }
+ if (other.hasStartTimestamp()) {
+ setStartTimestamp(other.getStartTimestamp());
+ }
+ if (other.hasEndTimestamp()) {
+ setEndTimestamp(other.getEndTimestamp());
+ }
+ if (coverageBuilder_ == null) {
+ if (!other.coverage_.isEmpty()) {
+ if (coverage_.isEmpty()) {
+ coverage_ = other.coverage_;
+ bitField0_ = (bitField0_ & ~0x00001000);
+ } else {
+ ensureCoverageIsMutable();
+ coverage_.addAll(other.coverage_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.coverage_.isEmpty()) {
+ if (coverageBuilder_.isEmpty()) {
+ coverageBuilder_.dispose();
+ coverageBuilder_ = null;
+ coverage_ = other.coverage_;
+ bitField0_ = (bitField0_ & ~0x00001000);
+ coverageBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getCoverageFieldBuilder() : null;
+ } else {
+ coverageBuilder_.addAllMessages(other.coverage_);
+ }
+ }
+ }
+ if (logBuilder_ == null) {
+ if (!other.log_.isEmpty()) {
+ if (log_.isEmpty()) {
+ log_ = other.log_;
+ bitField0_ = (bitField0_ & ~0x00002000);
+ } else {
+ ensureLogIsMutable();
+ log_.addAll(other.log_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.log_.isEmpty()) {
+ if (logBuilder_.isEmpty()) {
+ logBuilder_.dispose();
+ logBuilder_ = null;
+ log_ = other.log_;
+ bitField0_ = (bitField0_ & ~0x00002000);
+ logBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getLogFieldBuilder() : null;
+ } else {
+ logBuilder_.addAllMessages(other.log_);
+ }
+ }
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.TestReportMessage parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.TestReportMessage) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional bytes test_suite = 1 [deprecated = true];
+ private com.google.protobuf.ByteString testSuite_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes test_suite = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * The test suite name..
+ * </pre>
+ */
+ @java.lang.Deprecated public boolean hasTestSuite() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional bytes test_suite = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * The test suite name..
+ * </pre>
+ */
+ @java.lang.Deprecated public com.google.protobuf.ByteString getTestSuite() {
+ return testSuite_;
+ }
+ /**
+ * <code>optional bytes test_suite = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * The test suite name..
+ * </pre>
+ */
+ @java.lang.Deprecated public Builder setTestSuite(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ testSuite_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes test_suite = 1 [deprecated = true];</code>
+ *
+ * <pre>
+ * The test suite name..
+ * </pre>
+ */
+ @java.lang.Deprecated public Builder clearTestSuite() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ testSuite_ = getDefaultInstance().getTestSuite();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes test = 2;
+ private com.google.protobuf.ByteString test_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>optional bytes test = 2;</code>
+ *
+ * <pre>
+ * The test name.
+ * </pre>
+ */
+ public boolean hasTest() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * <code>optional bytes test = 2;</code>
+ *
+ * <pre>
+ * The test name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getTest() {
+ return test_;
+ }
+ /**
+ * <code>optional bytes test = 2;</code>
+ *
+ * <pre>
+ * The test name.
+ * </pre>
+ */
+ public Builder setTest(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000002;
+ test_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bytes test = 2;</code>
+ *
+ * <pre>
+ * The test name.
+ * </pre>
+ */
+ public Builder clearTest() {
+ bitField0_ = (bitField0_ & ~0x00000002);
+ test_ = getDefaultInstance().getTest();
+ onChanged();
+ return this;
+ }
+
+ // optional .android.vts.VtsTestType test_type = 3;
+ private com.android.vts.proto.VtsReportMessage.VtsTestType testType_ = com.android.vts.proto.VtsReportMessage.VtsTestType.UNKNOWN_VTS_TESTTYPE;
+ /**
+ * <code>optional .android.vts.VtsTestType test_type = 3;</code>
+ *
+ * <pre>
+ * The test type
+ * </pre>
+ */
+ public boolean hasTestType() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional .android.vts.VtsTestType test_type = 3;</code>
+ *
+ * <pre>
+ * The test type
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsTestType getTestType() {
+ return testType_;
+ }
+ /**
+ * <code>optional .android.vts.VtsTestType test_type = 3;</code>
+ *
+ * <pre>
+ * The test type
+ * </pre>
+ */
+ public Builder setTestType(com.android.vts.proto.VtsReportMessage.VtsTestType value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000004;
+ testType_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.VtsTestType test_type = 3;</code>
+ *
+ * <pre>
+ * The test type
+ * </pre>
+ */
+ public Builder clearTestType() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ testType_ = com.android.vts.proto.VtsReportMessage.VtsTestType.UNKNOWN_VTS_TESTTYPE;
+ onChanged();
+ return this;
+ }
+
+ // repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> deviceInfo_ =
+ java.util.Collections.emptyList();
+ private void ensureDeviceInfoIsMutable() {
+ if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+ deviceInfo_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage>(deviceInfo_);
+ bitField0_ |= 0x00000008;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder> deviceInfoBuilder_;
+
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> getDeviceInfoList() {
+ if (deviceInfoBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(deviceInfo_);
+ } else {
+ return deviceInfoBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public int getDeviceInfoCount() {
+ if (deviceInfoBuilder_ == null) {
+ return deviceInfo_.size();
+ } else {
+ return deviceInfoBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage getDeviceInfo(int index) {
+ if (deviceInfoBuilder_ == null) {
+ return deviceInfo_.get(index);
+ } else {
+ return deviceInfoBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public Builder setDeviceInfo(
+ int index, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage value) {
+ if (deviceInfoBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureDeviceInfoIsMutable();
+ deviceInfo_.set(index, value);
+ onChanged();
+ } else {
+ deviceInfoBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public Builder setDeviceInfo(
+ int index, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder builderForValue) {
+ if (deviceInfoBuilder_ == null) {
+ ensureDeviceInfoIsMutable();
+ deviceInfo_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ deviceInfoBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public Builder addDeviceInfo(com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage value) {
+ if (deviceInfoBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureDeviceInfoIsMutable();
+ deviceInfo_.add(value);
+ onChanged();
+ } else {
+ deviceInfoBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public Builder addDeviceInfo(
+ int index, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage value) {
+ if (deviceInfoBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureDeviceInfoIsMutable();
+ deviceInfo_.add(index, value);
+ onChanged();
+ } else {
+ deviceInfoBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public Builder addDeviceInfo(
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder builderForValue) {
+ if (deviceInfoBuilder_ == null) {
+ ensureDeviceInfoIsMutable();
+ deviceInfo_.add(builderForValue.build());
+ onChanged();
+ } else {
+ deviceInfoBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public Builder addDeviceInfo(
+ int index, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder builderForValue) {
+ if (deviceInfoBuilder_ == null) {
+ ensureDeviceInfoIsMutable();
+ deviceInfo_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ deviceInfoBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public Builder addAllDeviceInfo(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> values) {
+ if (deviceInfoBuilder_ == null) {
+ ensureDeviceInfoIsMutable();
+ super.addAll(values, deviceInfo_);
+ onChanged();
+ } else {
+ deviceInfoBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public Builder clearDeviceInfo() {
+ if (deviceInfoBuilder_ == null) {
+ deviceInfo_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000008);
+ onChanged();
+ } else {
+ deviceInfoBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public Builder removeDeviceInfo(int index) {
+ if (deviceInfoBuilder_ == null) {
+ ensureDeviceInfoIsMutable();
+ deviceInfo_.remove(index);
+ onChanged();
+ } else {
+ deviceInfoBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder getDeviceInfoBuilder(
+ int index) {
+ return getDeviceInfoFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder getDeviceInfoOrBuilder(
+ int index) {
+ if (deviceInfoBuilder_ == null) {
+ return deviceInfo_.get(index); } else {
+ return deviceInfoBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder>
+ getDeviceInfoOrBuilderList() {
+ if (deviceInfoBuilder_ != null) {
+ return deviceInfoBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(deviceInfo_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder addDeviceInfoBuilder() {
+ return getDeviceInfoFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder addDeviceInfoBuilder(
+ int index) {
+ return getDeviceInfoFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code>
+ *
+ * <pre>
+ * Target device info
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder>
+ getDeviceInfoBuilderList() {
+ return getDeviceInfoFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder>
+ getDeviceInfoFieldBuilder() {
+ if (deviceInfoBuilder_ == null) {
+ deviceInfoBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder>(
+ deviceInfo_,
+ ((bitField0_ & 0x00000008) == 0x00000008),
+ getParentForChildren(),
+ isClean());
+ deviceInfo_ = null;
+ }
+ return deviceInfoBuilder_;
+ }
+
+ // optional .android.vts.AndroidBuildInfo build_info = 5;
+ private com.android.vts.proto.VtsReportMessage.AndroidBuildInfo buildInfo_ = com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance();
+ private com.google.protobuf.SingleFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo, com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder, com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder> buildInfoBuilder_;
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public boolean hasBuildInfo() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo getBuildInfo() {
+ if (buildInfoBuilder_ == null) {
+ return buildInfo_;
+ } else {
+ return buildInfoBuilder_.getMessage();
+ }
+ }
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public Builder setBuildInfo(com.android.vts.proto.VtsReportMessage.AndroidBuildInfo value) {
+ if (buildInfoBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ buildInfo_ = value;
+ onChanged();
+ } else {
+ buildInfoBuilder_.setMessage(value);
+ }
+ bitField0_ |= 0x00000010;
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public Builder setBuildInfo(
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder builderForValue) {
+ if (buildInfoBuilder_ == null) {
+ buildInfo_ = builderForValue.build();
+ onChanged();
+ } else {
+ buildInfoBuilder_.setMessage(builderForValue.build());
+ }
+ bitField0_ |= 0x00000010;
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public Builder mergeBuildInfo(com.android.vts.proto.VtsReportMessage.AndroidBuildInfo value) {
+ if (buildInfoBuilder_ == null) {
+ if (((bitField0_ & 0x00000010) == 0x00000010) &&
+ buildInfo_ != com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance()) {
+ buildInfo_ =
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.newBuilder(buildInfo_).mergeFrom(value).buildPartial();
+ } else {
+ buildInfo_ = value;
+ }
+ onChanged();
+ } else {
+ buildInfoBuilder_.mergeFrom(value);
+ }
+ bitField0_ |= 0x00000010;
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public Builder clearBuildInfo() {
+ if (buildInfoBuilder_ == null) {
+ buildInfo_ = com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance();
+ onChanged();
+ } else {
+ buildInfoBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000010);
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder getBuildInfoBuilder() {
+ bitField0_ |= 0x00000010;
+ onChanged();
+ return getBuildInfoFieldBuilder().getBuilder();
+ }
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder getBuildInfoOrBuilder() {
+ if (buildInfoBuilder_ != null) {
+ return buildInfoBuilder_.getMessageOrBuilder();
+ } else {
+ return buildInfo_;
+ }
+ }
+ /**
+ * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code>
+ *
+ * <pre>
+ * Build info
+ * </pre>
+ */
+ private com.google.protobuf.SingleFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo, com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder, com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder>
+ getBuildInfoFieldBuilder() {
+ if (buildInfoBuilder_ == null) {
+ buildInfoBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.AndroidBuildInfo, com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder, com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder>(
+ buildInfo_,
+ getParentForChildren(),
+ isClean());
+ buildInfo_ = null;
+ }
+ return buildInfoBuilder_;
+ }
+
+ // repeated bytes subscriber_email = 6;
+ private java.util.List<com.google.protobuf.ByteString> subscriberEmail_ = java.util.Collections.emptyList();
+ private void ensureSubscriberEmailIsMutable() {
+ if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+ subscriberEmail_ = new java.util.ArrayList<com.google.protobuf.ByteString>(subscriberEmail_);
+ bitField0_ |= 0x00000020;
+ }
+ }
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ public java.util.List<com.google.protobuf.ByteString>
+ getSubscriberEmailList() {
+ return java.util.Collections.unmodifiableList(subscriberEmail_);
+ }
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ public int getSubscriberEmailCount() {
+ return subscriberEmail_.size();
+ }
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ public com.google.protobuf.ByteString getSubscriberEmail(int index) {
+ return subscriberEmail_.get(index);
+ }
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ public Builder setSubscriberEmail(
+ int index, com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureSubscriberEmailIsMutable();
+ subscriberEmail_.set(index, value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ public Builder addSubscriberEmail(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureSubscriberEmailIsMutable();
+ subscriberEmail_.add(value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ public Builder addAllSubscriberEmail(
+ java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
+ ensureSubscriberEmailIsMutable();
+ super.addAll(values, subscriberEmail_);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated bytes subscriber_email = 6;</code>
+ *
+ * <pre>
+ * Email addresses of subscribers to the test results
+ * </pre>
+ */
+ public Builder clearSubscriberEmail() {
+ subscriberEmail_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000020);
+ onChanged();
+ return this;
+ }
+
+ // optional .android.vts.VtsHostInfo host_info = 7;
+ private com.android.vts.proto.VtsReportMessage.VtsHostInfo hostInfo_ = com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance();
+ private com.google.protobuf.SingleFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo, com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder, com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder> hostInfoBuilder_;
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public boolean hasHostInfo() {
+ return ((bitField0_ & 0x00000040) == 0x00000040);
+ }
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsHostInfo getHostInfo() {
+ if (hostInfoBuilder_ == null) {
+ return hostInfo_;
+ } else {
+ return hostInfoBuilder_.getMessage();
+ }
+ }
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public Builder setHostInfo(com.android.vts.proto.VtsReportMessage.VtsHostInfo value) {
+ if (hostInfoBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ hostInfo_ = value;
+ onChanged();
+ } else {
+ hostInfoBuilder_.setMessage(value);
+ }
+ bitField0_ |= 0x00000040;
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public Builder setHostInfo(
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder builderForValue) {
+ if (hostInfoBuilder_ == null) {
+ hostInfo_ = builderForValue.build();
+ onChanged();
+ } else {
+ hostInfoBuilder_.setMessage(builderForValue.build());
+ }
+ bitField0_ |= 0x00000040;
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public Builder mergeHostInfo(com.android.vts.proto.VtsReportMessage.VtsHostInfo value) {
+ if (hostInfoBuilder_ == null) {
+ if (((bitField0_ & 0x00000040) == 0x00000040) &&
+ hostInfo_ != com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance()) {
+ hostInfo_ =
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo.newBuilder(hostInfo_).mergeFrom(value).buildPartial();
+ } else {
+ hostInfo_ = value;
+ }
+ onChanged();
+ } else {
+ hostInfoBuilder_.mergeFrom(value);
+ }
+ bitField0_ |= 0x00000040;
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public Builder clearHostInfo() {
+ if (hostInfoBuilder_ == null) {
+ hostInfo_ = com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance();
+ onChanged();
+ } else {
+ hostInfoBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000040);
+ return this;
+ }
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder getHostInfoBuilder() {
+ bitField0_ |= 0x00000040;
+ onChanged();
+ return getHostInfoFieldBuilder().getBuilder();
+ }
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder getHostInfoOrBuilder() {
+ if (hostInfoBuilder_ != null) {
+ return hostInfoBuilder_.getMessageOrBuilder();
+ } else {
+ return hostInfo_;
+ }
+ }
+ /**
+ * <code>optional .android.vts.VtsHostInfo host_info = 7;</code>
+ *
+ * <pre>
+ * Info about the host computer
+ * </pre>
+ */
+ private com.google.protobuf.SingleFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo, com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder, com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder>
+ getHostInfoFieldBuilder() {
+ if (hostInfoBuilder_ == null) {
+ hostInfoBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.VtsHostInfo, com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder, com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder>(
+ hostInfo_,
+ getParentForChildren(),
+ isClean());
+ hostInfo_ = null;
+ }
+ return hostInfoBuilder_;
+ }
+
+ // repeated .android.vts.TestCaseReportMessage test_case = 11;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> testCase_ =
+ java.util.Collections.emptyList();
+ private void ensureTestCaseIsMutable() {
+ if (!((bitField0_ & 0x00000080) == 0x00000080)) {
+ testCase_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage>(testCase_);
+ bitField0_ |= 0x00000080;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder> testCaseBuilder_;
+
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> getTestCaseList() {
+ if (testCaseBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(testCase_);
+ } else {
+ return testCaseBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public int getTestCaseCount() {
+ if (testCaseBuilder_ == null) {
+ return testCase_.size();
+ } else {
+ return testCaseBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage getTestCase(int index) {
+ if (testCaseBuilder_ == null) {
+ return testCase_.get(index);
+ } else {
+ return testCaseBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public Builder setTestCase(
+ int index, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage value) {
+ if (testCaseBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestCaseIsMutable();
+ testCase_.set(index, value);
+ onChanged();
+ } else {
+ testCaseBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public Builder setTestCase(
+ int index, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder builderForValue) {
+ if (testCaseBuilder_ == null) {
+ ensureTestCaseIsMutable();
+ testCase_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ testCaseBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public Builder addTestCase(com.android.vts.proto.VtsReportMessage.TestCaseReportMessage value) {
+ if (testCaseBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestCaseIsMutable();
+ testCase_.add(value);
+ onChanged();
+ } else {
+ testCaseBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public Builder addTestCase(
+ int index, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage value) {
+ if (testCaseBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestCaseIsMutable();
+ testCase_.add(index, value);
+ onChanged();
+ } else {
+ testCaseBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public Builder addTestCase(
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder builderForValue) {
+ if (testCaseBuilder_ == null) {
+ ensureTestCaseIsMutable();
+ testCase_.add(builderForValue.build());
+ onChanged();
+ } else {
+ testCaseBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public Builder addTestCase(
+ int index, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder builderForValue) {
+ if (testCaseBuilder_ == null) {
+ ensureTestCaseIsMutable();
+ testCase_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ testCaseBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public Builder addAllTestCase(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> values) {
+ if (testCaseBuilder_ == null) {
+ ensureTestCaseIsMutable();
+ super.addAll(values, testCase_);
+ onChanged();
+ } else {
+ testCaseBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public Builder clearTestCase() {
+ if (testCaseBuilder_ == null) {
+ testCase_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000080);
+ onChanged();
+ } else {
+ testCaseBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public Builder removeTestCase(int index) {
+ if (testCaseBuilder_ == null) {
+ ensureTestCaseIsMutable();
+ testCase_.remove(index);
+ onChanged();
+ } else {
+ testCaseBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder getTestCaseBuilder(
+ int index) {
+ return getTestCaseFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder getTestCaseOrBuilder(
+ int index) {
+ if (testCaseBuilder_ == null) {
+ return testCase_.get(index); } else {
+ return testCaseBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder>
+ getTestCaseOrBuilderList() {
+ if (testCaseBuilder_ != null) {
+ return testCaseBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(testCase_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder addTestCaseBuilder() {
+ return getTestCaseFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder addTestCaseBuilder(
+ int index) {
+ return getTestCaseFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code>
+ *
+ * <pre>
+ * Test case reports
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder>
+ getTestCaseBuilderList() {
+ return getTestCaseFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder>
+ getTestCaseFieldBuilder() {
+ if (testCaseBuilder_ == null) {
+ testCaseBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.TestCaseReportMessage, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder>(
+ testCase_,
+ ((bitField0_ & 0x00000080) == 0x00000080),
+ getParentForChildren(),
+ isClean());
+ testCase_ = null;
+ }
+ return testCaseBuilder_;
+ }
+
+ // repeated .android.vts.ProfilingReportMessage profiling = 21;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> profiling_ =
+ java.util.Collections.emptyList();
+ private void ensureProfilingIsMutable() {
+ if (!((bitField0_ & 0x00000100) == 0x00000100)) {
+ profiling_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage>(profiling_);
+ bitField0_ |= 0x00000100;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> profilingBuilder_;
+
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> getProfilingList() {
+ if (profilingBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(profiling_);
+ } else {
+ return profilingBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public int getProfilingCount() {
+ if (profilingBuilder_ == null) {
+ return profiling_.size();
+ } else {
+ return profilingBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index) {
+ if (profilingBuilder_ == null) {
+ return profiling_.get(index);
+ } else {
+ return profilingBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public Builder setProfiling(
+ int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) {
+ if (profilingBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureProfilingIsMutable();
+ profiling_.set(index, value);
+ onChanged();
+ } else {
+ profilingBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public Builder setProfiling(
+ int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) {
+ if (profilingBuilder_ == null) {
+ ensureProfilingIsMutable();
+ profiling_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ profilingBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public Builder addProfiling(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) {
+ if (profilingBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureProfilingIsMutable();
+ profiling_.add(value);
+ onChanged();
+ } else {
+ profilingBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public Builder addProfiling(
+ int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) {
+ if (profilingBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureProfilingIsMutable();
+ profiling_.add(index, value);
+ onChanged();
+ } else {
+ profilingBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public Builder addProfiling(
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) {
+ if (profilingBuilder_ == null) {
+ ensureProfilingIsMutable();
+ profiling_.add(builderForValue.build());
+ onChanged();
+ } else {
+ profilingBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public Builder addProfiling(
+ int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) {
+ if (profilingBuilder_ == null) {
+ ensureProfilingIsMutable();
+ profiling_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ profilingBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public Builder addAllProfiling(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> values) {
+ if (profilingBuilder_ == null) {
+ ensureProfilingIsMutable();
+ super.addAll(values, profiling_);
+ onChanged();
+ } else {
+ profilingBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public Builder clearProfiling() {
+ if (profilingBuilder_ == null) {
+ profiling_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000100);
+ onChanged();
+ } else {
+ profilingBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public Builder removeProfiling(int index) {
+ if (profilingBuilder_ == null) {
+ ensureProfilingIsMutable();
+ profiling_.remove(index);
+ onChanged();
+ } else {
+ profilingBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder getProfilingBuilder(
+ int index) {
+ return getProfilingFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder(
+ int index) {
+ if (profilingBuilder_ == null) {
+ return profiling_.get(index); } else {
+ return profilingBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>
+ getProfilingOrBuilderList() {
+ if (profilingBuilder_ != null) {
+ return profilingBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(profiling_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder addProfilingBuilder() {
+ return getProfilingFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder addProfilingBuilder(
+ int index) {
+ return getProfilingFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code>
+ *
+ * <pre>
+ * Profiling reports
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder>
+ getProfilingBuilderList() {
+ return getProfilingFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>
+ getProfilingFieldBuilder() {
+ if (profilingBuilder_ == null) {
+ profilingBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>(
+ profiling_,
+ ((bitField0_ & 0x00000100) == 0x00000100),
+ getParentForChildren(),
+ isClean());
+ profiling_ = null;
+ }
+ return profilingBuilder_;
+ }
+
+ // repeated .android.vts.SystraceReportMessage systrace = 22;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> systrace_ =
+ java.util.Collections.emptyList();
+ private void ensureSystraceIsMutable() {
+ if (!((bitField0_ & 0x00000200) == 0x00000200)) {
+ systrace_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.SystraceReportMessage>(systrace_);
+ bitField0_ |= 0x00000200;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> systraceBuilder_;
+
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> getSystraceList() {
+ if (systraceBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(systrace_);
+ } else {
+ return systraceBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public int getSystraceCount() {
+ if (systraceBuilder_ == null) {
+ return systrace_.size();
+ } else {
+ return systraceBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index) {
+ if (systraceBuilder_ == null) {
+ return systrace_.get(index);
+ } else {
+ return systraceBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public Builder setSystrace(
+ int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) {
+ if (systraceBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureSystraceIsMutable();
+ systrace_.set(index, value);
+ onChanged();
+ } else {
+ systraceBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public Builder setSystrace(
+ int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) {
+ if (systraceBuilder_ == null) {
+ ensureSystraceIsMutable();
+ systrace_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ systraceBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public Builder addSystrace(com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) {
+ if (systraceBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureSystraceIsMutable();
+ systrace_.add(value);
+ onChanged();
+ } else {
+ systraceBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public Builder addSystrace(
+ int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) {
+ if (systraceBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureSystraceIsMutable();
+ systrace_.add(index, value);
+ onChanged();
+ } else {
+ systraceBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public Builder addSystrace(
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) {
+ if (systraceBuilder_ == null) {
+ ensureSystraceIsMutable();
+ systrace_.add(builderForValue.build());
+ onChanged();
+ } else {
+ systraceBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public Builder addSystrace(
+ int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) {
+ if (systraceBuilder_ == null) {
+ ensureSystraceIsMutable();
+ systrace_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ systraceBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public Builder addAllSystrace(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessage> values) {
+ if (systraceBuilder_ == null) {
+ ensureSystraceIsMutable();
+ super.addAll(values, systrace_);
+ onChanged();
+ } else {
+ systraceBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public Builder clearSystrace() {
+ if (systraceBuilder_ == null) {
+ systrace_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000200);
+ onChanged();
+ } else {
+ systraceBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public Builder removeSystrace(int index) {
+ if (systraceBuilder_ == null) {
+ ensureSystraceIsMutable();
+ systrace_.remove(index);
+ onChanged();
+ } else {
+ systraceBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder getSystraceBuilder(
+ int index) {
+ return getSystraceFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder(
+ int index) {
+ if (systraceBuilder_ == null) {
+ return systrace_.get(index); } else {
+ return systraceBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>
+ getSystraceOrBuilderList() {
+ if (systraceBuilder_ != null) {
+ return systraceBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(systrace_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder addSystraceBuilder() {
+ return getSystraceFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder addSystraceBuilder(
+ int index) {
+ return getSystraceFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code>
+ *
+ * <pre>
+ * Systrace report per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder>
+ getSystraceBuilderList() {
+ return getSystraceFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>
+ getSystraceFieldBuilder() {
+ if (systraceBuilder_ == null) {
+ systraceBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>(
+ systrace_,
+ ((bitField0_ & 0x00000200) == 0x00000200),
+ getParentForChildren(),
+ isClean());
+ systrace_ = null;
+ }
+ return systraceBuilder_;
+ }
+
+ // optional int64 start_timestamp = 101;
+ private long startTimestamp_ ;
+ /**
+ * <code>optional int64 start_timestamp = 101;</code>
+ *
+ * <pre>
+ * Execution start and end time stamp.
+ * </pre>
+ */
+ public boolean hasStartTimestamp() {
+ return ((bitField0_ & 0x00000400) == 0x00000400);
+ }
+ /**
+ * <code>optional int64 start_timestamp = 101;</code>
+ *
+ * <pre>
+ * Execution start and end time stamp.
+ * </pre>
+ */
+ public long getStartTimestamp() {
+ return startTimestamp_;
+ }
+ /**
+ * <code>optional int64 start_timestamp = 101;</code>
+ *
+ * <pre>
+ * Execution start and end time stamp.
+ * </pre>
+ */
+ public Builder setStartTimestamp(long value) {
+ bitField0_ |= 0x00000400;
+ startTimestamp_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional int64 start_timestamp = 101;</code>
+ *
+ * <pre>
+ * Execution start and end time stamp.
+ * </pre>
+ */
+ public Builder clearStartTimestamp() {
+ bitField0_ = (bitField0_ & ~0x00000400);
+ startTimestamp_ = 0L;
+ onChanged();
+ return this;
+ }
+
+ // optional int64 end_timestamp = 102;
+ private long endTimestamp_ ;
+ /**
+ * <code>optional int64 end_timestamp = 102;</code>
+ */
+ public boolean hasEndTimestamp() {
+ return ((bitField0_ & 0x00000800) == 0x00000800);
+ }
+ /**
+ * <code>optional int64 end_timestamp = 102;</code>
+ */
+ public long getEndTimestamp() {
+ return endTimestamp_;
+ }
+ /**
+ * <code>optional int64 end_timestamp = 102;</code>
+ */
+ public Builder setEndTimestamp(long value) {
+ bitField0_ |= 0x00000800;
+ endTimestamp_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional int64 end_timestamp = 102;</code>
+ */
+ public Builder clearEndTimestamp() {
+ bitField0_ = (bitField0_ & ~0x00000800);
+ endTimestamp_ = 0L;
+ onChanged();
+ return this;
+ }
+
+ // repeated .android.vts.CoverageReportMessage coverage = 103;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> coverage_ =
+ java.util.Collections.emptyList();
+ private void ensureCoverageIsMutable() {
+ if (!((bitField0_ & 0x00001000) == 0x00001000)) {
+ coverage_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.CoverageReportMessage>(coverage_);
+ bitField0_ |= 0x00001000;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> coverageBuilder_;
+
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> getCoverageList() {
+ if (coverageBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(coverage_);
+ } else {
+ return coverageBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public int getCoverageCount() {
+ if (coverageBuilder_ == null) {
+ return coverage_.size();
+ } else {
+ return coverageBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index) {
+ if (coverageBuilder_ == null) {
+ return coverage_.get(index);
+ } else {
+ return coverageBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public Builder setCoverage(
+ int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) {
+ if (coverageBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureCoverageIsMutable();
+ coverage_.set(index, value);
+ onChanged();
+ } else {
+ coverageBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public Builder setCoverage(
+ int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) {
+ if (coverageBuilder_ == null) {
+ ensureCoverageIsMutable();
+ coverage_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ coverageBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public Builder addCoverage(com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) {
+ if (coverageBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureCoverageIsMutable();
+ coverage_.add(value);
+ onChanged();
+ } else {
+ coverageBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public Builder addCoverage(
+ int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) {
+ if (coverageBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureCoverageIsMutable();
+ coverage_.add(index, value);
+ onChanged();
+ } else {
+ coverageBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public Builder addCoverage(
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) {
+ if (coverageBuilder_ == null) {
+ ensureCoverageIsMutable();
+ coverage_.add(builderForValue.build());
+ onChanged();
+ } else {
+ coverageBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public Builder addCoverage(
+ int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) {
+ if (coverageBuilder_ == null) {
+ ensureCoverageIsMutable();
+ coverage_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ coverageBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public Builder addAllCoverage(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessage> values) {
+ if (coverageBuilder_ == null) {
+ ensureCoverageIsMutable();
+ super.addAll(values, coverage_);
+ onChanged();
+ } else {
+ coverageBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public Builder clearCoverage() {
+ if (coverageBuilder_ == null) {
+ coverage_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00001000);
+ onChanged();
+ } else {
+ coverageBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public Builder removeCoverage(int index) {
+ if (coverageBuilder_ == null) {
+ ensureCoverageIsMutable();
+ coverage_.remove(index);
+ onChanged();
+ } else {
+ coverageBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder getCoverageBuilder(
+ int index) {
+ return getCoverageFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder(
+ int index) {
+ if (coverageBuilder_ == null) {
+ return coverage_.get(index); } else {
+ return coverageBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>
+ getCoverageOrBuilderList() {
+ if (coverageBuilder_ != null) {
+ return coverageBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(coverage_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder addCoverageBuilder() {
+ return getCoverageFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder addCoverageBuilder(
+ int index) {
+ return getCoverageFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code>
+ *
+ * <pre>
+ * Coverage report per file
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder>
+ getCoverageBuilderList() {
+ return getCoverageFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>
+ getCoverageFieldBuilder() {
+ if (coverageBuilder_ == null) {
+ coverageBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>(
+ coverage_,
+ ((bitField0_ & 0x00001000) == 0x00001000),
+ getParentForChildren(),
+ isClean());
+ coverage_ = null;
+ }
+ return coverageBuilder_;
+ }
+
+ // repeated .android.vts.LogMessage log = 1001;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> log_ =
+ java.util.Collections.emptyList();
+ private void ensureLogIsMutable() {
+ if (!((bitField0_ & 0x00002000) == 0x00002000)) {
+ log_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.LogMessage>(log_);
+ bitField0_ |= 0x00002000;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> logBuilder_;
+
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> getLogList() {
+ if (logBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(log_);
+ } else {
+ return logBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public int getLogCount() {
+ if (logBuilder_ == null) {
+ return log_.size();
+ } else {
+ return logBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index) {
+ if (logBuilder_ == null) {
+ return log_.get(index);
+ } else {
+ return logBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder setLog(
+ int index, com.android.vts.proto.VtsReportMessage.LogMessage value) {
+ if (logBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureLogIsMutable();
+ log_.set(index, value);
+ onChanged();
+ } else {
+ logBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder setLog(
+ int index, com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) {
+ if (logBuilder_ == null) {
+ ensureLogIsMutable();
+ log_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ logBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder addLog(com.android.vts.proto.VtsReportMessage.LogMessage value) {
+ if (logBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureLogIsMutable();
+ log_.add(value);
+ onChanged();
+ } else {
+ logBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder addLog(
+ int index, com.android.vts.proto.VtsReportMessage.LogMessage value) {
+ if (logBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureLogIsMutable();
+ log_.add(index, value);
+ onChanged();
+ } else {
+ logBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder addLog(
+ com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) {
+ if (logBuilder_ == null) {
+ ensureLogIsMutable();
+ log_.add(builderForValue.build());
+ onChanged();
+ } else {
+ logBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder addLog(
+ int index, com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) {
+ if (logBuilder_ == null) {
+ ensureLogIsMutable();
+ log_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ logBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder addAllLog(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.LogMessage> values) {
+ if (logBuilder_ == null) {
+ ensureLogIsMutable();
+ super.addAll(values, log_);
+ onChanged();
+ } else {
+ logBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder clearLog() {
+ if (logBuilder_ == null) {
+ log_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00002000);
+ onChanged();
+ } else {
+ logBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public Builder removeLog(int index) {
+ if (logBuilder_ == null) {
+ ensureLogIsMutable();
+ log_.remove(index);
+ onChanged();
+ } else {
+ logBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessage.Builder getLogBuilder(
+ int index) {
+ return getLogFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder(
+ int index) {
+ if (logBuilder_ == null) {
+ return log_.get(index); } else {
+ return logBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>
+ getLogOrBuilderList() {
+ if (logBuilder_ != null) {
+ return logBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(log_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessage.Builder addLogBuilder() {
+ return getLogFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.LogMessage.Builder addLogBuilder(
+ int index) {
+ return getLogFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.LogMessage log = 1001;</code>
+ *
+ * <pre>
+ * Log for a test module. May contain multiple logs such as logcat, host log,
+ * etc.
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage.Builder>
+ getLogBuilderList() {
+ return getLogFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>
+ getLogFieldBuilder() {
+ if (logBuilder_ == null) {
+ logBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>(
+ log_,
+ ((bitField0_ & 0x00002000) == 0x00002000),
+ getParentForChildren(),
+ isClean());
+ log_ = null;
+ }
+ return logBuilder_;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.TestReportMessage)
+ }
+
+ static {
+ defaultInstance = new TestReportMessage(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.TestReportMessage)
+ }
+
+ public interface TestPlanReportMessageOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // repeated string test_module_name = 11;
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ java.util.List<java.lang.String>
+ getTestModuleNameList();
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ int getTestModuleNameCount();
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ java.lang.String getTestModuleName(int index);
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ com.google.protobuf.ByteString
+ getTestModuleNameBytes(int index);
+
+ // repeated int64 test_module_start_timestamp = 12;
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ java.util.List<java.lang.Long> getTestModuleStartTimestampList();
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ int getTestModuleStartTimestampCount();
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ long getTestModuleStartTimestamp(int index);
+
+ // optional string test_plan_name = 21;
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ boolean hasTestPlanName();
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ java.lang.String getTestPlanName();
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ com.google.protobuf.ByteString
+ getTestPlanNameBytes();
+
+ // repeated .android.vts.UrlResourceMessage partner_report = 31;
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage>
+ getPartnerReportList();
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage getPartnerReport(int index);
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ int getPartnerReportCount();
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder>
+ getPartnerReportOrBuilderList();
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder getPartnerReportOrBuilder(
+ int index);
+ }
+ /**
+ * Protobuf type {@code android.vts.TestPlanReportMessage}
+ *
+ * <pre>
+ * To specify a test execution report.
+ * </pre>
+ */
+ public static final class TestPlanReportMessage extends
+ com.google.protobuf.GeneratedMessage
+ implements TestPlanReportMessageOrBuilder {
+ // Use TestPlanReportMessage.newBuilder() to construct.
+ private TestPlanReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private TestPlanReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final TestPlanReportMessage defaultInstance;
+ public static TestPlanReportMessage getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public TestPlanReportMessage getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private TestPlanReportMessage(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 90: {
+ if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+ testModuleName_ = new com.google.protobuf.LazyStringArrayList();
+ mutable_bitField0_ |= 0x00000001;
+ }
+ testModuleName_.add(input.readBytes());
+ break;
+ }
+ case 96: {
+ if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+ testModuleStartTimestamp_ = new java.util.ArrayList<java.lang.Long>();
+ mutable_bitField0_ |= 0x00000002;
+ }
+ testModuleStartTimestamp_.add(input.readInt64());
+ break;
+ }
+ case 98: {
+ int length = input.readRawVarint32();
+ int limit = input.pushLimit(length);
+ if (!((mutable_bitField0_ & 0x00000002) == 0x00000002) && input.getBytesUntilLimit() > 0) {
+ testModuleStartTimestamp_ = new java.util.ArrayList<java.lang.Long>();
+ mutable_bitField0_ |= 0x00000002;
+ }
+ while (input.getBytesUntilLimit() > 0) {
+ testModuleStartTimestamp_.add(input.readInt64());
+ }
+ input.popLimit(limit);
+ break;
+ }
+ case 170: {
+ bitField0_ |= 0x00000001;
+ testPlanName_ = input.readBytes();
+ break;
+ }
+ case 250: {
+ if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+ partnerReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.UrlResourceMessage>();
+ mutable_bitField0_ |= 0x00000008;
+ }
+ partnerReport_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.UrlResourceMessage.PARSER, extensionRegistry));
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+ testModuleName_ = new com.google.protobuf.UnmodifiableLazyStringList(testModuleName_);
+ }
+ if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+ testModuleStartTimestamp_ = java.util.Collections.unmodifiableList(testModuleStartTimestamp_);
+ }
+ if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+ partnerReport_ = java.util.Collections.unmodifiableList(partnerReport_);
+ }
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestPlanReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestPlanReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.class, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<TestPlanReportMessage> PARSER =
+ new com.google.protobuf.AbstractParser<TestPlanReportMessage>() {
+ public TestPlanReportMessage parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new TestPlanReportMessage(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<TestPlanReportMessage> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // repeated string test_module_name = 11;
+ public static final int TEST_MODULE_NAME_FIELD_NUMBER = 11;
+ private com.google.protobuf.LazyStringList testModuleName_;
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public java.util.List<java.lang.String>
+ getTestModuleNameList() {
+ return testModuleName_;
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public int getTestModuleNameCount() {
+ return testModuleName_.size();
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public java.lang.String getTestModuleName(int index) {
+ return testModuleName_.get(index);
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString
+ getTestModuleNameBytes(int index) {
+ return testModuleName_.getByteString(index);
+ }
+
+ // repeated int64 test_module_start_timestamp = 12;
+ public static final int TEST_MODULE_START_TIMESTAMP_FIELD_NUMBER = 12;
+ private java.util.List<java.lang.Long> testModuleStartTimestamp_;
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ public java.util.List<java.lang.Long>
+ getTestModuleStartTimestampList() {
+ return testModuleStartTimestamp_;
+ }
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ public int getTestModuleStartTimestampCount() {
+ return testModuleStartTimestamp_.size();
+ }
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ public long getTestModuleStartTimestamp(int index) {
+ return testModuleStartTimestamp_.get(index);
+ }
+
+ // optional string test_plan_name = 21;
+ public static final int TEST_PLAN_NAME_FIELD_NUMBER = 21;
+ private java.lang.Object testPlanName_;
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ public boolean hasTestPlanName() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ public java.lang.String getTestPlanName() {
+ java.lang.Object ref = testPlanName_;
+ if (ref instanceof java.lang.String) {
+ return (java.lang.String) ref;
+ } else {
+ com.google.protobuf.ByteString bs =
+ (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ if (bs.isValidUtf8()) {
+ testPlanName_ = s;
+ }
+ return s;
+ }
+ }
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString
+ getTestPlanNameBytes() {
+ java.lang.Object ref = testPlanName_;
+ if (ref instanceof java.lang.String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ testPlanName_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+
+ // repeated .android.vts.UrlResourceMessage partner_report = 31;
+ public static final int PARTNER_REPORT_FIELD_NUMBER = 31;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage> partnerReport_;
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage> getPartnerReportList() {
+ return partnerReport_;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder>
+ getPartnerReportOrBuilderList() {
+ return partnerReport_;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public int getPartnerReportCount() {
+ return partnerReport_.size();
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.UrlResourceMessage getPartnerReport(int index) {
+ return partnerReport_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder getPartnerReportOrBuilder(
+ int index) {
+ return partnerReport_.get(index);
+ }
+
+ private void initFields() {
+ testModuleName_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+ testModuleStartTimestamp_ = java.util.Collections.emptyList();
+ testPlanName_ = "";
+ partnerReport_ = java.util.Collections.emptyList();
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ for (int i = 0; i < testModuleName_.size(); i++) {
+ output.writeBytes(11, testModuleName_.getByteString(i));
+ }
+ for (int i = 0; i < testModuleStartTimestamp_.size(); i++) {
+ output.writeInt64(12, testModuleStartTimestamp_.get(i));
+ }
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(21, getTestPlanNameBytes());
+ }
+ for (int i = 0; i < partnerReport_.size(); i++) {
+ output.writeMessage(31, partnerReport_.get(i));
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ {
+ int dataSize = 0;
+ for (int i = 0; i < testModuleName_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeBytesSizeNoTag(testModuleName_.getByteString(i));
+ }
+ size += dataSize;
+ size += 1 * getTestModuleNameList().size();
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < testModuleStartTimestamp_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeInt64SizeNoTag(testModuleStartTimestamp_.get(i));
+ }
+ size += dataSize;
+ size += 1 * getTestModuleStartTimestampList().size();
+ }
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(21, getTestPlanNameBytes());
+ }
+ for (int i = 0; i < partnerReport_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(31, partnerReport_.get(i));
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.TestPlanReportMessage prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.TestPlanReportMessage}
+ *
+ * <pre>
+ * To specify a test execution report.
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestPlanReportMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestPlanReportMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.class, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ getPartnerReportFieldBuilder();
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ testModuleName_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ testModuleStartTimestamp_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000002);
+ testPlanName_ = "";
+ bitField0_ = (bitField0_ & ~0x00000004);
+ if (partnerReportBuilder_ == null) {
+ partnerReport_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000008);
+ } else {
+ partnerReportBuilder_.clear();
+ }
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestPlanReportMessage_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage build() {
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage buildPartial() {
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage result = new com.android.vts.proto.VtsReportMessage.TestPlanReportMessage(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ testModuleName_ = new com.google.protobuf.UnmodifiableLazyStringList(
+ testModuleName_);
+ bitField0_ = (bitField0_ & ~0x00000001);
+ }
+ result.testModuleName_ = testModuleName_;
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ testModuleStartTimestamp_ = java.util.Collections.unmodifiableList(testModuleStartTimestamp_);
+ bitField0_ = (bitField0_ & ~0x00000002);
+ }
+ result.testModuleStartTimestamp_ = testModuleStartTimestamp_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.testPlanName_ = testPlanName_;
+ if (partnerReportBuilder_ == null) {
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ partnerReport_ = java.util.Collections.unmodifiableList(partnerReport_);
+ bitField0_ = (bitField0_ & ~0x00000008);
+ }
+ result.partnerReport_ = partnerReport_;
+ } else {
+ result.partnerReport_ = partnerReportBuilder_.build();
+ }
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.TestPlanReportMessage) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.TestPlanReportMessage)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.TestPlanReportMessage other) {
+ if (other == com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.getDefaultInstance()) return this;
+ if (!other.testModuleName_.isEmpty()) {
+ if (testModuleName_.isEmpty()) {
+ testModuleName_ = other.testModuleName_;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ } else {
+ ensureTestModuleNameIsMutable();
+ testModuleName_.addAll(other.testModuleName_);
+ }
+ onChanged();
+ }
+ if (!other.testModuleStartTimestamp_.isEmpty()) {
+ if (testModuleStartTimestamp_.isEmpty()) {
+ testModuleStartTimestamp_ = other.testModuleStartTimestamp_;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ } else {
+ ensureTestModuleStartTimestampIsMutable();
+ testModuleStartTimestamp_.addAll(other.testModuleStartTimestamp_);
+ }
+ onChanged();
+ }
+ if (other.hasTestPlanName()) {
+ bitField0_ |= 0x00000004;
+ testPlanName_ = other.testPlanName_;
+ onChanged();
+ }
+ if (partnerReportBuilder_ == null) {
+ if (!other.partnerReport_.isEmpty()) {
+ if (partnerReport_.isEmpty()) {
+ partnerReport_ = other.partnerReport_;
+ bitField0_ = (bitField0_ & ~0x00000008);
+ } else {
+ ensurePartnerReportIsMutable();
+ partnerReport_.addAll(other.partnerReport_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.partnerReport_.isEmpty()) {
+ if (partnerReportBuilder_.isEmpty()) {
+ partnerReportBuilder_.dispose();
+ partnerReportBuilder_ = null;
+ partnerReport_ = other.partnerReport_;
+ bitField0_ = (bitField0_ & ~0x00000008);
+ partnerReportBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getPartnerReportFieldBuilder() : null;
+ } else {
+ partnerReportBuilder_.addAllMessages(other.partnerReport_);
+ }
+ }
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.TestPlanReportMessage) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // repeated string test_module_name = 11;
+ private com.google.protobuf.LazyStringList testModuleName_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+ private void ensureTestModuleNameIsMutable() {
+ if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+ testModuleName_ = new com.google.protobuf.LazyStringArrayList(testModuleName_);
+ bitField0_ |= 0x00000001;
+ }
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public java.util.List<java.lang.String>
+ getTestModuleNameList() {
+ return java.util.Collections.unmodifiableList(testModuleName_);
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public int getTestModuleNameCount() {
+ return testModuleName_.size();
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public java.lang.String getTestModuleName(int index) {
+ return testModuleName_.get(index);
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString
+ getTestModuleNameBytes(int index) {
+ return testModuleName_.getByteString(index);
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public Builder setTestModuleName(
+ int index, java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestModuleNameIsMutable();
+ testModuleName_.set(index, value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public Builder addTestModuleName(
+ java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestModuleNameIsMutable();
+ testModuleName_.add(value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public Builder addAllTestModuleName(
+ java.lang.Iterable<java.lang.String> values) {
+ ensureTestModuleNameIsMutable();
+ super.addAll(values, testModuleName_);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public Builder clearTestModuleName() {
+ testModuleName_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated string test_module_name = 11;</code>
+ *
+ * <pre>
+ * Keys used to find all TestReportMessage messages of test modules in
+ * this plan.
+ * </pre>
+ */
+ public Builder addTestModuleNameBytes(
+ com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestModuleNameIsMutable();
+ testModuleName_.add(value);
+ onChanged();
+ return this;
+ }
+
+ // repeated int64 test_module_start_timestamp = 12;
+ private java.util.List<java.lang.Long> testModuleStartTimestamp_ = java.util.Collections.emptyList();
+ private void ensureTestModuleStartTimestampIsMutable() {
+ if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+ testModuleStartTimestamp_ = new java.util.ArrayList<java.lang.Long>(testModuleStartTimestamp_);
+ bitField0_ |= 0x00000002;
+ }
+ }
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ public java.util.List<java.lang.Long>
+ getTestModuleStartTimestampList() {
+ return java.util.Collections.unmodifiableList(testModuleStartTimestamp_);
+ }
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ public int getTestModuleStartTimestampCount() {
+ return testModuleStartTimestamp_.size();
+ }
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ public long getTestModuleStartTimestamp(int index) {
+ return testModuleStartTimestamp_.get(index);
+ }
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ public Builder setTestModuleStartTimestamp(
+ int index, long value) {
+ ensureTestModuleStartTimestampIsMutable();
+ testModuleStartTimestamp_.set(index, value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ public Builder addTestModuleStartTimestamp(long value) {
+ ensureTestModuleStartTimestampIsMutable();
+ testModuleStartTimestamp_.add(value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ public Builder addAllTestModuleStartTimestamp(
+ java.lang.Iterable<? extends java.lang.Long> values) {
+ ensureTestModuleStartTimestampIsMutable();
+ super.addAll(values, testModuleStartTimestamp_);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated int64 test_module_start_timestamp = 12;</code>
+ */
+ public Builder clearTestModuleStartTimestamp() {
+ testModuleStartTimestamp_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000002);
+ onChanged();
+ return this;
+ }
+
+ // optional string test_plan_name = 21;
+ private java.lang.Object testPlanName_ = "";
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ public boolean hasTestPlanName() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ public java.lang.String getTestPlanName() {
+ java.lang.Object ref = testPlanName_;
+ if (!(ref instanceof java.lang.String)) {
+ java.lang.String s = ((com.google.protobuf.ByteString) ref)
+ .toStringUtf8();
+ testPlanName_ = s;
+ return s;
+ } else {
+ return (java.lang.String) ref;
+ }
+ }
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ public com.google.protobuf.ByteString
+ getTestPlanNameBytes() {
+ java.lang.Object ref = testPlanName_;
+ if (ref instanceof String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ testPlanName_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ public Builder setTestPlanName(
+ java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000004;
+ testPlanName_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ public Builder clearTestPlanName() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ testPlanName_ = getDefaultInstance().getTestPlanName();
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional string test_plan_name = 21;</code>
+ *
+ * <pre>
+ * The test plan name.
+ * </pre>
+ */
+ public Builder setTestPlanNameBytes(
+ com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000004;
+ testPlanName_ = value;
+ onChanged();
+ return this;
+ }
+
+ // repeated .android.vts.UrlResourceMessage partner_report = 31;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage> partnerReport_ =
+ java.util.Collections.emptyList();
+ private void ensurePartnerReportIsMutable() {
+ if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+ partnerReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.UrlResourceMessage>(partnerReport_);
+ bitField0_ |= 0x00000008;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder, com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder> partnerReportBuilder_;
+
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage> getPartnerReportList() {
+ if (partnerReportBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(partnerReport_);
+ } else {
+ return partnerReportBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public int getPartnerReportCount() {
+ if (partnerReportBuilder_ == null) {
+ return partnerReport_.size();
+ } else {
+ return partnerReportBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.UrlResourceMessage getPartnerReport(int index) {
+ if (partnerReportBuilder_ == null) {
+ return partnerReport_.get(index);
+ } else {
+ return partnerReportBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public Builder setPartnerReport(
+ int index, com.android.vts.proto.VtsReportMessage.UrlResourceMessage value) {
+ if (partnerReportBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensurePartnerReportIsMutable();
+ partnerReport_.set(index, value);
+ onChanged();
+ } else {
+ partnerReportBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public Builder setPartnerReport(
+ int index, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder builderForValue) {
+ if (partnerReportBuilder_ == null) {
+ ensurePartnerReportIsMutable();
+ partnerReport_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ partnerReportBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public Builder addPartnerReport(com.android.vts.proto.VtsReportMessage.UrlResourceMessage value) {
+ if (partnerReportBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensurePartnerReportIsMutable();
+ partnerReport_.add(value);
+ onChanged();
+ } else {
+ partnerReportBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public Builder addPartnerReport(
+ int index, com.android.vts.proto.VtsReportMessage.UrlResourceMessage value) {
+ if (partnerReportBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensurePartnerReportIsMutable();
+ partnerReport_.add(index, value);
+ onChanged();
+ } else {
+ partnerReportBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public Builder addPartnerReport(
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder builderForValue) {
+ if (partnerReportBuilder_ == null) {
+ ensurePartnerReportIsMutable();
+ partnerReport_.add(builderForValue.build());
+ onChanged();
+ } else {
+ partnerReportBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public Builder addPartnerReport(
+ int index, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder builderForValue) {
+ if (partnerReportBuilder_ == null) {
+ ensurePartnerReportIsMutable();
+ partnerReport_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ partnerReportBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public Builder addAllPartnerReport(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.UrlResourceMessage> values) {
+ if (partnerReportBuilder_ == null) {
+ ensurePartnerReportIsMutable();
+ super.addAll(values, partnerReport_);
+ onChanged();
+ } else {
+ partnerReportBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public Builder clearPartnerReport() {
+ if (partnerReportBuilder_ == null) {
+ partnerReport_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000008);
+ onChanged();
+ } else {
+ partnerReportBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public Builder removePartnerReport(int index) {
+ if (partnerReportBuilder_ == null) {
+ ensurePartnerReportIsMutable();
+ partnerReport_.remove(index);
+ onChanged();
+ } else {
+ partnerReportBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder getPartnerReportBuilder(
+ int index) {
+ return getPartnerReportFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder getPartnerReportOrBuilder(
+ int index) {
+ if (partnerReportBuilder_ == null) {
+ return partnerReport_.get(index); } else {
+ return partnerReportBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder>
+ getPartnerReportOrBuilderList() {
+ if (partnerReportBuilder_ != null) {
+ return partnerReportBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(partnerReport_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder addPartnerReportBuilder() {
+ return getPartnerReportFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder addPartnerReportBuilder(
+ int index) {
+ return getPartnerReportFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code>
+ *
+ * <pre>
+ * Report resource flies.
+ * </pre>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder>
+ getPartnerReportBuilderList() {
+ return getPartnerReportFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder, com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder>
+ getPartnerReportFieldBuilder() {
+ if (partnerReportBuilder_ == null) {
+ partnerReportBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.UrlResourceMessage, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder, com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder>(
+ partnerReport_,
+ ((bitField0_ & 0x00000008) == 0x00000008),
+ getParentForChildren(),
+ isClean());
+ partnerReport_ = null;
+ }
+ return partnerReportBuilder_;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.TestPlanReportMessage)
+ }
+
+ static {
+ defaultInstance = new TestPlanReportMessage(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.TestPlanReportMessage)
+ }
+
+ public interface DashboardPostMessageOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional string access_token = 1;
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ boolean hasAccessToken();
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ java.lang.String getAccessToken();
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ com.google.protobuf.ByteString
+ getAccessTokenBytes();
+
+ // repeated .android.vts.TestReportMessage test_report = 2;
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage>
+ getTestReportList();
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ com.android.vts.proto.VtsReportMessage.TestReportMessage getTestReport(int index);
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ int getTestReportCount();
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder>
+ getTestReportOrBuilderList();
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder getTestReportOrBuilder(
+ int index);
+
+ // repeated .android.vts.TestPlanReportMessage test_plan_report = 3;
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage>
+ getTestPlanReportList();
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage getTestPlanReport(int index);
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ int getTestPlanReportCount();
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder>
+ getTestPlanReportOrBuilderList();
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder getTestPlanReportOrBuilder(
+ int index);
+ }
+ /**
+ * Protobuf type {@code android.vts.DashboardPostMessage}
+ *
+ * <pre>
+ * Proto wrapper for posting data to the VTS Dashboard
+ * </pre>
+ */
+ public static final class DashboardPostMessage extends
+ com.google.protobuf.GeneratedMessage
+ implements DashboardPostMessageOrBuilder {
+ // Use DashboardPostMessage.newBuilder() to construct.
+ private DashboardPostMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private DashboardPostMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final DashboardPostMessage defaultInstance;
+ public static DashboardPostMessage getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public DashboardPostMessage getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final com.google.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private DashboardPostMessage(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ accessToken_ = input.readBytes();
+ break;
+ }
+ case 18: {
+ if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+ testReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestReportMessage>();
+ mutable_bitField0_ |= 0x00000002;
+ }
+ testReport_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.TestReportMessage.PARSER, extensionRegistry));
+ break;
+ }
+ case 26: {
+ if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+ testPlanReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage>();
+ mutable_bitField0_ |= 0x00000004;
+ }
+ testPlanReport_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.PARSER, extensionRegistry));
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+ testReport_ = java.util.Collections.unmodifiableList(testReport_);
+ }
+ if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+ testPlanReport_ = java.util.Collections.unmodifiableList(testPlanReport_);
+ }
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_DashboardPostMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_DashboardPostMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.DashboardPostMessage.class, com.android.vts.proto.VtsReportMessage.DashboardPostMessage.Builder.class);
+ }
+
+ public static com.google.protobuf.Parser<DashboardPostMessage> PARSER =
+ new com.google.protobuf.AbstractParser<DashboardPostMessage>() {
+ public DashboardPostMessage parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new DashboardPostMessage(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<DashboardPostMessage> getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional string access_token = 1;
+ public static final int ACCESS_TOKEN_FIELD_NUMBER = 1;
+ private java.lang.Object accessToken_;
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ public boolean hasAccessToken() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ public java.lang.String getAccessToken() {
+ java.lang.Object ref = accessToken_;
+ if (ref instanceof java.lang.String) {
+ return (java.lang.String) ref;
+ } else {
+ com.google.protobuf.ByteString bs =
+ (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ if (bs.isValidUtf8()) {
+ accessToken_ = s;
+ }
+ return s;
+ }
+ }
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ public com.google.protobuf.ByteString
+ getAccessTokenBytes() {
+ java.lang.Object ref = accessToken_;
+ if (ref instanceof java.lang.String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ accessToken_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+
+ // repeated .android.vts.TestReportMessage test_report = 2;
+ public static final int TEST_REPORT_FIELD_NUMBER = 2;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage> testReport_;
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage> getTestReportList() {
+ return testReport_;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder>
+ getTestReportOrBuilderList() {
+ return testReport_;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public int getTestReportCount() {
+ return testReport_.size();
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestReportMessage getTestReport(int index) {
+ return testReport_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder getTestReportOrBuilder(
+ int index) {
+ return testReport_.get(index);
+ }
+
+ // repeated .android.vts.TestPlanReportMessage test_plan_report = 3;
+ public static final int TEST_PLAN_REPORT_FIELD_NUMBER = 3;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> testPlanReport_;
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> getTestPlanReportList() {
+ return testPlanReport_;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder>
+ getTestPlanReportOrBuilderList() {
+ return testPlanReport_;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public int getTestPlanReportCount() {
+ return testPlanReport_.size();
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage getTestPlanReport(int index) {
+ return testPlanReport_.get(index);
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder getTestPlanReportOrBuilder(
+ int index) {
+ return testPlanReport_.get(index);
+ }
+
+ private void initFields() {
+ accessToken_ = "";
+ testReport_ = java.util.Collections.emptyList();
+ testPlanReport_ = java.util.Collections.emptyList();
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, getAccessTokenBytes());
+ }
+ for (int i = 0; i < testReport_.size(); i++) {
+ output.writeMessage(2, testReport_.get(i));
+ }
+ for (int i = 0; i < testPlanReport_.size(); i++) {
+ output.writeMessage(3, testPlanReport_.get(i));
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, getAccessTokenBytes());
+ }
+ for (int i = 0; i < testReport_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(2, testReport_.get(i));
+ }
+ for (int i = 0; i < testPlanReport_.size(); i++) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(3, testPlanReport_.get(i));
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.DashboardPostMessage prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code android.vts.DashboardPostMessage}
+ *
+ * <pre>
+ * Proto wrapper for posting data to the VTS Dashboard
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder>
+ implements com.android.vts.proto.VtsReportMessage.DashboardPostMessageOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_DashboardPostMessage_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_DashboardPostMessage_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.android.vts.proto.VtsReportMessage.DashboardPostMessage.class, com.android.vts.proto.VtsReportMessage.DashboardPostMessage.Builder.class);
+ }
+
+ // Construct using com.android.vts.proto.VtsReportMessage.DashboardPostMessage.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ getTestReportFieldBuilder();
+ getTestPlanReportFieldBuilder();
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ accessToken_ = "";
+ bitField0_ = (bitField0_ & ~0x00000001);
+ if (testReportBuilder_ == null) {
+ testReport_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000002);
+ } else {
+ testReportBuilder_.clear();
+ }
+ if (testPlanReportBuilder_ == null) {
+ testPlanReport_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000004);
+ } else {
+ testPlanReportBuilder_.clear();
+ }
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_DashboardPostMessage_descriptor;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.DashboardPostMessage getDefaultInstanceForType() {
+ return com.android.vts.proto.VtsReportMessage.DashboardPostMessage.getDefaultInstance();
+ }
+
+ public com.android.vts.proto.VtsReportMessage.DashboardPostMessage build() {
+ com.android.vts.proto.VtsReportMessage.DashboardPostMessage result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.android.vts.proto.VtsReportMessage.DashboardPostMessage buildPartial() {
+ com.android.vts.proto.VtsReportMessage.DashboardPostMessage result = new com.android.vts.proto.VtsReportMessage.DashboardPostMessage(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.accessToken_ = accessToken_;
+ if (testReportBuilder_ == null) {
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ testReport_ = java.util.Collections.unmodifiableList(testReport_);
+ bitField0_ = (bitField0_ & ~0x00000002);
+ }
+ result.testReport_ = testReport_;
+ } else {
+ result.testReport_ = testReportBuilder_.build();
+ }
+ if (testPlanReportBuilder_ == null) {
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ testPlanReport_ = java.util.Collections.unmodifiableList(testPlanReport_);
+ bitField0_ = (bitField0_ & ~0x00000004);
+ }
+ result.testPlanReport_ = testPlanReport_;
+ } else {
+ result.testPlanReport_ = testPlanReportBuilder_.build();
+ }
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.android.vts.proto.VtsReportMessage.DashboardPostMessage) {
+ return mergeFrom((com.android.vts.proto.VtsReportMessage.DashboardPostMessage)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.DashboardPostMessage other) {
+ if (other == com.android.vts.proto.VtsReportMessage.DashboardPostMessage.getDefaultInstance()) return this;
+ if (other.hasAccessToken()) {
+ bitField0_ |= 0x00000001;
+ accessToken_ = other.accessToken_;
+ onChanged();
+ }
+ if (testReportBuilder_ == null) {
+ if (!other.testReport_.isEmpty()) {
+ if (testReport_.isEmpty()) {
+ testReport_ = other.testReport_;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ } else {
+ ensureTestReportIsMutable();
+ testReport_.addAll(other.testReport_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.testReport_.isEmpty()) {
+ if (testReportBuilder_.isEmpty()) {
+ testReportBuilder_.dispose();
+ testReportBuilder_ = null;
+ testReport_ = other.testReport_;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ testReportBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getTestReportFieldBuilder() : null;
+ } else {
+ testReportBuilder_.addAllMessages(other.testReport_);
+ }
+ }
+ }
+ if (testPlanReportBuilder_ == null) {
+ if (!other.testPlanReport_.isEmpty()) {
+ if (testPlanReport_.isEmpty()) {
+ testPlanReport_ = other.testPlanReport_;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ } else {
+ ensureTestPlanReportIsMutable();
+ testPlanReport_.addAll(other.testPlanReport_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.testPlanReport_.isEmpty()) {
+ if (testPlanReportBuilder_.isEmpty()) {
+ testPlanReportBuilder_.dispose();
+ testPlanReportBuilder_ = null;
+ testPlanReport_ = other.testPlanReport_;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ testPlanReportBuilder_ =
+ com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getTestPlanReportFieldBuilder() : null;
+ } else {
+ testPlanReportBuilder_.addAllMessages(other.testPlanReport_);
+ }
+ }
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.android.vts.proto.VtsReportMessage.DashboardPostMessage parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.android.vts.proto.VtsReportMessage.DashboardPostMessage) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional string access_token = 1;
+ private java.lang.Object accessToken_ = "";
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ public boolean hasAccessToken() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ public java.lang.String getAccessToken() {
+ java.lang.Object ref = accessToken_;
+ if (!(ref instanceof java.lang.String)) {
+ java.lang.String s = ((com.google.protobuf.ByteString) ref)
+ .toStringUtf8();
+ accessToken_ = s;
+ return s;
+ } else {
+ return (java.lang.String) ref;
+ }
+ }
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ public com.google.protobuf.ByteString
+ getAccessTokenBytes() {
+ java.lang.Object ref = accessToken_;
+ if (ref instanceof String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ accessToken_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ public Builder setAccessToken(
+ java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ accessToken_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ public Builder clearAccessToken() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ accessToken_ = getDefaultInstance().getAccessToken();
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional string access_token = 1;</code>
+ *
+ * <pre>
+ * oauth2.0 access token
+ * </pre>
+ */
+ public Builder setAccessTokenBytes(
+ com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ accessToken_ = value;
+ onChanged();
+ return this;
+ }
+
+ // repeated .android.vts.TestReportMessage test_report = 2;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage> testReport_ =
+ java.util.Collections.emptyList();
+ private void ensureTestReportIsMutable() {
+ if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+ testReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestReportMessage>(testReport_);
+ bitField0_ |= 0x00000002;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.TestReportMessage, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder> testReportBuilder_;
+
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage> getTestReportList() {
+ if (testReportBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(testReport_);
+ } else {
+ return testReportBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public int getTestReportCount() {
+ if (testReportBuilder_ == null) {
+ return testReport_.size();
+ } else {
+ return testReportBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestReportMessage getTestReport(int index) {
+ if (testReportBuilder_ == null) {
+ return testReport_.get(index);
+ } else {
+ return testReportBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public Builder setTestReport(
+ int index, com.android.vts.proto.VtsReportMessage.TestReportMessage value) {
+ if (testReportBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestReportIsMutable();
+ testReport_.set(index, value);
+ onChanged();
+ } else {
+ testReportBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public Builder setTestReport(
+ int index, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder builderForValue) {
+ if (testReportBuilder_ == null) {
+ ensureTestReportIsMutable();
+ testReport_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ testReportBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public Builder addTestReport(com.android.vts.proto.VtsReportMessage.TestReportMessage value) {
+ if (testReportBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestReportIsMutable();
+ testReport_.add(value);
+ onChanged();
+ } else {
+ testReportBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public Builder addTestReport(
+ int index, com.android.vts.proto.VtsReportMessage.TestReportMessage value) {
+ if (testReportBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestReportIsMutable();
+ testReport_.add(index, value);
+ onChanged();
+ } else {
+ testReportBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public Builder addTestReport(
+ com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder builderForValue) {
+ if (testReportBuilder_ == null) {
+ ensureTestReportIsMutable();
+ testReport_.add(builderForValue.build());
+ onChanged();
+ } else {
+ testReportBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public Builder addTestReport(
+ int index, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder builderForValue) {
+ if (testReportBuilder_ == null) {
+ ensureTestReportIsMutable();
+ testReport_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ testReportBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public Builder addAllTestReport(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.TestReportMessage> values) {
+ if (testReportBuilder_ == null) {
+ ensureTestReportIsMutable();
+ super.addAll(values, testReport_);
+ onChanged();
+ } else {
+ testReportBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public Builder clearTestReport() {
+ if (testReportBuilder_ == null) {
+ testReport_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000002);
+ onChanged();
+ } else {
+ testReportBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public Builder removeTestReport(int index) {
+ if (testReportBuilder_ == null) {
+ ensureTestReportIsMutable();
+ testReport_.remove(index);
+ onChanged();
+ } else {
+ testReportBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder getTestReportBuilder(
+ int index) {
+ return getTestReportFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder getTestReportOrBuilder(
+ int index) {
+ if (testReportBuilder_ == null) {
+ return testReport_.get(index); } else {
+ return testReportBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder>
+ getTestReportOrBuilderList() {
+ if (testReportBuilder_ != null) {
+ return testReportBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(testReport_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder addTestReportBuilder() {
+ return getTestReportFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.TestReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder addTestReportBuilder(
+ int index) {
+ return getTestReportFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.TestReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.TestReportMessage test_report = 2;</code>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder>
+ getTestReportBuilderList() {
+ return getTestReportFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.TestReportMessage, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder>
+ getTestReportFieldBuilder() {
+ if (testReportBuilder_ == null) {
+ testReportBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.TestReportMessage, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder>(
+ testReport_,
+ ((bitField0_ & 0x00000002) == 0x00000002),
+ getParentForChildren(),
+ isClean());
+ testReport_ = null;
+ }
+ return testReportBuilder_;
+ }
+
+ // repeated .android.vts.TestPlanReportMessage test_plan_report = 3;
+ private java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> testPlanReport_ =
+ java.util.Collections.emptyList();
+ private void ensureTestPlanReportIsMutable() {
+ if (!((bitField0_ & 0x00000004) == 0x00000004)) {
+ testPlanReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage>(testPlanReport_);
+ bitField0_ |= 0x00000004;
+ }
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder> testPlanReportBuilder_;
+
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> getTestPlanReportList() {
+ if (testPlanReportBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(testPlanReport_);
+ } else {
+ return testPlanReportBuilder_.getMessageList();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public int getTestPlanReportCount() {
+ if (testPlanReportBuilder_ == null) {
+ return testPlanReport_.size();
+ } else {
+ return testPlanReportBuilder_.getCount();
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage getTestPlanReport(int index) {
+ if (testPlanReportBuilder_ == null) {
+ return testPlanReport_.get(index);
+ } else {
+ return testPlanReportBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public Builder setTestPlanReport(
+ int index, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage value) {
+ if (testPlanReportBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestPlanReportIsMutable();
+ testPlanReport_.set(index, value);
+ onChanged();
+ } else {
+ testPlanReportBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public Builder setTestPlanReport(
+ int index, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder builderForValue) {
+ if (testPlanReportBuilder_ == null) {
+ ensureTestPlanReportIsMutable();
+ testPlanReport_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ testPlanReportBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public Builder addTestPlanReport(com.android.vts.proto.VtsReportMessage.TestPlanReportMessage value) {
+ if (testPlanReportBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestPlanReportIsMutable();
+ testPlanReport_.add(value);
+ onChanged();
+ } else {
+ testPlanReportBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public Builder addTestPlanReport(
+ int index, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage value) {
+ if (testPlanReportBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTestPlanReportIsMutable();
+ testPlanReport_.add(index, value);
+ onChanged();
+ } else {
+ testPlanReportBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public Builder addTestPlanReport(
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder builderForValue) {
+ if (testPlanReportBuilder_ == null) {
+ ensureTestPlanReportIsMutable();
+ testPlanReport_.add(builderForValue.build());
+ onChanged();
+ } else {
+ testPlanReportBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public Builder addTestPlanReport(
+ int index, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder builderForValue) {
+ if (testPlanReportBuilder_ == null) {
+ ensureTestPlanReportIsMutable();
+ testPlanReport_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ testPlanReportBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public Builder addAllTestPlanReport(
+ java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> values) {
+ if (testPlanReportBuilder_ == null) {
+ ensureTestPlanReportIsMutable();
+ super.addAll(values, testPlanReport_);
+ onChanged();
+ } else {
+ testPlanReportBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public Builder clearTestPlanReport() {
+ if (testPlanReportBuilder_ == null) {
+ testPlanReport_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000004);
+ onChanged();
+ } else {
+ testPlanReportBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public Builder removeTestPlanReport(int index) {
+ if (testPlanReportBuilder_ == null) {
+ ensureTestPlanReportIsMutable();
+ testPlanReport_.remove(index);
+ onChanged();
+ } else {
+ testPlanReportBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder getTestPlanReportBuilder(
+ int index) {
+ return getTestPlanReportFieldBuilder().getBuilder(index);
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder getTestPlanReportOrBuilder(
+ int index) {
+ if (testPlanReportBuilder_ == null) {
+ return testPlanReport_.get(index); } else {
+ return testPlanReportBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder>
+ getTestPlanReportOrBuilderList() {
+ if (testPlanReportBuilder_ != null) {
+ return testPlanReportBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(testPlanReport_);
+ }
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder addTestPlanReportBuilder() {
+ return getTestPlanReportFieldBuilder().addBuilder(
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder addTestPlanReportBuilder(
+ int index) {
+ return getTestPlanReportFieldBuilder().addBuilder(
+ index, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.getDefaultInstance());
+ }
+ /**
+ * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code>
+ */
+ public java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder>
+ getTestPlanReportBuilderList() {
+ return getTestPlanReportFieldBuilder().getBuilderList();
+ }
+ private com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder>
+ getTestPlanReportFieldBuilder() {
+ if (testPlanReportBuilder_ == null) {
+ testPlanReportBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+ com.android.vts.proto.VtsReportMessage.TestPlanReportMessage, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder>(
+ testPlanReport_,
+ ((bitField0_ & 0x00000004) == 0x00000004),
+ getParentForChildren(),
+ isClean());
+ testPlanReport_ = null;
+ }
+ return testPlanReportBuilder_;
+ }
+
+ // @@protoc_insertion_point(builder_scope:android.vts.DashboardPostMessage)
+ }
+
+ static {
+ defaultInstance = new DashboardPostMessage(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:android.vts.DashboardPostMessage)
+ }
+
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_AndroidDeviceInfoMessage_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_AndroidDeviceInfoMessage_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_AndroidBuildInfo_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_AndroidBuildInfo_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_VtsHostInfo_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_VtsHostInfo_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_TestCaseReportMessage_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_TestCaseReportMessage_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_ProfilingReportMessage_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_ProfilingReportMessage_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_SystraceReportMessage_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_SystraceReportMessage_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_CoverageReportMessage_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_CoverageReportMessage_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_LogMessage_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_LogMessage_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_UrlResourceMessage_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_UrlResourceMessage_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_TestReportMessage_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_TestReportMessage_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_TestPlanReportMessage_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_TestPlanReportMessage_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_android_vts_DashboardPostMessage_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_android_vts_DashboardPostMessage_fieldAccessorTable;
+
+ public static com.google.protobuf.Descriptors.FileDescriptor
+ getDescriptor() {
+ return descriptor;
+ }
+ private static com.google.protobuf.Descriptors.FileDescriptor
+ descriptor;
+ static {
+ java.lang.String[] descriptorData = {
+ "\n\034proto/VtsReportMessage.proto\022\013android." +
+ "vts\"\340\001\n\030AndroidDeviceInfoMessage\022\024\n\014prod" +
+ "uct_type\030\001 \001(\014\022\027\n\017product_variant\030\002 \001(\014\022" +
+ "\024\n\014build_flavor\030\013 \001(\014\022\020\n\010build_id\030\014 \001(\014\022" +
+ "\016\n\006branch\030\025 \001(\014\022\023\n\013build_alias\030\026 \001(\014\022\021\n\t" +
+ "api_level\030\037 \001(\014\022\020\n\010abi_name\0303 \001(\014\022\023\n\013abi" +
+ "_bitness\0304 \001(\014\022\016\n\006serial\030e \001(\014\"g\n\020Androi" +
+ "dBuildInfo\022\n\n\002id\030\001 \001(\014\022\014\n\004name\030\013 \001(\014\022\022\n\n" +
+ "build_type\030\014 \001(\014\022\016\n\006branch\030\r \001(\014\022\025\n\rbuil" +
+ "d_summary\030\025 \001(\014\"\037\n\013VtsHostInfo\022\020\n\010hostna",
+ "me\030\001 \001(\014\"\321\002\n\025TestCaseReportMessage\022\014\n\004na" +
+ "me\030\001 \001(\014\0220\n\013test_result\030\013 \001(\0162\033.android." +
+ "vts.TestCaseResult\022\027\n\017start_timestamp\030\025 " +
+ "\001(\003\022\025\n\rend_timestamp\030\026 \001(\003\0224\n\010coverage\030\037" +
+ " \003(\0132\".android.vts.CoverageReportMessage" +
+ "\0226\n\tprofiling\030) \003(\0132#.android.vts.Profil" +
+ "ingReportMessage\0224\n\010systrace\030* \003(\0132\".and" +
+ "roid.vts.SystraceReportMessage\022$\n\003log\030e " +
+ "\003(\0132\027.android.vts.LogMessage\"\240\002\n\026Profili" +
+ "ngReportMessage\022\014\n\004name\030\001 \001(\014\022+\n\004type\030\002 ",
+ "\001(\0162\035.android.vts.VtsProfilingType\022@\n\017re" +
+ "gression_mode\030\003 \001(\0162\'.android.vts.VtsPro" +
+ "filingRegressionMode\022\027\n\017start_timestamp\030" +
+ "\013 \001(\003\022\025\n\rend_timestamp\030\014 \001(\003\022\r\n\005label\030\025 " +
+ "\003(\014\022\r\n\005value\030\026 \003(\003\022\024\n\014x_axis_label\030\037 \001(\014" +
+ "\022\024\n\014y_axis_label\030 \001(\014\022\017\n\007options\030) \003(\014\"" +
+ "H\n\025SystraceReportMessage\022\024\n\014process_name" +
+ "\030\001 \001(\014\022\014\n\004html\030\013 \003(\014\022\013\n\003url\030\025 \003(\014\"\345\001\n\025Co" +
+ "verageReportMessage\022\021\n\tfile_path\030\013 \001(\014\022\024" +
+ "\n\014project_name\030\014 \001(\014\022\020\n\010revision\030\r \001(\014\022\034",
+ "\n\024line_coverage_vector\030\027 \003(\005\022\030\n\020total_li" +
+ "ne_count\030e \001(\005\022\032\n\022covered_line_count\030f \001" +
+ "(\005\022\024\n\010dir_path\030\001 \001(\014B\002\030\001\022\025\n\tfile_name\030\002 " +
+ "\001(\014B\002\030\001\022\020\n\004html\030\003 \001(\014B\002\030\001\"8\n\nLogMessage\022" +
+ "\013\n\003url\030\001 \001(\014\022\014\n\004name\030\002 \001(\014\022\017\n\007content\030\003 " +
+ "\001(\014\"@\n\022UrlResourceMessage\022\013\n\003url\030\001 \001(\014\022\014" +
+ "\n\004name\030\002 \001(\014\022\017\n\007content\030\003 \001(\014\"\316\004\n\021TestRe" +
+ "portMessage\022\026\n\ntest_suite\030\001 \001(\014B\002\030\001\022\014\n\004t" +
+ "est\030\002 \001(\014\022+\n\ttest_type\030\003 \001(\0162\030.android.v" +
+ "ts.VtsTestType\022:\n\013device_info\030\004 \003(\0132%.an",
+ "droid.vts.AndroidDeviceInfoMessage\0221\n\nbu" +
+ "ild_info\030\005 \001(\0132\035.android.vts.AndroidBuil" +
+ "dInfo\022\030\n\020subscriber_email\030\006 \003(\014\022+\n\thost_" +
+ "info\030\007 \001(\0132\030.android.vts.VtsHostInfo\0225\n\t" +
+ "test_case\030\013 \003(\0132\".android.vts.TestCaseRe" +
+ "portMessage\0226\n\tprofiling\030\025 \003(\0132#.android" +
+ ".vts.ProfilingReportMessage\0224\n\010systrace\030" +
+ "\026 \003(\0132\".android.vts.SystraceReportMessag" +
+ "e\022\027\n\017start_timestamp\030e \001(\003\022\025\n\rend_timest" +
+ "amp\030f \001(\003\0224\n\010coverage\030g \003(\0132\".android.vt",
+ "s.CoverageReportMessage\022%\n\003log\030\351\007 \003(\0132\027." +
+ "android.vts.LogMessage\"\247\001\n\025TestPlanRepor" +
+ "tMessage\022\030\n\020test_module_name\030\013 \003(\t\022#\n\033te" +
+ "st_module_start_timestamp\030\014 \003(\003\022\026\n\016test_" +
+ "plan_name\030\025 \001(\t\0227\n\016partner_report\030\037 \003(\0132" +
+ "\037.android.vts.UrlResourceMessage\"\237\001\n\024Das" +
+ "hboardPostMessage\022\024\n\014access_token\030\001 \001(\t\022" +
+ "3\n\013test_report\030\002 \003(\0132\036.android.vts.TestR" +
+ "eportMessage\022<\n\020test_plan_report\030\003 \003(\0132\"" +
+ ".android.vts.TestPlanReportMessage*\263\001\n\016T",
+ "estCaseResult\022\022\n\016UNKNOWN_RESULT\020\000\022\031\n\025TES" +
+ "T_CASE_RESULT_PASS\020\001\022\031\n\025TEST_CASE_RESULT" +
+ "_FAIL\020\002\022\031\n\025TEST_CASE_RESULT_SKIP\020\003\022\036\n\032TE" +
+ "ST_CASE_RESULT_EXCEPTION\020\004\022\034\n\030TEST_CASE_" +
+ "RESULT_TIMEOUT\020\005*\234\001\n\013VtsTestType\022\030\n\024UNKN" +
+ "OWN_VTS_TESTTYPE\020\000\022\036\n\032VTS_HOST_DRIVEN_ST" +
+ "RUCTURAL\020\001\022\033\n\027VTS_HOST_DRIVEN_FUZZING\020\002\022" +
+ "\031\n\025VTS_TARGET_SIDE_GTEST\020\003\022\033\n\027VTS_TARGET" +
+ "_SIDE_FUZZING\020\004*\243\001\n\032VtsProfilingRegressi" +
+ "onMode\022\033\n\027UNKNOWN_REGRESSION_MODE\020\000\022 \n\034V",
+ "TS_REGRESSION_MODE_DISABLED\020\001\022\"\n\036VTS_REG" +
+ "RESSION_MODE_INCREASING\020\002\022\"\n\036VTS_REGRESS" +
+ "ION_MODE_DECREASING\020\003*\244\001\n\020VtsProfilingTy" +
+ "pe\022\036\n\032UNKNOWN_VTS_PROFILING_TYPE\020\000\022 \n\034VT" +
+ "S_PROFILING_TYPE_TIMESTAMP\020\001\022%\n!VTS_PROF" +
+ "ILING_TYPE_LABELED_VECTOR\020\002\022\'\n#VTS_PROFI" +
+ "LING_TYPE_UNLABELED_VECTOR\020\003B+\n\025com.andr" +
+ "oid.vts.protoB\020VtsReportMessageP\000"
+ };
+ com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+ new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+ public com.google.protobuf.ExtensionRegistry assignDescriptors(
+ com.google.protobuf.Descriptors.FileDescriptor root) {
+ descriptor = root;
+ internal_static_android_vts_AndroidDeviceInfoMessage_descriptor =
+ getDescriptor().getMessageTypes().get(0);
+ internal_static_android_vts_AndroidDeviceInfoMessage_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_AndroidDeviceInfoMessage_descriptor,
+ new java.lang.String[] { "ProductType", "ProductVariant", "BuildFlavor", "BuildId", "Branch", "BuildAlias", "ApiLevel", "AbiName", "AbiBitness", "Serial", });
+ internal_static_android_vts_AndroidBuildInfo_descriptor =
+ getDescriptor().getMessageTypes().get(1);
+ internal_static_android_vts_AndroidBuildInfo_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_AndroidBuildInfo_descriptor,
+ new java.lang.String[] { "Id", "Name", "BuildType", "Branch", "BuildSummary", });
+ internal_static_android_vts_VtsHostInfo_descriptor =
+ getDescriptor().getMessageTypes().get(2);
+ internal_static_android_vts_VtsHostInfo_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_VtsHostInfo_descriptor,
+ new java.lang.String[] { "Hostname", });
+ internal_static_android_vts_TestCaseReportMessage_descriptor =
+ getDescriptor().getMessageTypes().get(3);
+ internal_static_android_vts_TestCaseReportMessage_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_TestCaseReportMessage_descriptor,
+ new java.lang.String[] { "Name", "TestResult", "StartTimestamp", "EndTimestamp", "Coverage", "Profiling", "Systrace", "Log", });
+ internal_static_android_vts_ProfilingReportMessage_descriptor =
+ getDescriptor().getMessageTypes().get(4);
+ internal_static_android_vts_ProfilingReportMessage_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_ProfilingReportMessage_descriptor,
+ new java.lang.String[] { "Name", "Type", "RegressionMode", "StartTimestamp", "EndTimestamp", "Label", "Value", "XAxisLabel", "YAxisLabel", "Options", });
+ internal_static_android_vts_SystraceReportMessage_descriptor =
+ getDescriptor().getMessageTypes().get(5);
+ internal_static_android_vts_SystraceReportMessage_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_SystraceReportMessage_descriptor,
+ new java.lang.String[] { "ProcessName", "Html", "Url", });
+ internal_static_android_vts_CoverageReportMessage_descriptor =
+ getDescriptor().getMessageTypes().get(6);
+ internal_static_android_vts_CoverageReportMessage_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_CoverageReportMessage_descriptor,
+ new java.lang.String[] { "FilePath", "ProjectName", "Revision", "LineCoverageVector", "TotalLineCount", "CoveredLineCount", "DirPath", "FileName", "Html", });
+ internal_static_android_vts_LogMessage_descriptor =
+ getDescriptor().getMessageTypes().get(7);
+ internal_static_android_vts_LogMessage_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_LogMessage_descriptor,
+ new java.lang.String[] { "Url", "Name", "Content", });
+ internal_static_android_vts_UrlResourceMessage_descriptor =
+ getDescriptor().getMessageTypes().get(8);
+ internal_static_android_vts_UrlResourceMessage_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_UrlResourceMessage_descriptor,
+ new java.lang.String[] { "Url", "Name", "Content", });
+ internal_static_android_vts_TestReportMessage_descriptor =
+ getDescriptor().getMessageTypes().get(9);
+ internal_static_android_vts_TestReportMessage_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_TestReportMessage_descriptor,
+ new java.lang.String[] { "TestSuite", "Test", "TestType", "DeviceInfo", "BuildInfo", "SubscriberEmail", "HostInfo", "TestCase", "Profiling", "Systrace", "StartTimestamp", "EndTimestamp", "Coverage", "Log", });
+ internal_static_android_vts_TestPlanReportMessage_descriptor =
+ getDescriptor().getMessageTypes().get(10);
+ internal_static_android_vts_TestPlanReportMessage_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_TestPlanReportMessage_descriptor,
+ new java.lang.String[] { "TestModuleName", "TestModuleStartTimestamp", "TestPlanName", "PartnerReport", });
+ internal_static_android_vts_DashboardPostMessage_descriptor =
+ getDescriptor().getMessageTypes().get(11);
+ internal_static_android_vts_DashboardPostMessage_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_android_vts_DashboardPostMessage_descriptor,
+ new java.lang.String[] { "AccessToken", "TestReport", "TestPlanReport", });
+ return null;
+ }
+ };
+ com.google.protobuf.Descriptors.FileDescriptor
+ .internalBuildGeneratedFileFrom(descriptorData,
+ new com.google.protobuf.Descriptors.FileDescriptor[] {
+ }, assigner);
+ }
+
+ // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/main/java/com/android/vts/servlet/BaseServlet.java b/src/main/java/com/android/vts/servlet/BaseServlet.java
new file mode 100644
index 0000000..3fdca0a
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/BaseServlet.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.google.appengine.api.users.User;
+import com.google.appengine.api.users.UserService;
+import com.google.appengine.api.users.UserServiceFactory;
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public abstract class BaseServlet extends HttpServlet {
+ protected final Logger logger = Logger.getLogger(getClass().getName());
+
+ // Environment variables
+ protected static final String GERRIT_URI = System.getProperty("GERRIT_URI");
+ protected static final String GERRIT_SCOPE = System.getProperty("GERRIT_SCOPE");
+ protected static final String CLIENT_ID = System.getProperty("CLIENT_ID");
+ protected static final String ANALYTICS_ID = System.getProperty("ANALYTICS_ID");
+
+ public enum PageType {
+ TOT("ToT", "/"),
+ RELEASE("Release", "/show_release"),
+ COVERAGE_OVERVIEW("Coverage", "/show_coverage_overview"),
+ TABLE("", "/show_table"),
+ TREE("", "/show_tree"),
+ GRAPH("Profiling", "/show_graph"),
+ COVERAGE("Coverage", "/show_coverage"),
+ PERFORMANCE("Performance Digest", "/show_performance_digest"),
+ PLAN_RELEASE("", "/show_plan_release"),
+ PLAN_RUN("Plan Run", "/show_plan_run");
+
+ public final String defaultName;
+ public final String defaultUrl;
+
+ PageType(String defaultName, String defaultUrl) {
+ this.defaultName = defaultName;
+ this.defaultUrl = defaultUrl;
+ }
+ }
+
+ public static class Page {
+ private final PageType type;
+ private final String name;
+ private final String url;
+
+ public Page(PageType type) {
+ this.type = type;
+ this.name = type.defaultName;
+ this.url = type.defaultUrl;
+ }
+
+ public Page(PageType type, String name, String url) {
+ this.type = type;
+ this.name = type.defaultName + name;
+ this.url = type.defaultUrl + url;
+ }
+
+ public Page(PageType type, String url) {
+ this.type = type;
+ this.name = type.defaultName;
+ this.url = type.defaultUrl + url;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+ }
+
+ public static final List<Page> navbarLinks;
+
+ static {
+ List<Page> links = new ArrayList<>();
+ links.add(new Page(PageType.TOT));
+ links.add(new Page(PageType.RELEASE));
+ links.add(new Page(PageType.COVERAGE_OVERVIEW));
+ navbarLinks = links;
+ }
+
+ public abstract PageType getNavParentType();
+
+ /**
+ * Get a list of URL/Display name pairs for the breadcrumb hierarchy.
+ *
+ * @param request The HttpServletRequest object for the page request.
+ * @return a list of Page entries.
+ */
+ public abstract List<Page> getBreadcrumbLinks(HttpServletRequest request);
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ // If the user is logged out, allow them to log back in and return to the page.
+ // Set the logout URL to direct back to a login page that directs to the current request.
+ UserService userService = UserServiceFactory.getUserService();
+ User currentUser = userService.getCurrentUser();
+ String requestUri = request.getRequestURI();
+ String requestArgs = request.getQueryString();
+ String loginURI = userService.createLoginURL(requestUri + '?' + requestArgs);
+ String logoutURI = userService.createLogoutURL(loginURI);
+ if (currentUser == null || currentUser.getEmail() == null) {
+ response.sendRedirect(loginURI);
+ return;
+ }
+ PageType parentType = getNavParentType();
+ int activeIndex;
+ switch (getNavParentType()) {
+ case COVERAGE_OVERVIEW:
+ activeIndex = 2;
+ break;
+ case RELEASE:
+ activeIndex = 1;
+ break;
+ default:
+ activeIndex = 0;
+ break;
+ }
+ request.setAttribute("logoutURL", logoutURI);
+ request.setAttribute("email", currentUser.getEmail());
+ request.setAttribute("analyticsID", new Gson().toJson(ANALYTICS_ID));
+ request.setAttribute("breadcrumbLinks", getBreadcrumbLinks(request));
+ request.setAttribute("navbarLinks", navbarLinks);
+ request.setAttribute("activeIndex", activeIndex);
+ response.setContentType("text/html");
+ doGetHandler(request, response);
+ }
+
+ /**
+ * Implementation of the doGet method to be executed by servlet subclasses.
+ *
+ * @param request The HttpServletRequest object.
+ * @param response The HttpServletResponse object.
+ * @throws IOException
+ */
+ public abstract void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException;
+}
diff --git a/src/main/java/com/android/vts/servlet/DashboardMainServlet.java b/src/main/java/com/android/vts/servlet/DashboardMainServlet.java
new file mode 100644
index 0000000..3766664
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/DashboardMainServlet.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.UserFavoriteEntity;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.PropertyProjection;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.FilterOperator;
+import com.google.appengine.api.datastore.Query.FilterPredicate;
+import com.google.appengine.api.users.User;
+import com.google.appengine.api.users.UserService;
+import com.google.appengine.api.users.UserServiceFactory;
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Represents the servlet that is invoked on loading the first page of dashboard. */
+public class DashboardMainServlet extends BaseServlet {
+ private static final String DASHBOARD_MAIN_JSP = "WEB-INF/jsp/dashboard_main.jsp";
+ private static final String DASHBOARD_ALL_LINK = "/?showAll=true";
+ private static final String DASHBOARD_FAVORITES_LINK = "/";
+ private static final String ALL_HEADER = "All Tests";
+ private static final String FAVORITES_HEADER = "Favorites";
+ private static final String NO_TESTS_ERROR = "No test results available.";
+ private static final String FAVORITES_BUTTON = "Show Favorites";
+ private static final String ALL_BUTTON = "Show All";
+ private static final String UP_ARROW = "keyboard_arrow_up";
+ private static final String DOWN_ARROW = "keyboard_arrow_down";
+
+ @Override
+ public PageType getNavParentType() {
+ return PageType.TOT;
+ }
+
+ @Override
+ public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
+ return null;
+ }
+
+ /** Helper class for displaying test entries on the main dashboard. */
+ public class TestDisplay implements Comparable<TestDisplay> {
+ private final Key testKey;
+ private final int passCount;
+ private final int failCount;
+
+ /**
+ * Test display constructor.
+ *
+ * @param testKey The key of the test.
+ * @param passCount The number of tests passing.
+ * @param failCount The number of tests failing.
+ */
+ public TestDisplay(Key testKey, int passCount, int failCount) {
+ this.testKey = testKey;
+ this.passCount = passCount;
+ this.failCount = failCount;
+ }
+
+ /**
+ * Get the key of the test.
+ *
+ * @return The key of the test.
+ */
+ public String getName() {
+ return this.testKey.getName();
+ }
+
+ /**
+ * Get the number of passing test cases.
+ *
+ * @return The number of passing test cases.
+ */
+ public int getPassCount() {
+ return this.passCount;
+ }
+
+ /**
+ * Get the number of failing test cases.
+ *
+ * @return The number of failing test cases.
+ */
+ public int getFailCount() {
+ return this.failCount;
+ }
+
+ @Override
+ public int compareTo(TestDisplay test) {
+ return this.testKey.getName().compareTo(test.getName());
+ }
+ }
+
+ @Override
+ public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ UserService userService = UserServiceFactory.getUserService();
+ User currentUser = userService.getCurrentUser();
+ RequestDispatcher dispatcher = null;
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+
+ List<TestDisplay> displayedTests = new ArrayList<>();
+ List<String> allTests = new ArrayList<>();
+
+ Map<Key, TestDisplay> testMap = new HashMap<>(); // map from table key to TestDisplay
+ Map<String, String> subscriptionMap = new HashMap<>();
+
+ boolean showAll = request.getParameter("showAll") != null;
+ String header;
+ String buttonLabel;
+ String buttonIcon;
+ String buttonLink;
+ String error = null;
+
+ Query q = new Query(TestEntity.KIND)
+ .addProjection(new PropertyProjection(TestEntity.PASS_COUNT, Long.class))
+ .addProjection(new PropertyProjection(TestEntity.FAIL_COUNT, Long.class));
+ for (Entity test : datastore.prepare(q).asIterable()) {
+ TestEntity testEntity = TestEntity.fromEntity(test);
+ if (test != null) {
+ TestDisplay display =
+ new TestDisplay(test.getKey(), testEntity.passCount, testEntity.failCount);
+ testMap.put(test.getKey(), display);
+ allTests.add(test.getKey().getName());
+ }
+ }
+
+ if (testMap.size() == 0) {
+ error = NO_TESTS_ERROR;
+ }
+
+ if (showAll) {
+ for (Key testKey : testMap.keySet()) {
+ displayedTests.add(testMap.get(testKey));
+ }
+ header = ALL_HEADER;
+ buttonLabel = FAVORITES_BUTTON;
+ buttonIcon = UP_ARROW;
+ buttonLink = DASHBOARD_FAVORITES_LINK;
+ } else {
+ if (testMap.size() > 0) {
+ Filter userFilter = new FilterPredicate(
+ UserFavoriteEntity.USER, FilterOperator.EQUAL, currentUser);
+ q = new Query(UserFavoriteEntity.KIND).setFilter(userFilter);
+
+ for (Entity favorite : datastore.prepare(q).asIterable()) {
+ Key testKey = (Key) favorite.getProperty(UserFavoriteEntity.TEST_KEY);
+ if (!testMap.containsKey(testKey)) {
+ continue;
+ }
+ displayedTests.add(testMap.get(testKey));
+ subscriptionMap.put(
+ testKey.getName(), KeyFactory.keyToString(favorite.getKey()));
+ }
+ }
+ header = FAVORITES_HEADER;
+ buttonLabel = ALL_BUTTON;
+ buttonIcon = DOWN_ARROW;
+ buttonLink = DASHBOARD_ALL_LINK;
+ }
+ Collections.sort(displayedTests);
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ request.setAttribute("allTestsJson", new Gson().toJson(allTests));
+ request.setAttribute("subscriptionMapJson", new Gson().toJson(subscriptionMap));
+ request.setAttribute("testNames", displayedTests);
+ request.setAttribute("headerLabel", header);
+ request.setAttribute("showAll", showAll);
+ request.setAttribute("buttonLabel", buttonLabel);
+ request.setAttribute("buttonIcon", buttonIcon);
+ request.setAttribute("buttonLink", buttonLink);
+ request.setAttribute("error", error);
+ dispatcher = request.getRequestDispatcher(DASHBOARD_MAIN_JSP);
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Excpetion caught : ", e);
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java b/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java
new file mode 100644
index 0000000..dac864f
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.proto.VtsReportMessage;
+import com.android.vts.util.TestRunMetadata;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.FetchOptions;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.Query;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Represents the servlet that is invoked on loading the coverage overview page. */
+public class ShowCoverageOverviewServlet extends BaseServlet {
+ private static final String COVERAGE_OVERVIEW_JSP = "WEB-INF/jsp/show_coverage_overview.jsp";
+
+ @Override
+ public PageType getNavParentType() {
+ return PageType.COVERAGE_OVERVIEW;
+ }
+
+ @Override
+ public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
+ return null;
+ }
+
+ @Override
+ public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ RequestDispatcher dispatcher = null;
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+
+ Query q = new Query(TestEntity.KIND).setKeysOnly();
+ List<Key> allTests = new ArrayList<>();
+ for (Entity test : datastore.prepare(q).asIterable()) {
+ allTests.add(test.getKey());
+ }
+
+ // Add test names to list
+ List<String> resultNames = new ArrayList<>();
+ for (VtsReportMessage.TestCaseResult r : VtsReportMessage.TestCaseResult.values()) {
+ resultNames.add(r.name());
+ }
+
+ List<JsonObject> testRunObjects = new ArrayList<>();
+
+ Query.Filter coverageFilter = new Query.FilterPredicate(
+ TestRunEntity.HAS_COVERAGE, Query.FilterOperator.EQUAL, true);
+ int coveredLines = 0;
+ int uncoveredLines = 0;
+ int passCount = 0;
+ int failCount = 0;
+ for (Key key : allTests) {
+ Query testRunQuery =
+ new Query(TestRunEntity.KIND)
+ .setAncestor(key)
+ .setFilter(coverageFilter)
+ .addSort(Entity.KEY_RESERVED_PROPERTY, Query.SortDirection.DESCENDING);
+ for (Entity testRunEntity :
+ datastore.prepare(testRunQuery).asIterable(FetchOptions.Builder.withLimit(1))) {
+ TestRunEntity testRun = TestRunEntity.fromEntity(testRunEntity);
+ if (testRun == null)
+ continue;
+ TestRunMetadata metadata = new TestRunMetadata(key.getName(), testRun);
+ testRunObjects.add(metadata.toJson());
+ coveredLines += testRun.coveredLineCount;
+ uncoveredLines += testRun.totalLineCount - testRun.coveredLineCount;
+ passCount += testRun.passCount;
+ failCount += testRun.failCount;
+ }
+ }
+
+ int[] testStats = new int[VtsReportMessage.TestCaseResult.values().length];
+ testStats[VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_PASS.getNumber()] = passCount;
+ testStats[VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_FAIL.getNumber()] = failCount;
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ request.setAttribute("resultNames", resultNames);
+ request.setAttribute("resultNamesJson", new Gson().toJson(resultNames));
+ request.setAttribute("testRuns", new Gson().toJson(testRunObjects));
+ request.setAttribute("coveredLines", new Gson().toJson(coveredLines));
+ request.setAttribute("uncoveredLines", new Gson().toJson(uncoveredLines));
+ request.setAttribute("testStats", new Gson().toJson(testStats));
+ dispatcher = request.getRequestDispatcher(COVERAGE_OVERVIEW_JSP);
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Exception caught : ", e);
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/ShowCoverageServlet.java b/src/main/java/com/android/vts/servlet/ShowCoverageServlet.java
new file mode 100644
index 0000000..9efe7f8
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/ShowCoverageServlet.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.CoverageEntity;
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Query;
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Servlet for handling requests to show code coverage. */
+public class ShowCoverageServlet extends BaseServlet {
+ private static final String COVERAGE_JSP = "WEB-INF/jsp/show_coverage.jsp";
+
+ @Override
+ public PageType getNavParentType() {
+ return PageType.TOT;
+ }
+
+ @Override
+ public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
+ List<Page> links = new ArrayList<>();
+ String testName = request.getParameter("testName");
+ links.add(new Page(PageType.TABLE, testName, "?testName=" + testName));
+
+ String startTime = request.getParameter("startTime");
+ links.add(new Page(PageType.COVERAGE, "?testName=" + testName + "&startTime=" + startTime));
+ return links;
+ }
+
+ @Override
+ public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ RequestDispatcher dispatcher = null;
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ String test = request.getParameter("testName");
+ String timeString = request.getParameter("startTime");
+
+ // Process the time key requested
+ long time = -1;
+ try {
+ time = Long.parseLong(timeString);
+ } catch (NumberFormatException e) {
+ request.setAttribute("testName", test);
+ dispatcher = request.getRequestDispatcher("/show_table.jsp");
+ return;
+ }
+
+ // Compute the parent test run key based off of the test and time
+ Key testKey = KeyFactory.createKey(TestEntity.KIND, test);
+ Key testRunKey = KeyFactory.createKey(testKey, TestRunEntity.KIND, time);
+
+ // Create a query for coverage entities
+ Query coverageQuery = new Query(CoverageEntity.KIND).setAncestor(testRunKey);
+
+ List<String> sourceFiles = new ArrayList<>(); // list of source files
+ List<List<Long>> coverageVectors = new ArrayList<>(); // list of line coverage vectors
+ List<String> projects = new ArrayList<>(); // list of project names
+ List<String> commits = new ArrayList<>(); // list of project commit hashes
+ List<String> indicators = new ArrayList<>(); // list of HTML indicates to display
+
+ /*
+ * Map from section name to a list of indexes into the above lists where each coverage
+ * report's data is located.
+ */
+ Map<String, List<Integer>> sectionMap = new HashMap<>();
+ for (Entity e : datastore.prepare(coverageQuery).asIterable()) {
+ CoverageEntity coverageEntity = CoverageEntity.fromEntity(e);
+ if (coverageEntity == null) {
+ logger.log(Level.WARNING, "Invalid coverage entity: " + e.getKey());
+ continue;
+ }
+ if (!sectionMap.containsKey(coverageEntity.group)) {
+ sectionMap.put(coverageEntity.group, new ArrayList<Integer>());
+ }
+ sectionMap.get(coverageEntity.group).add(coverageVectors.size());
+ coverageVectors.add(coverageEntity.lineCoverage);
+ sourceFiles.add(coverageEntity.filePath);
+ projects.add(coverageEntity.projectName);
+ commits.add(coverageEntity.projectVersion);
+ String indicator = "";
+ long total = coverageEntity.totalLineCount;
+ long covered = coverageEntity.coveredLineCount;
+ if (total > 0) {
+ double pct = Math.round(covered * 10000d / total) / 100d;
+ String color = pct >= 70 ? "green" : "red";
+ indicator = "<div class=\"right indicator " + color + "\">" + pct + "%</div>"
+ + "<span class=\"right total-count\">" + covered + "/" + total + "</span>";
+ }
+ indicators.add(indicator);
+ }
+
+ request.setAttribute("testName", request.getParameter("testName"));
+ request.setAttribute("gerritURI", new Gson().toJson(GERRIT_URI));
+ request.setAttribute("gerritScope", new Gson().toJson(GERRIT_SCOPE));
+ request.setAttribute("clientId", new Gson().toJson(CLIENT_ID));
+ request.setAttribute("coverageVectors", new Gson().toJson(coverageVectors));
+ request.setAttribute("sourceFiles", new Gson().toJson(sourceFiles));
+ request.setAttribute("projects", new Gson().toJson(projects));
+ request.setAttribute("commits", new Gson().toJson(commits));
+ request.setAttribute("indicators", new Gson().toJson(indicators));
+ request.setAttribute("sectionMap", new Gson().toJson(sectionMap));
+ request.setAttribute("startTime", request.getParameter("startTime"));
+ dispatcher = request.getRequestDispatcher(COVERAGE_JSP);
+
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Exception caught : ", e);
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/ShowGraphServlet.java b/src/main/java/com/android/vts/servlet/ShowGraphServlet.java
new file mode 100644
index 0000000..8144ecf
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/ShowGraphServlet.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.util.DatastoreHelper;
+import com.android.vts.util.FilterUtil;
+import com.android.vts.util.Graph;
+import com.android.vts.util.GraphSerializer;
+import com.android.vts.util.Histogram;
+import com.android.vts.util.LineGraph;
+import com.android.vts.util.PerformanceUtil;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.EntityNotFoundException;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang.StringUtils;
+
+/** Servlet for handling requests to load graphs. */
+public class ShowGraphServlet extends BaseServlet {
+ private static final String GRAPH_JSP = "WEB-INF/jsp/show_graph.jsp";
+ private static final long DEFAULT_FILTER_OPTION = -1;
+
+ private static final String HIDL_HAL_OPTION = "hidl_hal_mode";
+ private static final String[] splitKeysArray = new String[] {HIDL_HAL_OPTION};
+ private static final Set<String> splitKeySet = new HashSet<>(Arrays.asList(splitKeysArray));
+ private static final String PROFILING_DATA_ALERT = "No profiling data was found.";
+
+ @Override
+ public PageType getNavParentType() {
+ return PageType.TOT;
+ }
+
+ @Override
+ public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
+ List<Page> links = new ArrayList<>();
+ String testName = request.getParameter("testName");
+ links.add(new Page(PageType.TABLE, testName, "?testName=" + testName));
+
+ String profilingPointName = request.getParameter("profilingPoint");
+ links.add(new Page(
+ PageType.GRAPH, "?testName=" + testName + "&profilingPoint=" + profilingPointName));
+ return links;
+ }
+
+ /**
+ * Process a profiling report message and add it to the map of graphs.
+ *
+ * @param profilingRun The Entity of a profiling point run to process.
+ * @param idString The ID derived from the test run to identify the profiling report.
+ * @param graphMap A map from graph name to Graph object.
+ */
+ private static void processProfilingRun(
+ Entity profilingRun, String idString, Map<String, Graph> graphMap) {
+ ProfilingPointRunEntity pt = ProfilingPointRunEntity.fromEntity(profilingRun);
+ if (pt == null)
+ return;
+ String name = PerformanceUtil.getOptionAlias(pt, splitKeySet);
+ Graph g = null;
+ if (pt.labels != null && pt.labels.size() == pt.values.size()) {
+ g = new LineGraph(name);
+ } else if (pt.labels == null && pt.values.size() > 0) {
+ g = new Histogram(name);
+ } else {
+ return;
+ }
+ if (!graphMap.containsKey(name)) {
+ graphMap.put(name, g);
+ }
+ graphMap.get(name).addData(idString, pt);
+ }
+
+ /**
+ * Get a summary string describing the devices in the test run.
+ *
+ * @param testRun The entity storing test run information.
+ * @param selectedDevice The name of the selected device.
+ * @return A string describing the devices in the test run, or null if it doesn't match filter.
+ */
+ private static String getDeviceSummary(Entity testRun, String selectedDevice) {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ List<String> buildInfos = new ArrayList<>();
+ Query deviceQuery = new Query(DeviceInfoEntity.KIND).setAncestor(testRun.getKey());
+ boolean isSelectedDevice = selectedDevice == null;
+ for (Entity device : datastore.prepare(deviceQuery).asIterable()) {
+ String product = (String) device.getProperty(DeviceInfoEntity.PRODUCT);
+ if (selectedDevice != null && product.equals(selectedDevice)) {
+ isSelectedDevice = true;
+ }
+ String buildId = (String) device.getProperty(DeviceInfoEntity.BUILD_ID);
+ buildInfos.add(product + " (" + buildId + ")");
+ }
+ return isSelectedDevice ? StringUtils.join(buildInfos, ", ") : null;
+ }
+
+ @Override
+ public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ RequestDispatcher dispatcher = null;
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ String testName = request.getParameter("testName");
+ String profilingPointName = request.getParameter("profilingPoint");
+ String selectedDevice = request.getParameter("device");
+ Long endTime = null;
+ if (request.getParameter("endTime") != null) {
+ String time = request.getParameter("endTime");
+ try {
+ endTime = Long.parseLong(time);
+ } catch (NumberFormatException e) {
+ }
+ }
+ if (endTime == null) {
+ endTime = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
+ }
+ Long startTime = endTime - TimeUnit.DAYS.toMicros(1);
+
+ // Set of device names
+ List<String> devices = DatastoreHelper.getAllProducts();
+ if (!devices.contains(selectedDevice))
+ selectedDevice = null;
+
+ Map<String, Graph> graphMap = new HashMap<>();
+
+ // Create a query for test runs matching the time window filter
+ Key parentKey = KeyFactory.createKey(TestEntity.KIND, testName);
+ Filter timeFilter =
+ FilterUtil.getTimeFilter(parentKey, TestRunEntity.KIND, startTime, endTime);
+ Query testRunQuery = new Query(TestRunEntity.KIND)
+ .setAncestor(parentKey)
+ .setFilter(timeFilter)
+ .setKeysOnly();
+
+ // Process the test runs in the query
+ for (Entity testRun : datastore.prepare(testRunQuery).asIterable()) {
+ String buildInfoString = getDeviceSummary(testRun, selectedDevice);
+ if (buildInfoString == null) {
+ continue;
+ }
+
+ try {
+ Entity profilingRun = datastore.get(KeyFactory.createKey(
+ testRun.getKey(), ProfilingPointRunEntity.KIND, profilingPointName));
+ processProfilingRun(profilingRun, buildInfoString, graphMap);
+ } catch (EntityNotFoundException e) {
+ // Profiling point not collected during this test run
+ continue;
+ }
+ }
+ // Get the names of the graphs to render
+ String[] names = graphMap.keySet().toArray(new String[graphMap.size()]);
+ Arrays.sort(names);
+
+ List<Graph> graphList = new ArrayList<>();
+ boolean hasHistogram = false;
+ for (String name : names) {
+ Graph g = graphMap.get(name);
+ if (g.size() > 0) {
+ graphList.add(g);
+ if (g instanceof Histogram)
+ hasHistogram = true;
+ }
+ }
+
+ String filterVal = request.getParameter("filterVal");
+ try {
+ Long.parseLong(filterVal);
+ } catch (NumberFormatException e) {
+ filterVal = Long.toString(DEFAULT_FILTER_OPTION);
+ }
+ request.setAttribute("testName", request.getParameter("testName"));
+ request.setAttribute("filterVal", filterVal);
+ request.setAttribute("endTime", new Gson().toJson(endTime));
+ request.setAttribute("devices", devices);
+ request.setAttribute("selectedDevice", selectedDevice);
+ request.setAttribute("showFilterDropdown", hasHistogram);
+ if (graphList.size() == 0)
+ request.setAttribute("error", PROFILING_DATA_ALERT);
+
+ Gson gson = new GsonBuilder()
+ .registerTypeHierarchyAdapter(Graph.class, new GraphSerializer())
+ .create();
+ request.setAttribute("graphs", gson.toJson(graphList));
+
+ request.setAttribute("profilingPointName", profilingPointName);
+ dispatcher = request.getRequestDispatcher(GRAPH_JSP);
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Excpetion caught : ", e);
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java b/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java
new file mode 100644
index 0000000..51b0127
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.util.DatastoreHelper;
+import com.android.vts.util.PerformanceSummary;
+import com.android.vts.util.PerformanceUtil;
+import com.android.vts.util.PerformanceUtil.TimeInterval;
+import com.android.vts.util.ProfilingPointSummary;
+import com.android.vts.util.StatSummary;
+import java.io.IOException;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Servlet for producing tabular performance summaries. */
+public class ShowPerformanceDigestServlet extends BaseServlet {
+ private static final String PERF_DIGEST_JSP = "WEB-INF/jsp/show_performance_digest.jsp";
+ private static final String HIDL_HAL_OPTION = "hidl_hal_mode";
+ private static final String[] splitKeysArray = new String[] {HIDL_HAL_OPTION};
+ private static final Set<String> splitKeySet =
+ new HashSet<String>(Arrays.asList(splitKeysArray));
+
+ private static final String MEAN = "Mean";
+ private static final String MIN = "Min";
+ private static final String MAX = "Max";
+ private static final String MEAN_DELTA = "&Delta;Mean (%)";
+ private static final String HIGHER_IS_BETTER =
+ "Note: Higher values are better. Maximum is the best-case performance.";
+ private static final String LOWER_IS_BETTER =
+ "Note: Lower values are better. Minimum is the best-case performance.";
+ private static final String STD = "Std";
+
+ private static final DecimalFormat FORMATTER;
+
+ /**
+ * Initialize the decimal formatter.
+ */
+ static {
+ FORMATTER = new DecimalFormat("#.##");
+ FORMATTER.setRoundingMode(RoundingMode.HALF_UP);
+ }
+
+ @Override
+ public PageType getNavParentType() {
+ return PageType.TOT;
+ }
+
+ @Override
+ public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
+ List<Page> links = new ArrayList<>();
+ String testName = request.getParameter("testName");
+ links.add(new Page(PageType.TABLE, testName, "?testName=" + testName));
+ links.add(new Page(PageType.PERFORMANCE, "?testName=" + testName));
+ return links;
+ }
+
+ /**
+ * Generates an HTML summary of the performance changes for the profiling results in the
+ * specified
+ * table.
+ *
+ * <p>Retrieves the past 24 hours of profiling data and compares it to the 24 hours that
+ * preceded
+ * it. Creates a table representation of the mean and standard deviation for each profiling
+ * point.
+ * When performance degrades, the cell is shaded red.
+ *
+ * @param profilingPoint The name of the profiling point to summarize.
+ * @param testSummary The ProfilingPointSummary object to compare against.
+ * @param perfSummaries List of PerformanceSummary objects for each profiling run (in reverse
+ * chronological order).
+ * @param sectionLabels HTML string for the section labels (i.e. for each time interval).
+ * @returns An HTML string for a table comparing the profiling point results across time
+ * intervals.
+ */
+ public static String getPeformanceSummary(String profilingPoint,
+ ProfilingPointSummary testSummary, List<PerformanceSummary> perfSummaries,
+ String sectionLabels) {
+ String tableHTML = "<table>";
+
+ // Format section labels
+ tableHTML += "<tr>";
+ tableHTML += "<th class='section-label grey lighten-2'>";
+ tableHTML += testSummary.yLabel + "</th>";
+ tableHTML += sectionLabels;
+ tableHTML += "</tr>";
+
+ String bestCaseString;
+ switch (testSummary.getRegressionMode()) {
+ case VTS_REGRESSION_MODE_DECREASING:
+ bestCaseString = MAX;
+ break;
+ default:
+ bestCaseString = MIN;
+ break;
+ }
+
+ // Format column labels
+ tableHTML += "<tr>";
+ for (int i = 0; i <= perfSummaries.size() + 1; i++) {
+ if (i > 1) {
+ tableHTML += "<th class='section-label grey lighten-2'>" + MEAN_DELTA + "</th>";
+ }
+ if (i == 0) {
+ tableHTML += "<th class='section-label grey lighten-2'>";
+ tableHTML += testSummary.xLabel + "</th>";
+ } else if (i > 0) {
+ tableHTML += "<th class='section-label grey lighten-2'>" + bestCaseString + "</th>";
+ tableHTML += "<th class='section-label grey lighten-2'>" + MEAN + "</th>";
+ tableHTML += "<th class='section-label grey lighten-2'>" + STD + "</th>";
+ }
+ }
+ tableHTML += "</tr>";
+
+ // Populate data cells
+ for (StatSummary stats : testSummary) {
+ String label = stats.getLabel();
+ tableHTML += "<tr><td class='axis-label grey lighten-2'>" + label;
+ tableHTML += "</td><td class='cell inner-cell'>";
+ tableHTML += FORMATTER.format(stats.getBestCase()) + "</td>";
+ tableHTML += "<td class='cell inner-cell'>";
+ tableHTML += FORMATTER.format(stats.getMean()) + "</td>";
+ tableHTML += "<td class='cell outer-cell'>";
+ tableHTML += FORMATTER.format(stats.getStd()) + "</td>";
+ for (PerformanceSummary prevPerformance : perfSummaries) {
+ if (prevPerformance.hasProfilingPoint(profilingPoint)) {
+ StatSummary baseline = prevPerformance.getProfilingPointSummary(profilingPoint)
+ .getStatSummary(label);
+ tableHTML += PerformanceUtil.getAvgCasePerformanceComparisonHTML(
+ baseline, stats, "cell inner-cell", "cell outer-cell", "", "");
+ } else {
+ tableHTML += "<td></td><td></td><td></td><td></td>";
+ }
+ }
+ tableHTML += "</tr>";
+ }
+ tableHTML += "</table>";
+ return tableHTML;
+ }
+
+ @Override
+ public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ RequestDispatcher dispatcher = null;
+ String testName = request.getParameter("testName");
+ String selectedDevice = request.getParameter("device");
+ Long startTime = null;
+ if (request.getParameter("startTime") != null) {
+ String time = request.getParameter("startTime");
+ try {
+ startTime = Long.parseLong(time);
+ } catch (NumberFormatException e) {
+ logger.log(Level.WARNING, "Invalid start time passed to digest servlet: " + time);
+ }
+ }
+ if (startTime == null) {
+ startTime = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
+ }
+
+ // Add today to the list of time intervals to analyze
+ List<TimeInterval> timeIntervals = new ArrayList<>();
+ TimeInterval today = new TimeInterval(startTime - TimeUnit.DAYS.toMicros(1), startTime);
+ timeIntervals.add(today);
+
+ // Add yesterday as a baseline time interval for analysis
+ long oneDayAgo = startTime - TimeUnit.DAYS.toMicros(1);
+ TimeInterval yesterday = new TimeInterval(oneDayAgo - TimeUnit.DAYS.toMicros(1), oneDayAgo);
+ timeIntervals.add(yesterday);
+
+ // Add last week as a baseline time interval for analysis
+ long oneWeek = TimeUnit.DAYS.toMicros(7);
+ long oneWeekAgo = startTime - oneWeek;
+ String spanString = "<span class='date-label'>";
+ String label =
+ spanString + TimeUnit.MICROSECONDS.toMillis(oneWeekAgo - oneWeek) + "</span>";
+ label += " - " + spanString + TimeUnit.MICROSECONDS.toMillis(oneWeekAgo) + "</span>";
+ TimeInterval lastWeek = new TimeInterval(oneWeekAgo - oneWeek, oneWeekAgo, label);
+ timeIntervals.add(lastWeek);
+
+ List<PerformanceSummary> perfSummaries = new ArrayList<>();
+
+ String sectionLabels = "";
+ int i = 0;
+ for (TimeInterval interval : timeIntervals) {
+ PerformanceSummary perfSummary = new PerformanceSummary(splitKeySet);
+ PerformanceUtil.updatePerformanceSummary(
+ testName, interval.start, interval.end, selectedDevice, perfSummary);
+ if (perfSummary.size() == 0) {
+ continue;
+ }
+ perfSummaries.add(perfSummary);
+ String content = interval.label;
+ sectionLabels += "<th class='section-label grey lighten-2 center' ";
+ if (i++ == 0)
+ sectionLabels += "colspan='3'";
+ else
+ sectionLabels += "colspan='4'";
+ sectionLabels += ">" + content + "</th>";
+ }
+
+ List<String> tables = new ArrayList<>();
+ List<String> tableTitles = new ArrayList<>();
+ List<String> tableSubtitles = new ArrayList<>();
+ if (perfSummaries.size() != 0) {
+ PerformanceSummary todayPerformance = perfSummaries.remove(0);
+ String[] profilingNames = todayPerformance.getProfilingPointNames();
+
+ for (String profilingPointName : profilingNames) {
+ ProfilingPointSummary baselinePerformance =
+ todayPerformance.getProfilingPointSummary(profilingPointName);
+ String table = getPeformanceSummary(
+ profilingPointName, baselinePerformance, perfSummaries, sectionLabels);
+ if (table != null) {
+ tables.add(table);
+ tableTitles.add(profilingPointName);
+ switch (baselinePerformance.getRegressionMode()) {
+ case VTS_REGRESSION_MODE_DECREASING:
+ tableSubtitles.add(HIGHER_IS_BETTER);
+ break;
+ default:
+ tableSubtitles.add(LOWER_IS_BETTER);
+ break;
+ }
+ }
+ }
+ }
+
+ request.setAttribute("testName", testName);
+ request.setAttribute("tables", tables);
+ request.setAttribute("tableTitles", tableTitles);
+ request.setAttribute("tableSubtitles", tableSubtitles);
+ request.setAttribute("startTime", Long.toString(startTime));
+ request.setAttribute("selectedDevice", selectedDevice);
+ request.setAttribute("devices", DatastoreHelper.getAllProducts());
+
+ dispatcher = request.getRequestDispatcher(PERF_DIGEST_JSP);
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Exception caught : " + e.toString());
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/ShowPlanReleaseServlet.java b/src/main/java/com/android/vts/servlet/ShowPlanReleaseServlet.java
new file mode 100644
index 0000000..4e88bcc
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/ShowPlanReleaseServlet.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.TestPlanEntity;
+import com.android.vts.entity.TestPlanRunEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.util.DatastoreHelper;
+import com.android.vts.util.FilterUtil;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.FetchOptions;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.SortDirection;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.Set;
+import java.util.HashSet;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang.StringUtils;
+
+public class ShowPlanReleaseServlet extends BaseServlet {
+ private static final String PLAN_RELEASE_JSP = "WEB-INF/jsp/show_plan_release.jsp";
+ private static final int MAX_RUNS_PER_PAGE = 90;
+
+ @Override
+ public PageType getNavParentType() {
+ return PageType.RELEASE;
+ }
+
+ @Override
+ public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
+ List<Page> links = new ArrayList<>();
+ String planName = request.getParameter("plan");
+ links.add(new Page(PageType.PLAN_RELEASE, planName.toUpperCase(), "?plan=" + planName));
+ return links;
+ }
+
+ /**
+ * Model to describe each test plan run .
+ */
+ private class TestPlanRunMetadata implements Comparable<TestPlanRunMetadata> {
+ public final TestPlanRunEntity testPlanRun;
+ public final List<String> devices;
+ public final Set<DeviceInfoEntity> deviceSet;
+
+ public TestPlanRunMetadata(TestPlanRunEntity testPlanRun) {
+ this.testPlanRun = testPlanRun;
+ this.devices = new ArrayList<>();
+ this.deviceSet = new HashSet<>();
+ }
+
+ public void addDevice(DeviceInfoEntity device) {
+ if (device == null || deviceSet.contains(device))
+ return;
+ devices.add(device.branch + "/" + device.buildFlavor + " (" + device.buildId + ")");
+ deviceSet.add(device);
+ }
+
+ public JsonObject toJson() {
+ JsonObject obj = new JsonObject();
+ obj.add("testPlanRun", testPlanRun.toJson());
+ obj.add("deviceInfo", new JsonPrimitive(StringUtils.join(devices, ", ")));
+ return obj;
+ }
+
+ @Override
+ public int compareTo(TestPlanRunMetadata o) {
+ return new Long(o.testPlanRun.startTimestamp)
+ .compareTo(this.testPlanRun.startTimestamp);
+ }
+ }
+
+ @Override
+ public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Long startTime = null; // time in microseconds
+ Long endTime = null; // time in microseconds
+ if (request.getParameter("startTime") != null) {
+ String time = request.getParameter("startTime");
+ try {
+ startTime = Long.parseLong(time);
+ startTime = startTime > 0 ? startTime : null;
+ } catch (NumberFormatException e) {
+ startTime = null;
+ }
+ }
+ if (request.getParameter("endTime") != null) {
+ String time = request.getParameter("endTime");
+ try {
+ endTime = Long.parseLong(time);
+ endTime = endTime > 0 ? endTime : null;
+ } catch (NumberFormatException e) {
+ endTime = null;
+ }
+ }
+ SortDirection dir = SortDirection.DESCENDING;
+ if (startTime != null && endTime == null) {
+ dir = SortDirection.ASCENDING;
+ }
+ boolean unfiltered = request.getParameter("unfiltered") != null;
+ boolean showPresubmit = request.getParameter("showPresubmit") != null;
+ boolean showPostsubmit = request.getParameter("showPostsubmit") != null;
+ // If no params are specified, set to default of postsubmit-only.
+ if (!(showPresubmit || showPostsubmit)) {
+ showPostsubmit = true;
+ }
+
+ // If unfiltered, set showPre- and Post-submit to true for accurate UI.
+ if (unfiltered) {
+ showPostsubmit = true;
+ showPresubmit = true;
+ }
+ Filter typeFilter = FilterUtil.getTestTypeFilter(showPresubmit, showPostsubmit, unfiltered);
+ String testPlan = request.getParameter("plan");
+ Key testPlanKey = KeyFactory.createKey(TestPlanEntity.KIND, testPlan);
+ Filter testPlanRunFilter = FilterUtil.getTimeFilter(
+ testPlanKey, TestPlanRunEntity.KIND, startTime, endTime, typeFilter);
+ Map<String, Object> parameterMap = request.getParameterMap();
+ Filter userDeviceFilter = FilterUtil.getUserDeviceFilter(parameterMap);
+
+ List<TestPlanRunMetadata> testPlanRuns = new ArrayList<>();
+ if (userDeviceFilter == null) {
+ Query testPlanRunQuery = new Query(TestPlanRunEntity.KIND)
+ .setAncestor(testPlanKey)
+ .setFilter(testPlanRunFilter)
+ .addSort(Entity.KEY_RESERVED_PROPERTY, dir);
+ for (Entity testPlanRunEntity :
+ datastore.prepare(testPlanRunQuery)
+ .asIterable(FetchOptions.Builder.withLimit(MAX_RUNS_PER_PAGE))) {
+ TestPlanRunEntity testPlanRun = TestPlanRunEntity.fromEntity(testPlanRunEntity);
+ if (testPlanRun == null) {
+ logger.log(
+ Level.WARNING, "Invalid test plan run: " + testPlanRunEntity.getKey());
+ continue;
+ }
+ TestPlanRunMetadata metadata = new TestPlanRunMetadata(testPlanRun);
+ testPlanRuns.add(metadata);
+ Query deviceInfoQuery =
+ new Query(DeviceInfoEntity.KIND).setAncestor(testPlanRun.key);
+ for (Entity deviceInfoEntity : datastore.prepare(deviceInfoQuery).asIterable()) {
+ DeviceInfoEntity deviceInfo = DeviceInfoEntity.fromEntity(deviceInfoEntity);
+ metadata.addDevice(deviceInfo);
+ }
+ }
+ } else {
+ List<Key> gets = FilterUtil.getMatchingKeys(testPlanKey, TestPlanRunEntity.KIND,
+ testPlanRunFilter, userDeviceFilter, dir, MAX_RUNS_PER_PAGE);
+ Map<Key, Entity> entityMap = datastore.get(gets);
+ for (Key key : gets) {
+ if (!entityMap.containsKey(key)) {
+ continue;
+ }
+ TestPlanRunEntity testPlanRun = TestPlanRunEntity.fromEntity(entityMap.get(key));
+ if (testPlanRun == null) {
+ continue;
+ }
+ TestPlanRunMetadata metadata = new TestPlanRunMetadata(testPlanRun);
+ testPlanRuns.add(metadata);
+ Query deviceInfoQuery =
+ new Query(DeviceInfoEntity.KIND).setAncestor(testPlanRun.key);
+ for (Entity deviceInfoEntity : datastore.prepare(deviceInfoQuery).asIterable()) {
+ DeviceInfoEntity deviceInfo = DeviceInfoEntity.fromEntity(deviceInfoEntity);
+ metadata.addDevice(deviceInfo);
+ }
+ }
+ }
+
+ Collections.sort(testPlanRuns);
+
+ if (testPlanRuns.size() > 0) {
+ TestPlanRunMetadata firstRun = testPlanRuns.get(0);
+ endTime = firstRun.testPlanRun.startTimestamp;
+
+ TestPlanRunMetadata lastRun = testPlanRuns.get(testPlanRuns.size() - 1);
+ startTime = lastRun.testPlanRun.startTimestamp;
+ }
+
+ List<JsonObject> testPlanRunObjects = new ArrayList<>();
+ for (TestPlanRunMetadata metadata : testPlanRuns) {
+ testPlanRunObjects.add(metadata.toJson());
+ }
+
+ FilterUtil.setAttributes(request, parameterMap);
+
+ request.setAttribute("plan", request.getParameter("plan"));
+ request.setAttribute("hasNewer", new Gson().toJson(DatastoreHelper.hasNewer(
+ testPlanKey, TestPlanRunEntity.KIND, endTime)));
+ request.setAttribute("hasOlder", new Gson().toJson(DatastoreHelper.hasOlder(
+ testPlanKey, TestPlanRunEntity.KIND, startTime)));
+ request.setAttribute("planRuns", new Gson().toJson(testPlanRunObjects));
+
+ request.setAttribute("unfiltered", unfiltered);
+ request.setAttribute("showPresubmit", showPresubmit);
+ request.setAttribute("showPostsubmit", showPostsubmit);
+ request.setAttribute("startTime", new Gson().toJson(startTime));
+ request.setAttribute("endTime", new Gson().toJson(endTime));
+ request.setAttribute("branches", new Gson().toJson(DatastoreHelper.getAllBranches()));
+ request.setAttribute("devices", new Gson().toJson(DatastoreHelper.getAllBuildFlavors()));
+ response.setStatus(HttpServletResponse.SC_OK);
+ RequestDispatcher dispatcher = request.getRequestDispatcher(PLAN_RELEASE_JSP);
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Excpetion caught : ", e);
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/ShowPlanRunServlet.java b/src/main/java/com/android/vts/servlet/ShowPlanRunServlet.java
new file mode 100644
index 0000000..32b3ec4
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/ShowPlanRunServlet.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.TestPlanEntity;
+import com.android.vts.entity.TestPlanRunEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.proto.VtsReportMessage.TestCaseResult;
+import com.android.vts.util.TestRunMetadata;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.EntityNotFoundException;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Servlet for handling requests to load individual plan runs. */
+public class ShowPlanRunServlet extends BaseServlet {
+ private static final String PLAN_RUN_JSP = "WEB-INF/jsp/show_plan_run.jsp";
+ private static final String PROFILING_DATA_ALERT = "No profiling data was found.";
+
+ @Override
+ public PageType getNavParentType() {
+ return PageType.RELEASE;
+ }
+
+ @Override
+ public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
+ List<Page> links = new ArrayList<>();
+ String planName = request.getParameter("plan");
+ links.add(new Page(PageType.PLAN_RELEASE, planName.toUpperCase(), "?plan=" + planName));
+
+ String time = request.getParameter("time");
+ links.add(new Page(PageType.PLAN_RUN, "?plan=" + planName + "&time=" + time));
+ return links;
+ }
+
+ @Override
+ public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ Long startTime = null; // time in microseconds
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ RequestDispatcher dispatcher = null;
+
+ String plan = request.getParameter("plan");
+
+ if (request.getParameter("time") != null) {
+ String time = request.getParameter("time");
+ try {
+ startTime = Long.parseLong(time);
+ startTime = startTime > 0 ? startTime : null;
+ } catch (NumberFormatException e) {
+ startTime = null;
+ }
+ }
+
+ // Add result names to list
+ List<String> resultNames = new ArrayList<>();
+ for (TestCaseResult r : TestCaseResult.values()) {
+ resultNames.add(r.name());
+ }
+
+ List<TestRunMetadata> testRunMetadata = new ArrayList<>();
+ List<JsonObject> testRunObjects = new ArrayList<>();
+
+ Key planKey = KeyFactory.createKey(TestPlanEntity.KIND, plan);
+ Key planRunKey = KeyFactory.createKey(planKey, TestPlanRunEntity.KIND, startTime);
+ int passCount = 0;
+ int failCount = 0;
+ try {
+ Entity testPlanRunEntity = datastore.get(planRunKey);
+ TestPlanRunEntity testPlanRun = TestPlanRunEntity.fromEntity(testPlanRunEntity);
+ Map<Key, Entity> testRuns = datastore.get(testPlanRun.testRuns);
+ passCount = (int) testPlanRun.passCount;
+ failCount = (int) testPlanRun.failCount;
+
+ for (Key key : testPlanRun.testRuns) {
+ if (!testRuns.containsKey(key))
+ continue;
+ TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRuns.get(key));
+ if (testRunEntity == null)
+ continue;
+ TestRunMetadata metadata =
+ new TestRunMetadata(key.getParent().getName(), testRunEntity);
+ testRunMetadata.add(metadata);
+ testRunObjects.add(metadata.toJson());
+ }
+ } catch (EntityNotFoundException e) {
+ // Invalid parameters
+ }
+
+ int[] topBuildResultCounts = new int[TestCaseResult.values().length];
+ topBuildResultCounts = new int[TestCaseResult.values().length];
+ topBuildResultCounts[TestCaseResult.TEST_CASE_RESULT_PASS.getNumber()] = passCount;
+ topBuildResultCounts[TestCaseResult.TEST_CASE_RESULT_FAIL.getNumber()] = failCount;
+
+ Set<String> profilingPoints = new HashSet<>();
+
+ String profilingDataAlert = "";
+ if (profilingPoints.size() == 0) {
+ profilingDataAlert = PROFILING_DATA_ALERT;
+ }
+ List<String> profilingPointNames = new ArrayList<>(profilingPoints);
+ Collections.sort(profilingPointNames);
+
+ request.setAttribute("plan", request.getParameter("plan"));
+ request.setAttribute("time", request.getParameter("time"));
+
+ request.setAttribute("error", profilingDataAlert);
+
+ request.setAttribute("profilingPointNames", profilingPointNames);
+ request.setAttribute("resultNames", resultNames);
+ request.setAttribute("resultNamesJson", new Gson().toJson(resultNames));
+ request.setAttribute("testRuns", new Gson().toJson(testRunObjects));
+
+ // data for pie chart
+ request.setAttribute("topBuildResultCounts", new Gson().toJson(topBuildResultCounts));
+
+ dispatcher = request.getRequestDispatcher(PLAN_RUN_JSP);
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Exception caught : " + e.toString());
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/ShowReleaseServlet.java b/src/main/java/com/android/vts/servlet/ShowReleaseServlet.java
new file mode 100644
index 0000000..35f1af2
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/ShowReleaseServlet.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.TestPlanEntity;
+import com.android.vts.entity.UserFavoriteEntity;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.PropertyProjection;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.FilterOperator;
+import com.google.appengine.api.datastore.Query.FilterPredicate;
+import com.google.appengine.api.users.User;
+import com.google.appengine.api.users.UserService;
+import com.google.appengine.api.users.UserServiceFactory;
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Represents the servlet that is invoked on loading the release page. */
+public class ShowReleaseServlet extends BaseServlet {
+ private static final String RELEASE_JSP = "WEB-INF/jsp/show_release.jsp";
+
+ @Override
+ public PageType getNavParentType() {
+ return PageType.RELEASE;
+ }
+
+ @Override
+ public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
+ return null;
+ }
+
+ @Override
+ public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ UserService userService = UserServiceFactory.getUserService();
+ User currentUser = userService.getCurrentUser();
+ RequestDispatcher dispatcher = null;
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+
+ Set<String> planSet = new HashSet<>();
+
+ Query q = new Query(TestPlanEntity.KIND).setKeysOnly();
+ for (Entity testPlanEntity : datastore.prepare(q).asIterable()) {
+ planSet.add(testPlanEntity.getKey().getName());
+ }
+
+ List<String> plans = new ArrayList<>(planSet);
+ Collections.sort(plans);
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ request.setAttribute("planNames", plans);
+ dispatcher = request.getRequestDispatcher(RELEASE_JSP);
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Excpetion caught : ", e);
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/ShowTableServlet.java b/src/main/java/com/android/vts/servlet/ShowTableServlet.java
new file mode 100644
index 0000000..b525c3d
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/ShowTableServlet.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.entity.TestCaseRunEntity;
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.proto.VtsReportMessage.TestCaseResult;
+import com.android.vts.util.DatastoreHelper;
+import com.android.vts.util.FilterUtil;
+import com.android.vts.util.TestResults;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.FetchOptions;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.SortDirection;
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang.StringUtils;
+
+/** Servlet for handling requests to load individual tables. */
+public class ShowTableServlet extends BaseServlet {
+ private static final String TABLE_JSP = "WEB-INF/jsp/show_table.jsp";
+ // Error message displayed on the webpage is tableName passed is null.
+ private static final String TABLE_NAME_ERROR = "Error : Table name must be passed!";
+ private static final String PROFILING_DATA_ALERT = "No profiling data was found.";
+ private static final int MAX_BUILD_IDS_PER_PAGE = 10;
+
+ @Override
+ public PageType getNavParentType() {
+ return PageType.TOT;
+ }
+
+ @Override
+ public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
+ List<Page> links = new ArrayList<>();
+ String testName = request.getParameter("testName");
+ links.add(new Page(PageType.TABLE, testName, "?testName=" + testName));
+ return links;
+ }
+
+ public static void processTestRun(TestResults testResults, Entity testRun) {
+ TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRun);
+ if (testRunEntity == null) {
+ return;
+ }
+
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ List<Key> gets = new ArrayList<>();
+ for (long testCaseId : testRunEntity.testCaseIds) {
+ gets.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseId));
+ }
+
+ List<Entity> testCases = new ArrayList<>();
+ Map<Key, Entity> entityMap = datastore.get(gets);
+ for (Key key : gets) {
+ if (entityMap.containsKey(key)) {
+ testCases.add(entityMap.get(key));
+ }
+ }
+
+ Query deviceInfoQuery = new Query(DeviceInfoEntity.KIND).setAncestor(testRun.getKey());
+ Iterable<Entity> deviceInfos = datastore.prepare(deviceInfoQuery).asIterable();
+
+ Query profilingPointQuery =
+ new Query(ProfilingPointRunEntity.KIND).setAncestor(testRun.getKey()).setKeysOnly();
+ Iterable<Entity> profilingPoints = datastore.prepare(profilingPointQuery).asIterable();
+
+ testResults.addTestRun(testRun, testCases, deviceInfos, profilingPoints);
+ }
+
+ @Override
+ public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ boolean unfiltered = request.getParameter("unfiltered") != null;
+ boolean showPresubmit = request.getParameter("showPresubmit") != null;
+ boolean showPostsubmit = request.getParameter("showPostsubmit") != null;
+ String searchString = request.getParameter("search");
+ Long startTime = null; // time in microseconds
+ Long endTime = null; // time in microseconds
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ RequestDispatcher dispatcher = null;
+
+ // message to display if profiling point data is not available
+ String profilingDataAlert = "";
+
+ if (request.getParameter("testName") == null) {
+ request.setAttribute("testName", TABLE_NAME_ERROR);
+ return;
+ }
+ String testName = request.getParameter("testName");
+
+ if (request.getParameter("startTime") != null) {
+ String time = request.getParameter("startTime");
+ try {
+ startTime = Long.parseLong(time);
+ startTime = startTime > 0 ? startTime : null;
+ } catch (NumberFormatException e) {
+ startTime = null;
+ }
+ }
+ if (request.getParameter("endTime") != null) {
+ String time = request.getParameter("endTime");
+ try {
+ endTime = Long.parseLong(time);
+ endTime = endTime > 0 ? endTime : null;
+ } catch (NumberFormatException e) {
+ endTime = null;
+ }
+ }
+
+ // If no params are specified, set to default of postsubmit-only.
+ if (!(showPresubmit || showPostsubmit)) {
+ showPostsubmit = true;
+ }
+
+ // If unfiltered, set showPre- and Post-submit to true for accurate UI.
+ if (unfiltered) {
+ showPostsubmit = true;
+ showPresubmit = true;
+ }
+
+ // Add result names to list
+ List<String> resultNames = new ArrayList<>();
+ for (TestCaseResult r : TestCaseResult.values()) {
+ resultNames.add(r.name());
+ }
+
+ TestResults testResults = new TestResults(testName);
+
+ SortDirection dir = SortDirection.DESCENDING;
+ if (startTime != null && endTime == null) {
+ dir = SortDirection.ASCENDING;
+ }
+ Key testKey = KeyFactory.createKey(TestEntity.KIND, testName);
+ Map<String, Object> parameterMap = request.getParameterMap();
+ Filter userTestFilter = FilterUtil.getUserTestFilter(parameterMap);
+ Filter userDeviceFilter = FilterUtil.getUserDeviceFilter(parameterMap);
+
+ Filter typeFilter = FilterUtil.getTestTypeFilter(showPresubmit, showPostsubmit, unfiltered);
+ Filter testFilter = FilterUtil.getTimeFilter(
+ testKey, TestRunEntity.KIND, startTime, endTime, typeFilter);
+ if (userTestFilter == null && userDeviceFilter == null) {
+ Query testRunQuery = new Query(TestRunEntity.KIND)
+ .setAncestor(testKey)
+ .setFilter(testFilter)
+ .addSort(Entity.KEY_RESERVED_PROPERTY, dir);
+ for (Entity testRun :
+ datastore.prepare(testRunQuery)
+ .asIterable(FetchOptions.Builder.withLimit(MAX_BUILD_IDS_PER_PAGE))) {
+ processTestRun(testResults, testRun);
+ }
+ } else {
+ if (userTestFilter != null) {
+ testFilter = CompositeFilterOperator.and(userTestFilter, testFilter);
+ }
+ List<Key> gets = FilterUtil.getMatchingKeys(testKey, TestRunEntity.KIND, testFilter,
+ userDeviceFilter, dir, MAX_BUILD_IDS_PER_PAGE);
+ Map<Key, Entity> entityMap = datastore.get(gets);
+ for (Key key : gets) {
+ if (!entityMap.containsKey(key)) {
+ continue;
+ }
+ processTestRun(testResults, entityMap.get(key));
+ }
+ }
+
+ testResults.processReport();
+
+ if (testResults.profilingPointNames.length == 0) {
+ profilingDataAlert = PROFILING_DATA_ALERT;
+ }
+
+ FilterUtil.setAttributes(request, parameterMap);
+
+ request.setAttribute("testName", request.getParameter("testName"));
+
+ request.setAttribute("error", profilingDataAlert);
+
+ // pass values by converting to JSON
+ request.setAttribute("headerRow", new Gson().toJson(testResults.headerRow));
+ request.setAttribute("timeGrid", new Gson().toJson(testResults.timeGrid));
+ request.setAttribute("durationGrid", new Gson().toJson(testResults.durationGrid));
+ request.setAttribute("summaryGrid", new Gson().toJson(testResults.summaryGrid));
+ request.setAttribute("resultsGrid", new Gson().toJson(testResults.resultsGrid));
+ request.setAttribute("profilingPointNames", testResults.profilingPointNames);
+ request.setAttribute("resultNames", resultNames);
+ request.setAttribute("resultNamesJson", new Gson().toJson(resultNames));
+ request.setAttribute("logInfoMap", new Gson().toJson(testResults.logInfoMap));
+
+ // data for pie chart
+ request.setAttribute(
+ "topBuildResultCounts", new Gson().toJson(testResults.totResultCounts));
+ request.setAttribute("topBuildId", testResults.totBuildId);
+ request.setAttribute("startTime", new Gson().toJson(testResults.startTime));
+ request.setAttribute("endTime", new Gson().toJson(testResults.endTime));
+ request.setAttribute("hasNewer", new Gson().toJson(DatastoreHelper.hasNewer(testKey,
+ TestRunEntity.KIND, testResults.endTime)));
+ request.setAttribute("hasOlder", new Gson().toJson(DatastoreHelper.hasOlder(testKey,
+ TestRunEntity.KIND, testResults.startTime)));
+ request.setAttribute("unfiltered", unfiltered);
+ request.setAttribute("showPresubmit", showPresubmit);
+ request.setAttribute("showPostsubmit", showPostsubmit);
+
+ request.setAttribute("branches", new Gson().toJson(DatastoreHelper.getAllBranches()));
+ request.setAttribute("devices", new Gson().toJson(DatastoreHelper.getAllBuildFlavors()));
+
+ dispatcher = request.getRequestDispatcher(TABLE_JSP);
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Exception caught : " + e.toString());
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/ShowTreeServlet.java b/src/main/java/com/android/vts/servlet/ShowTreeServlet.java
new file mode 100644
index 0000000..d6e759e
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/ShowTreeServlet.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.entity.TestCaseRunEntity;
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.proto.VtsReportMessage.TestCaseResult;
+import com.android.vts.util.DatastoreHelper;
+import com.android.vts.util.FilterUtil;
+import com.android.vts.util.TestRunDetails;
+import com.android.vts.util.TestRunMetadata;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.FetchOptions;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.SortDirection;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang.StringUtils;
+
+/** Servlet for handling requests to load individual tables. */
+public class ShowTreeServlet extends BaseServlet {
+ private static final String TABLE_JSP = "WEB-INF/jsp/show_tree.jsp";
+ // Error message displayed on the webpage is tableName passed is null.
+ private static final String TABLE_NAME_ERROR = "Error : Table name must be passed!";
+ private static final String PROFILING_DATA_ALERT = "No profiling data was found.";
+ private static final int MAX_BUILD_IDS_PER_PAGE = 20;
+ private static final int MAX_PREFETCH_COUNT = 10;
+
+ @Override
+ public PageType getNavParentType() {
+ return PageType.TOT;
+ }
+
+ @Override
+ public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
+ List<Page> links = new ArrayList<>();
+ String testName = request.getParameter("testName");
+ links.add(new Page(PageType.TREE, testName, "?testName=" + testName));
+ return links;
+ }
+
+ /**
+ * Get the test run details for a test run.
+ * @param metadata The metadata for the test run whose details will be fetched.
+ * @return The TestRunDetails object for the provided test run.
+ */
+ public static TestRunDetails processTestDetails(TestRunMetadata metadata) {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ TestRunDetails details = new TestRunDetails();
+ List<Key> gets = new ArrayList<>();
+ for (long testCaseId : metadata.testRun.testCaseIds) {
+ gets.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseId));
+ }
+ Map<Key, Entity> entityMap = datastore.get(gets);
+ for (int i = 0; i < 1; i++) {
+ for (Key key : entityMap.keySet()) {
+ TestCaseRunEntity testCaseRun = TestCaseRunEntity.fromEntity(entityMap.get(key));
+ if (testCaseRun == null) {
+ continue;
+ }
+ details.addTestCase(testCaseRun);
+ }
+ }
+ return details;
+ }
+
+ @Override
+ public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ boolean unfiltered = request.getParameter("unfiltered") != null;
+ boolean showPresubmit = request.getParameter("showPresubmit") != null;
+ boolean showPostsubmit = request.getParameter("showPostsubmit") != null;
+ String searchString = request.getParameter("search");
+ Long startTime = null; // time in microseconds
+ Long endTime = null; // time in microseconds
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ RequestDispatcher dispatcher = null;
+
+ // message to display if profiling point data is not available
+ String profilingDataAlert = "";
+
+ if (request.getParameter("testName") == null) {
+ request.setAttribute("testName", TABLE_NAME_ERROR);
+ return;
+ }
+ String testName = request.getParameter("testName");
+
+ if (request.getParameter("startTime") != null) {
+ String time = request.getParameter("startTime");
+ try {
+ startTime = Long.parseLong(time);
+ startTime = startTime > 0 ? startTime : null;
+ } catch (NumberFormatException e) {
+ startTime = null;
+ }
+ }
+ if (request.getParameter("endTime") != null) {
+ String time = request.getParameter("endTime");
+ try {
+ endTime = Long.parseLong(time);
+ endTime = endTime > 0 ? endTime : null;
+ } catch (NumberFormatException e) {
+ endTime = null;
+ }
+ }
+
+ // If no params are specified, set to default of postsubmit-only.
+ if (!(showPresubmit || showPostsubmit)) {
+ showPostsubmit = true;
+ }
+
+ // If unfiltered, set showPre- and Post-submit to true for accurate UI.
+ if (unfiltered) {
+ showPostsubmit = true;
+ showPresubmit = true;
+ }
+
+ // Add result names to list
+ List<String> resultNames = new ArrayList<>();
+ for (TestCaseResult r : TestCaseResult.values()) {
+ resultNames.add(r.name());
+ }
+
+ SortDirection dir = SortDirection.DESCENDING;
+ if (startTime != null && endTime == null) {
+ dir = SortDirection.ASCENDING;
+ }
+ Key testKey = KeyFactory.createKey(TestEntity.KIND, testName);
+ Map<String, Object> parameterMap = request.getParameterMap();
+ Filter userTestFilter = FilterUtil.getUserTestFilter(parameterMap);
+ Filter userDeviceFilter = FilterUtil.getUserDeviceFilter(parameterMap);
+
+ Filter typeFilter = FilterUtil.getTestTypeFilter(showPresubmit, showPostsubmit, unfiltered);
+ Filter testFilter = FilterUtil.getTimeFilter(
+ testKey, TestRunEntity.KIND, startTime, endTime, typeFilter);
+
+ List<TestRunMetadata> testRunMetadata = new ArrayList<>();
+ if (userTestFilter == null && userDeviceFilter == null) {
+ Query testRunQuery = new Query(TestRunEntity.KIND)
+ .setAncestor(testKey)
+ .setFilter(testFilter)
+ .addSort(Entity.KEY_RESERVED_PROPERTY, dir);
+ for (Entity testRun :
+ datastore.prepare(testRunQuery)
+ .asIterable(FetchOptions.Builder.withLimit(MAX_BUILD_IDS_PER_PAGE))) {
+ TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRun);
+ if (testRunEntity == null) {
+ continue;
+ }
+ TestRunMetadata metadata = new TestRunMetadata(testName, testRunEntity);
+ testRunMetadata.add(metadata);
+ }
+ } else {
+ if (userTestFilter != null) {
+ testFilter = Query.CompositeFilterOperator.and(userTestFilter, testFilter);
+ }
+ List<Key> gets = FilterUtil.getMatchingKeys(testKey, TestRunEntity.KIND, testFilter,
+ userDeviceFilter, dir, MAX_BUILD_IDS_PER_PAGE);
+ Map<Key, Entity> entityMap = datastore.get(gets);
+ for (Key key : gets) {
+ if (!entityMap.containsKey(key)) {
+ continue;
+ }
+ TestRunEntity testRunEntity = TestRunEntity.fromEntity(entityMap.get(key));
+ if (testRunEntity == null) {
+ continue;
+ }
+ TestRunMetadata metadata = new TestRunMetadata(testName, testRunEntity);
+ testRunMetadata.add(metadata);
+ }
+ }
+
+ Comparator<TestRunMetadata> comparator = new Comparator<TestRunMetadata>() {
+ @Override
+ public int compare(TestRunMetadata t1, TestRunMetadata t2) {
+ return new Long(t2.testRun.startTimestamp).compareTo(t1.testRun.startTimestamp);
+ }
+ };
+ Collections.sort(testRunMetadata, comparator);
+ List<JsonObject> testRunObjects = new ArrayList<>();
+
+ int prefetchCount = 0;
+ for (TestRunMetadata metadata : testRunMetadata) {
+ if (metadata.testRun.failCount > 0 && prefetchCount < MAX_PREFETCH_COUNT) {
+ // process
+ metadata.addDetails(processTestDetails(metadata));
+ ++prefetchCount;
+ }
+ testRunObjects.add(metadata.toJson());
+ }
+
+ int[] topBuildResultCounts = null;
+ String topBuild = "";
+ if (testRunMetadata.size() > 0) {
+ TestRunMetadata firstRun = testRunMetadata.get(0);
+ topBuild = firstRun.getDeviceInfo();
+ endTime = firstRun.testRun.startTimestamp;
+ TestRunDetails topDetails = firstRun.getDetails();
+ if (topDetails == null) {
+ topDetails = processTestDetails(firstRun);
+ }
+ topBuildResultCounts = topDetails.resultCounts;
+
+ TestRunMetadata lastRun = testRunMetadata.get(testRunMetadata.size() - 1);
+ startTime = lastRun.testRun.startTimestamp;
+ }
+
+ Set<String> profilingPoints = new HashSet<>();
+ Query profilingPointQuery =
+ new Query(ProfilingPointRunEntity.KIND).setAncestor(testKey).setKeysOnly();
+ for (Entity e : datastore.prepare(profilingPointQuery).asIterable()) {
+ profilingPoints.add(e.getKey().getName());
+ }
+
+ if (profilingPoints.size() == 0) {
+ profilingDataAlert = PROFILING_DATA_ALERT;
+ }
+ List<String> profilingPointNames = new ArrayList<>(profilingPoints);
+ Collections.sort(profilingPointNames);
+
+ FilterUtil.setAttributes(request, parameterMap);
+
+ request.setAttribute("testName", request.getParameter("testName"));
+
+ request.setAttribute("error", profilingDataAlert);
+
+ request.setAttribute("profilingPointNames", profilingPointNames);
+ request.setAttribute("resultNames", resultNames);
+ request.setAttribute("resultNamesJson", new Gson().toJson(resultNames));
+ request.setAttribute("testRuns", new Gson().toJson(testRunObjects));
+
+ // data for pie chart
+ request.setAttribute("topBuildResultCounts", new Gson().toJson(topBuildResultCounts));
+ request.setAttribute("topBuildId", topBuild);
+ request.setAttribute("startTime", new Gson().toJson(startTime));
+ request.setAttribute("endTime", new Gson().toJson(endTime));
+ request.setAttribute("hasNewer",
+ new Gson().toJson(DatastoreHelper.hasNewer(testKey, TestRunEntity.KIND, endTime)));
+ request.setAttribute("hasOlder", new Gson().toJson(DatastoreHelper.hasOlder(
+ testKey, TestRunEntity.KIND, startTime)));
+ request.setAttribute("unfiltered", unfiltered);
+ request.setAttribute("showPresubmit", showPresubmit);
+ request.setAttribute("showPostsubmit", showPostsubmit);
+
+ request.setAttribute("branches", new Gson().toJson(DatastoreHelper.getAllBranches()));
+ request.setAttribute("devices", new Gson().toJson(DatastoreHelper.getAllBuildFlavors()));
+
+ dispatcher = request.getRequestDispatcher(TABLE_JSP);
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Exception caught : " + e.toString());
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java b/src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java
new file mode 100644
index 0000000..9e48108
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.TestCaseRunEntity;
+import com.android.vts.entity.TestCaseRunEntity.TestCase;
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.TestEntity.TestCaseReference;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.proto.VtsReportMessage.TestCaseResult;
+import com.android.vts.util.DatastoreHelper;
+import com.android.vts.util.EmailHelper;
+import com.android.vts.util.FilterUtil;
+import com.google.appengine.api.datastore.DatastoreFailureException;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.DatastoreTimeoutException;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.EntityNotFoundException;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.SortDirection;
+import com.google.appengine.api.datastore.Transaction;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.ConcurrentModificationException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.math3.analysis.function.Add;
+
+/** Represents the notifications service which is automatically called on a fixed schedule. */
+public class VtsAlertJobServlet extends HttpServlet {
+ protected final Logger logger = Logger.getLogger(getClass().getName());
+
+ /**
+ * Creates an email footer with the provided link.
+ *
+ * @param link The (string) link to provide in the footer.
+ * @return The full HTML email footer.
+ */
+ private String getFooter(String link) {
+ return "<br><br>For details, visit the"
+ + " <a href='" + link + "'>"
+ + "VTS dashboard.</a>";
+ }
+
+ /**
+ * Compose an email if the test is inactive.
+ *
+ * @param test The TestEntity document storing the test status.
+ * @param link Fully specified link to the test's status page.
+ * @param emails The list of email addresses to send the email.
+ * @param messages The message list in which to insert the inactivity notification email.
+ * @return True if the test is inactive, false otherwise.
+ */
+ private boolean notifyIfInactive(
+ TestEntity test, String link, List<String> emails, List<Message> messages) {
+ long now = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
+ long diff = now - test.timestamp;
+ // Send an email daily to notify that the test hasn't been running.
+ // After 7 full days have passed, notifications will no longer be sent (i.e. the
+ // test is assumed to be deprecated).
+ if (diff > TimeUnit.DAYS.toMicros(1) && diff < TimeUnit.DAYS.toMicros(8)
+ && diff % TimeUnit.DAYS.toMicros(1) < TimeUnit.MINUTES.toMicros(3)) {
+ Date lastUpload = new Date(TimeUnit.MICROSECONDS.toMillis(test.timestamp));
+ String uploadTimeString =
+ new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(lastUpload);
+ String subject = "Warning! Inactive test: " + test.testName;
+ String body = "Hello,<br><br>Test \"" + test.testName + "\" is inactive. "
+ + "No new data has been uploaded since " + uploadTimeString + "."
+ + getFooter(link);
+ try {
+ messages.add(EmailHelper.composeEmail(emails, subject, body));
+ return true;
+ } catch (MessagingException | UnsupportedEncodingException e) {
+ logger.log(Level.WARNING, "Error composing email : ", e);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks whether any new failures have occurred beginning since (and including) startTime.
+ *
+ * @param test The TestEntity object for the test.
+ * @param link The string URL linking to the test's status table.
+ * @param failedTestCaseMap The map of test case names to TestCase for those failing in the
+ * last status update.
+ * @param emailAddresses The list of email addresses to send notifications to.
+ * @param messages The email Message queue.
+ * @returns latest TestStatusMessage or null if no update is available.
+ * @throws IOException
+ */
+ public TestEntity getTestStatus(TestEntity test, String link,
+ Map<String, TestCase> failedTestCaseMap, List<String> emailAddresses,
+ List<Message> messages) throws IOException {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ String footer = getFooter(link);
+
+ TestRunEntity mostRecentRun = null;
+ Map<String, TestCaseResult> mostRecentTestCaseResults = new HashMap<>();
+ Map<String, TestCase> testCaseBreakageMap = new HashMap<>();
+ int passingTestcaseCount = 0;
+ List<TestCaseReference> failingTestCases = new ArrayList<>();
+ Set<String> fixedTestcases = new HashSet<>();
+ Set<String> newTestcaseFailures = new HashSet<>();
+ Set<String> continuedTestcaseFailures = new HashSet<>();
+ Set<String> skippedTestcaseFailures = new HashSet<>();
+ Set<String> transientTestcaseFailures = new HashSet<>();
+
+ String testName = test.testName;
+ Key testKey = KeyFactory.createKey(TestEntity.KIND, testName);
+ Filter testTypeFilter = FilterUtil.getTestTypeFilter(false, true, false);
+ Filter runFilter = FilterUtil.getTimeFilter(
+ testKey, TestRunEntity.KIND, test.timestamp + 1, null, testTypeFilter);
+ Query q = new Query(TestRunEntity.KIND)
+ .setAncestor(testKey)
+ .setFilter(runFilter)
+ .addSort(Entity.KEY_RESERVED_PROPERTY, SortDirection.DESCENDING);
+
+ for (Entity testRun : datastore.prepare(q).asIterable()) {
+ TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRun);
+ if (testRunEntity == null) {
+ logger.log(Level.WARNING, "Invalid test run detected: " + testRun.getKey());
+ }
+ if (mostRecentRun == null) {
+ mostRecentRun = testRunEntity;
+ }
+ List<Key> testCaseKeys = new ArrayList<>();
+ for (long testCaseId : testRunEntity.testCaseIds) {
+ testCaseKeys.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseId));
+ }
+ Map<Key, Entity> entityMap = datastore.get(testCaseKeys);
+ for (Key testCaseKey : testCaseKeys) {
+ if (!entityMap.containsKey(testCaseKey)) {
+ logger.log(Level.WARNING, "Test case entity missing: " + testCaseKey);
+ continue;
+ }
+ Entity testCaseRun = entityMap.get(testCaseKey);
+ TestCaseRunEntity testCaseRunEntity = TestCaseRunEntity.fromEntity(testCaseRun);
+ if (testCaseRunEntity == null) {
+ logger.log(Level.WARNING, "Invalid test case run: " + testCaseRun.getKey());
+ continue;
+ }
+ for (TestCase testCase : testCaseRunEntity.testCases) {
+ String testCaseName = testCase.name;
+ TestCaseResult result = TestCaseResult.valueOf(testCase.result);
+
+ if (mostRecentRun == testRunEntity) {
+ mostRecentTestCaseResults.put(testCaseName, result);
+ } else {
+ if (!mostRecentTestCaseResults.containsKey(testCaseName)) {
+ // Deprecate notifications for tests that are not present on newer runs
+ continue;
+ }
+ TestCaseResult mostRecentRes = mostRecentTestCaseResults.get(testCaseName);
+ if (mostRecentRes == TestCaseResult.TEST_CASE_RESULT_SKIP) {
+ mostRecentTestCaseResults.put(testCaseName, result);
+ } else if (mostRecentRes == TestCaseResult.TEST_CASE_RESULT_PASS) {
+ // Test is passing now, witnessed a transient failure
+ if (result != TestCaseResult.TEST_CASE_RESULT_PASS
+ && result != TestCaseResult.TEST_CASE_RESULT_SKIP) {
+ transientTestcaseFailures.add(testCaseName);
+ }
+ }
+ }
+
+ // Record test case breakages
+ if (result != TestCaseResult.TEST_CASE_RESULT_PASS
+ && result != TestCaseResult.TEST_CASE_RESULT_SKIP) {
+ testCaseBreakageMap.put(testCaseName, testCase);
+ }
+ }
+ }
+ }
+
+ if (mostRecentRun == null) {
+ notifyIfInactive(test, link, emailAddresses, messages);
+ return null;
+ }
+
+ for (String testCaseName : mostRecentTestCaseResults.keySet()) {
+ TestCaseResult mostRecentResult = mostRecentTestCaseResults.get(testCaseName);
+ boolean previouslyFailed = failedTestCaseMap.containsKey(testCaseName);
+ if (mostRecentResult == TestCaseResult.TEST_CASE_RESULT_SKIP) {
+ // persist previous status
+ if (previouslyFailed) {
+ failingTestCases.add(
+ new TestCaseReference(failedTestCaseMap.get(testCaseName)));
+ } else {
+ ++passingTestcaseCount;
+ }
+ } else if (mostRecentResult == TestCaseResult.TEST_CASE_RESULT_PASS) {
+ ++passingTestcaseCount;
+ if (previouslyFailed && !transientTestcaseFailures.contains(testCaseName)) {
+ fixedTestcases.add(testCaseName);
+ }
+ } else {
+ if (!previouslyFailed) {
+ newTestcaseFailures.add(testCaseName);
+ failingTestCases.add(
+ new TestCaseReference(testCaseBreakageMap.get(testCaseName)));
+ } else {
+ continuedTestcaseFailures.add(testCaseName);
+ failingTestCases.add(
+ new TestCaseReference(failedTestCaseMap.get(testCaseName)));
+ }
+ }
+ }
+
+ Set<String> buildIdList = new HashSet<>();
+ Query deviceQuery = new Query(DeviceInfoEntity.KIND).setAncestor(mostRecentRun.key);
+ for (Entity device : datastore.prepare(deviceQuery).asIterable()) {
+ DeviceInfoEntity deviceEntity = DeviceInfoEntity.fromEntity(device);
+ if (deviceEntity == null) {
+ continue;
+ }
+ buildIdList.add(deviceEntity.buildId);
+ }
+ String buildId = StringUtils.join(buildIdList, ",");
+ String summary = new String();
+ if (newTestcaseFailures.size() + continuedTestcaseFailures.size() > 0) {
+ summary += "The following test cases failed in the latest test run:<br>";
+
+ // Add new test case failures to top of summary in bold font.
+ List<String> sortedNewTestcaseFailures = new ArrayList<>(newTestcaseFailures);
+ Collections.sort(sortedNewTestcaseFailures);
+ for (String testcaseName : sortedNewTestcaseFailures) {
+ summary += "- "
+ + "<b>" + testcaseName + "</b><br>";
+ }
+
+ // Add continued test case failures to summary.
+ List<String> sortedContinuedTestcaseFailures =
+ new ArrayList<>(continuedTestcaseFailures);
+ Collections.sort(sortedContinuedTestcaseFailures);
+ for (String testcaseName : sortedContinuedTestcaseFailures) {
+ summary += "- " + testcaseName + "<br>";
+ }
+ }
+ if (fixedTestcases.size() > 0) {
+ // Add fixed test cases to summary.
+ summary += "<br><br>The following test cases were fixed in the latest test run:<br>";
+ List<String> sortedFixedTestcases = new ArrayList<>(fixedTestcases);
+ Collections.sort(sortedFixedTestcases);
+ for (String testcaseName : sortedFixedTestcases) {
+ summary += "- <i>" + testcaseName + "</i><br>";
+ }
+ }
+ if (transientTestcaseFailures.size() > 0) {
+ // Add transient test case failures to summary.
+ summary += "<br><br>The following transient test case failures occured:<br>";
+ List<String> sortedTransientTestcaseFailures =
+ new ArrayList<>(transientTestcaseFailures);
+ Collections.sort(sortedTransientTestcaseFailures);
+ for (String testcaseName : sortedTransientTestcaseFailures) {
+ summary += "- " + testcaseName + "<br>";
+ }
+ }
+ if (skippedTestcaseFailures.size() > 0) {
+ // Add skipped test case failures to summary.
+ summary += "<br><br>The following test cases have not been run since failing:<br>";
+ List<String> sortedSkippedTestcaseFailures = new ArrayList<>(skippedTestcaseFailures);
+ Collections.sort(sortedSkippedTestcaseFailures);
+ for (String testcaseName : sortedSkippedTestcaseFailures) {
+ summary += "- " + testcaseName + "<br>";
+ }
+ }
+
+ if (newTestcaseFailures.size() > 0) {
+ String subject = "New test failures in " + testName + " @ " + buildId;
+ String body = "Hello,<br><br>Test cases are failing in " + testName
+ + " for device build ID(s): " + buildId + ".<br><br>" + summary + footer;
+ try {
+ messages.add(EmailHelper.composeEmail(emailAddresses, subject, body));
+ } catch (MessagingException | UnsupportedEncodingException e) {
+ logger.log(Level.WARNING, "Error composing email : ", e);
+ }
+ } else if (continuedTestcaseFailures.size() > 0) {
+ String subject = "Continued test failures in " + testName + " @ " + buildId;
+ String body = "Hello,<br><br>Test cases are failing in " + testName
+ + " for device build ID(s): " + buildId + ".<br><br>" + summary + footer;
+ try {
+ messages.add(EmailHelper.composeEmail(emailAddresses, subject, body));
+ } catch (MessagingException | UnsupportedEncodingException e) {
+ logger.log(Level.WARNING, "Error composing email : ", e);
+ }
+ } else if (transientTestcaseFailures.size() > 0) {
+ String subject = "Transient test failure in " + testName + " @ " + buildId;
+ String body = "Hello,<br><br>Some test cases failed in " + testName + " but tests all "
+ + "are passing in the latest device build(s): " + buildId + ".<br><br>"
+ + summary + footer;
+ try {
+ messages.add(EmailHelper.composeEmail(emailAddresses, subject, body));
+ } catch (MessagingException | UnsupportedEncodingException e) {
+ logger.log(Level.WARNING, "Error composing email : ", e);
+ }
+ } else if (fixedTestcases.size() > 0) {
+ String subject = "All test cases passing in " + testName + " @ " + buildId;
+ String body = "Hello,<br><br>All test cases passed in " + testName
+ + " for device build ID(s): " + buildId + "!<br><br>" + summary + footer;
+ try {
+ messages.add(EmailHelper.composeEmail(emailAddresses, subject, body));
+ } catch (MessagingException | UnsupportedEncodingException e) {
+ logger.log(Level.WARNING, "Error composing email : ", e);
+ }
+ }
+ return new TestEntity(test.testName, mostRecentRun.startTimestamp, passingTestcaseCount,
+ failingTestCases.size(), failingTestCases);
+ }
+
+ /**
+ * Process the current test case failures for a test.
+ *
+ * @param testEntity The TestEntity object for the test.
+ * @returns a map from test case name to the test case run ID for which the test case failed.
+ */
+ public static Map<String, TestCase> getCurrentFailures(TestEntity testEntity) {
+ if (testEntity.failingTestCases == null || testEntity.failingTestCases.size() == 0) {
+ return new HashMap<>();
+ }
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Map<String, TestCase> failingTestcases = new HashMap<>();
+ Set<Key> gets = new HashSet<>();
+ for (TestCaseReference testCaseRef : testEntity.failingTestCases) {
+ gets.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseRef.parentId));
+ }
+ if (gets.size() == 0) {
+ return failingTestcases;
+ }
+ Map<Key, Entity> testCaseMap = datastore.get(gets);
+
+ for (TestCaseReference testCaseRef : testEntity.failingTestCases) {
+ Key key = KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseRef.parentId);
+ if (!testCaseMap.containsKey(key)) {
+ continue;
+ }
+ Entity testCaseRun = testCaseMap.get(key);
+ TestCaseRunEntity testCaseRunEntity = TestCaseRunEntity.fromEntity(testCaseRun);
+ if (testCaseRunEntity.testCases.size() <= testCaseRef.offset) {
+ continue;
+ }
+ TestCase testCase = testCaseRunEntity.testCases.get(testCaseRef.offset);
+ failingTestcases.put(testCase.name, testCase);
+ }
+ return failingTestcases;
+ }
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Query q = new Query(TestEntity.KIND);
+ for (Entity test : datastore.prepare(q).asIterable()) {
+ TestEntity testEntity = TestEntity.fromEntity(test);
+ if (testEntity == null) {
+ logger.log(Level.WARNING, "Corrupted test entity: " + test.getKey().getName());
+ continue;
+ }
+ List<String> emails = EmailHelper.getSubscriberEmails(test.getKey());
+
+ StringBuffer fullUrl = request.getRequestURL();
+ String baseUrl = fullUrl.substring(0, fullUrl.indexOf(request.getRequestURI()));
+ String link = baseUrl + "/show_table?testName=" + testEntity.testName;
+
+ List<Message> messageQueue = new ArrayList<>();
+ Map<String, TestCase> failedTestcaseMap = getCurrentFailures(testEntity);
+
+ TestEntity newTestEntity =
+ getTestStatus(testEntity, link, failedTestcaseMap, emails, messageQueue);
+
+ // Send any inactivity notifications
+ if (newTestEntity == null) {
+ if (messageQueue.size() > 0) {
+ EmailHelper.sendAll(messageQueue);
+ }
+ continue;
+ }
+
+ int retries = 0;
+ while (true) {
+ Transaction txn = datastore.beginTransaction();
+ try {
+ try {
+ testEntity = TestEntity.fromEntity(datastore.get(test.getKey()));
+
+ // Another job updated the test entity
+ if (testEntity == null || testEntity.timestamp >= newTestEntity.timestamp) {
+ txn.rollback();
+ } else { // This update is most recent.
+ datastore.put(newTestEntity.toEntity());
+ txn.commit();
+ EmailHelper.sendAll(messageQueue);
+ }
+ } catch (EntityNotFoundException e) {
+ logger.log(Level.INFO,
+ "Test disappeared during updated: " + newTestEntity.testName);
+ }
+ break;
+ } catch (ConcurrentModificationException | DatastoreFailureException
+ | DatastoreTimeoutException e) {
+ logger.log(Level.WARNING, "Retrying alert job insert: " + test.getKey());
+ if (retries++ >= DatastoreHelper.MAX_WRITE_RETRIES) {
+ logger.log(Level.SEVERE, "Exceeded alert job retries: " + test.getKey());
+ throw e;
+ }
+ } finally {
+ if (txn.isActive()) {
+ txn.rollback();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java b/src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java
new file mode 100644
index 0000000..616f5c7
--- /dev/null
+++ b/src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import com.android.vts.entity.TestEntity;
+import com.android.vts.util.EmailHelper;
+import com.android.vts.util.PerformanceSummary;
+import com.android.vts.util.PerformanceUtil;
+import com.android.vts.util.PerformanceUtil.TimeInterval;
+import com.android.vts.util.ProfilingPointSummary;
+import com.android.vts.util.StatSummary;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.Query;
+import java.io.IOException;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Represents the notifications service which is automatically called on a fixed schedule. */
+public class VtsPerformanceJobServlet extends HttpServlet {
+ private static final String MEAN = "Mean";
+ private static final String MAX = "Max";
+ private static final String MIN = "Min";
+ private static final String MIN_DELTA = "&Delta;Min (%)";
+ private static final String MAX_DELTA = "&Delta;Max (%)";
+ private static final String HIGHER_IS_BETTER =
+ "Note: Higher values are better. Maximum is the best-case performance.";
+ private static final String LOWER_IS_BETTER =
+ "Note: Lower values are better. Minimum is the best-case performance.";
+ private static final String STD = "Std";
+ private static final String SUBJECT_PREFIX = "Daily Performance Digest: ";
+ private static final String LAST_WEEK = "Last Week";
+ private static final String LABEL_STYLE = "font-family: arial";
+ private static final String SUBTEXT_STYLE = "font-family: arial; font-size: 12px";
+ private static final String TABLE_STYLE =
+ "width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;";
+ private static final String SECTION_LABEL_STYLE =
+ "border: 1px solid black; border-bottom: none; background-color: lightgray;";
+ private static final String COL_LABEL_STYLE =
+ "border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;";
+ private static final String HEADER_COL_STYLE =
+ "border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;";
+ private static final String INNER_CELL_STYLE =
+ "border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;";
+ private static final String OUTER_CELL_STYLE =
+ "border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;";
+
+ private static final DecimalFormat FORMATTER;
+
+ /**
+ * Initialize the decimal formatter.
+ */
+ static {
+ FORMATTER = new DecimalFormat("#.##");
+ FORMATTER.setRoundingMode(RoundingMode.HALF_UP);
+ }
+
+ /**
+ * Generates an HTML summary of the performance changes for the profiling results in the
+ * specified
+ * table.
+ *
+ * <p>Retrieves the past 24 hours of profiling data and compares it to the 24 hours that
+ * preceded
+ * it. Creates a table representation of the mean and standard deviation for each profiling
+ * point.
+ * When performance degrades, the cell is shaded red.
+ *
+ * @param testName The name of the test whose profiling data to summarize.
+ * @param perfSummaries List of PerformanceSummary objects for each profiling run (in reverse
+ * chronological order).
+ * @param labels List of string labels for use as the column headers.
+ * @returns An HTML string containing labeled table summaries.
+ */
+ public static String getPeformanceSummary(
+ String testName, List<PerformanceSummary> perfSummaries, List<String> labels) {
+ if (perfSummaries.size() == 0)
+ return "";
+ PerformanceSummary now = perfSummaries.get(0);
+ String tableHTML = "<p style='" + LABEL_STYLE + "'><b>";
+ tableHTML += testName + "</b></p>";
+ for (String profilingPoint : now.getProfilingPointNames()) {
+ ProfilingPointSummary summary = now.getProfilingPointSummary(profilingPoint);
+ tableHTML += "<table cellpadding='2' style='" + TABLE_STYLE + "'>";
+
+ // Format header rows
+ String[] headerRows = new String[] {profilingPoint, summary.yLabel};
+ int colspan = labels.size() * 4;
+ for (String content : headerRows) {
+ tableHTML += "<tr><td colspan='" + colspan + "'>" + content + "</td></tr>";
+ }
+
+ // Format section labels
+ tableHTML += "<tr>";
+ for (int i = 0; i < labels.size(); i++) {
+ String content = labels.get(i);
+ tableHTML += "<th style='" + SECTION_LABEL_STYLE + "' ";
+ if (i == 0)
+ tableHTML += "colspan='1'";
+ else if (i == 1)
+ tableHTML += "colspan='3'";
+ else
+ tableHTML += "colspan='4'";
+ tableHTML += ">" + content + "</th>";
+ }
+ tableHTML += "</tr>";
+
+ String deltaString;
+ String bestCaseString;
+ String subtext;
+ switch (now.getProfilingPointSummary(profilingPoint).getRegressionMode()) {
+ case VTS_REGRESSION_MODE_DECREASING:
+ deltaString = MAX_DELTA;
+ bestCaseString = MAX;
+ subtext = HIGHER_IS_BETTER;
+ break;
+ default:
+ deltaString = MIN_DELTA;
+ bestCaseString = MIN;
+ subtext = LOWER_IS_BETTER;
+ break;
+ }
+
+ // Format column labels
+ tableHTML += "<tr>";
+ for (int i = 0; i < labels.size(); i++) {
+ if (i > 1) {
+ tableHTML += "<th style='" + COL_LABEL_STYLE + "'>" + deltaString + "</th>";
+ }
+ if (i == 0) {
+ tableHTML += "<th style='" + COL_LABEL_STYLE + "'>";
+ tableHTML += summary.xLabel + "</th>";
+ } else if (i > 0) {
+ tableHTML += "<th style='" + COL_LABEL_STYLE + "'>" + bestCaseString + "</th>";
+ tableHTML += "<th style='" + COL_LABEL_STYLE + "'>" + MEAN + "</th>";
+ tableHTML += "<th style='" + COL_LABEL_STYLE + "'>" + STD + "</th>";
+ }
+ }
+ tableHTML += "</tr>";
+
+ // Populate data cells
+ for (StatSummary stats : summary) {
+ String label = stats.getLabel();
+ tableHTML += "<tr><td style='" + HEADER_COL_STYLE + "'>" + label;
+ tableHTML += "</td><td style='" + INNER_CELL_STYLE + "'>";
+ tableHTML += FORMATTER.format(stats.getBestCase()) + "</td>";
+ tableHTML += "<td style='" + INNER_CELL_STYLE + "'>";
+ tableHTML += FORMATTER.format(stats.getMean()) + "</td>";
+ tableHTML += "<td style='" + OUTER_CELL_STYLE + "'>";
+ tableHTML += FORMATTER.format(stats.getStd()) + "</td>";
+ for (int i = 1; i < perfSummaries.size(); i++) {
+ PerformanceSummary oldPerfSummary = perfSummaries.get(i);
+ if (oldPerfSummary.hasProfilingPoint(profilingPoint)) {
+ StatSummary baseline =
+ oldPerfSummary.getProfilingPointSummary(profilingPoint)
+ .getStatSummary(label);
+ tableHTML += PerformanceUtil.getBestCasePerformanceComparisonHTML(
+ baseline, stats, "", "", INNER_CELL_STYLE, OUTER_CELL_STYLE);
+ } else
+ tableHTML += "<td></td><td></td><td></td><td></td>";
+ }
+ tableHTML += "</tr>";
+ }
+ tableHTML += "</table>";
+ tableHTML += "<i style='" + SUBTEXT_STYLE + "'>" + subtext + "</i><br><br>";
+ }
+ return tableHTML;
+ }
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Set<Key> allTestKeys = new HashSet<>();
+
+ Query q = new Query(TestEntity.KIND).setKeysOnly();
+ for (Entity test : datastore.prepare(q).asIterable()) {
+ if (test.getKey().getName() == null) {
+ continue;
+ }
+ allTestKeys.add(test.getKey());
+ }
+
+ // Add today to the list of time intervals to analyze
+ List<TimeInterval> timeIntervals = new ArrayList<>();
+ long nowMilli = System.currentTimeMillis();
+ long nowMicro = TimeUnit.MILLISECONDS.toMicros(nowMilli);
+ String dateString = new SimpleDateFormat("MM-dd-yyyy").format(new Date(nowMilli));
+ TimeInterval today =
+ new TimeInterval(nowMicro - TimeUnit.DAYS.toMicros(1), nowMicro, dateString);
+ timeIntervals.add(today);
+
+ // Add yesterday as a baseline time interval for analysis
+ long oneDayAgo = nowMicro - TimeUnit.DAYS.toMicros(1);
+ String dateStringYesterday = new SimpleDateFormat(
+ "MM-dd-yyyy").format(new Date(TimeUnit.MICROSECONDS.toMillis(oneDayAgo)));
+ TimeInterval yesterday = new TimeInterval(
+ oneDayAgo - TimeUnit.DAYS.toMicros(1), oneDayAgo, dateStringYesterday);
+ timeIntervals.add(yesterday);
+
+ // Add last week as a baseline time interval for analysis
+ long oneWeek = TimeUnit.DAYS.toMicros(7);
+ long oneWeekAgo = nowMicro - oneWeek;
+ TimeInterval lastWeek = new TimeInterval(oneWeekAgo - oneWeek, oneWeekAgo, LAST_WEEK);
+ timeIntervals.add(lastWeek);
+
+ for (Key testKey : allTestKeys) {
+ List<PerformanceSummary> perfSummaries = new ArrayList<>();
+ List<String> labels = new ArrayList<>();
+ labels.add("");
+ for (TimeInterval interval : timeIntervals) {
+ PerformanceSummary perfSummary = new PerformanceSummary();
+ PerformanceUtil.updatePerformanceSummary(
+ testKey.getName(), interval.start, interval.end, null, perfSummary);
+ if (perfSummary.size() == 0) {
+ continue;
+ }
+ perfSummaries.add(perfSummary);
+ labels.add(interval.label);
+ }
+ String body = getPeformanceSummary(testKey.getName(), perfSummaries, labels);
+ if (body == null || body.equals("")) {
+ continue;
+ }
+ List<String> emails = EmailHelper.getSubscriberEmails(testKey);
+ if (emails.size() == 0) {
+ continue;
+ }
+ String subject = SUBJECT_PREFIX + testKey.getName();
+ EmailHelper.send(emails, subject, body);
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/util/DatastoreHelper.java b/src/main/java/com/android/vts/util/DatastoreHelper.java
new file mode 100644
index 0000000..4710b88
--- /dev/null
+++ b/src/main/java/com/android/vts/util/DatastoreHelper.java
@@ -0,0 +1,457 @@
+/**
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>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.vts.util;
+
+import com.android.vts.entity.CoverageEntity;
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.entity.TestCaseRunEntity;
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.TestPlanEntity;
+import com.android.vts.entity.TestPlanRunEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.entity.TestRunEntity.TestRunType;
+import com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage;
+import com.android.vts.proto.VtsReportMessage.CoverageReportMessage;
+import com.android.vts.proto.VtsReportMessage.LogMessage;
+import com.android.vts.proto.VtsReportMessage.ProfilingReportMessage;
+import com.android.vts.proto.VtsReportMessage.TestCaseReportMessage;
+import com.android.vts.proto.VtsReportMessage.TestCaseResult;
+import com.android.vts.proto.VtsReportMessage.TestPlanReportMessage;
+import com.android.vts.proto.VtsReportMessage.TestReportMessage;
+import com.google.appengine.api.datastore.DatastoreFailureException;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.DatastoreTimeoutException;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.EntityNotFoundException;
+import com.google.appengine.api.datastore.FetchOptions;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.KeyRange;
+import com.google.appengine.api.datastore.PropertyProjection;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.FilterOperator;
+import com.google.appengine.api.datastore.Query.FilterPredicate;
+import com.google.appengine.api.datastore.Transaction;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** DatastoreHelper, a helper class for interacting with Cloud Datastore. */
+public class DatastoreHelper {
+ protected static final Logger logger = Logger.getLogger(DatastoreHelper.class.getName());
+ public static final int MAX_WRITE_RETRIES = 5;
+
+ /**
+ * Returns true if there are data points newer than lowerBound in the results table.
+ *
+ * @param parentKey The parent key to use in the query.
+ * @param kind The query entity kind.
+ * @param lowerBound The (exclusive) lower time bound, long, microseconds.
+ * @return boolean True if there are newer data points.
+ * @throws IOException
+ */
+ public static boolean hasNewer(Key parentKey, String kind, Long lowerBound) throws IOException {
+ if (lowerBound == null || lowerBound <= 0)
+ return false;
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Key startKey = KeyFactory.createKey(parentKey, kind, lowerBound);
+ Filter startFilter = new FilterPredicate(
+ Entity.KEY_RESERVED_PROPERTY, FilterOperator.GREATER_THAN, startKey);
+ Query q = new Query(kind).setAncestor(parentKey).setFilter(startFilter).setKeysOnly();
+ return datastore.prepare(q).countEntities(FetchOptions.Builder.withLimit(1)) > 0;
+ }
+
+ /**
+ * Returns true if there are data points older than upperBound in the table.
+ *
+ * @param parentKey The parent key to use in the query.
+ * @param kind The query entity kind.
+ * @param upperBound The (exclusive) upper time bound, long, microseconds.
+ * @return boolean True if there are older data points.
+ * @throws IOException
+ */
+ public static boolean hasOlder(Key parentKey, String kind, Long upperBound) throws IOException {
+ if (upperBound == null || upperBound <= 0)
+ return false;
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Key endKey = KeyFactory.createKey(parentKey, kind, upperBound);
+ Filter endFilter =
+ new FilterPredicate(Entity.KEY_RESERVED_PROPERTY, FilterOperator.LESS_THAN, endKey);
+ Query q = new Query(kind).setAncestor(parentKey).setFilter(endFilter).setKeysOnly();
+ return datastore.prepare(q).countEntities(FetchOptions.Builder.withLimit(1)) > 0;
+ }
+
+ /**
+ * Determines if any entities match the provided query.
+ *
+ * @param query The query to test.
+ * @return true if entities match the query.
+ */
+ public static boolean hasEntities(Query query) {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ FetchOptions limitOne = FetchOptions.Builder.withLimit(1);
+ return datastore.prepare(query).countEntities(limitOne) > 0;
+ }
+
+ /**
+ * Get all of the target product names.
+ *
+ * @return a list of all device product names.
+ */
+ public static List<String> getAllProducts() {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Query query = new Query(DeviceInfoEntity.KIND)
+ .addProjection(new PropertyProjection(
+ DeviceInfoEntity.PRODUCT, String.class))
+ .setDistinct(true);
+ List<String> devices = new ArrayList<>();
+ for (Entity e : datastore.prepare(query).asIterable()) {
+ devices.add((String) e.getProperty(DeviceInfoEntity.PRODUCT));
+ }
+ return devices;
+ }
+
+ /**
+ * Get all of the devices branches.
+ *
+ * @return a list of all branches.
+ */
+ public static List<String> getAllBranches() {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Query query = new Query(DeviceInfoEntity.KIND)
+ .addProjection(
+ new PropertyProjection(DeviceInfoEntity.BRANCH, String.class))
+ .setDistinct(true);
+ List<String> devices = new ArrayList<>();
+ for (Entity e : datastore.prepare(query).asIterable()) {
+ devices.add((String) e.getProperty(DeviceInfoEntity.BRANCH));
+ }
+ return devices;
+ }
+
+ /**
+ * Get all of the device build flavors.
+ *
+ * @return a list of all device build flavors.
+ */
+ public static List<String> getAllBuildFlavors() {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Query query = new Query(DeviceInfoEntity.KIND)
+ .addProjection(new PropertyProjection(
+ DeviceInfoEntity.BUILD_FLAVOR, String.class))
+ .setDistinct(true);
+ List<String> devices = new ArrayList<>();
+ for (Entity e : datastore.prepare(query).asIterable()) {
+ devices.add((String) e.getProperty(DeviceInfoEntity.BUILD_FLAVOR));
+ }
+ return devices;
+ }
+
+ /**
+ * Upload data from a test report message
+ *
+ * @param report The test report containing data to upload.
+ */
+ public static void insertTestReport(TestReportMessage report) {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Set<Entity> puts = new HashSet<>();
+
+ if (!report.hasStartTimestamp() || !report.hasEndTimestamp() || !report.hasTest()
+ || !report.hasHostInfo() || !report.hasBuildInfo()) {
+ // missing information
+ return;
+ }
+ long startTimestamp = report.getStartTimestamp();
+ long endTimestamp = report.getEndTimestamp();
+ String testName = report.getTest().toStringUtf8();
+ String testBuildId = report.getBuildInfo().getId().toStringUtf8();
+ String hostName = report.getHostInfo().getHostname().toStringUtf8();
+
+ Entity testEntity = new TestEntity(testName).toEntity();
+ List<Long> testCaseIds = new ArrayList<>();
+
+ Key testRunKey = KeyFactory.createKey(
+ testEntity.getKey(), TestRunEntity.KIND, report.getStartTimestamp());
+
+ long passCount = 0;
+ long failCount = 0;
+ long coveredLineCount = 0;
+ long totalLineCount = 0;
+
+ List<TestCaseRunEntity> testCases = new ArrayList<>();
+
+ // Process test cases
+ for (TestCaseReportMessage testCase : report.getTestCaseList()) {
+ String testCaseName = testCase.getName().toStringUtf8();
+ TestCaseResult result = testCase.getTestResult();
+ // Track global pass/fail counts
+ if (result == TestCaseResult.TEST_CASE_RESULT_PASS) {
+ ++passCount;
+ } else if (result != TestCaseResult.TEST_CASE_RESULT_SKIP) {
+ ++failCount;
+ }
+ String systraceLink = null;
+ if (testCase.getSystraceCount() > 0
+ && testCase.getSystraceList().get(0).getUrlCount() > 0) {
+ systraceLink = testCase.getSystraceList().get(0).getUrl(0).toStringUtf8();
+ }
+ // Process coverage data for test case
+ for (CoverageReportMessage coverage : testCase.getCoverageList()) {
+ CoverageEntity coverageEntity =
+ CoverageEntity.fromCoverageReport(testRunKey, testCaseName, coverage);
+ if (coverageEntity == null) {
+ logger.log(Level.WARNING, "Invalid coverage report in test run " + testRunKey);
+ continue;
+ }
+ coveredLineCount += coverageEntity.coveredLineCount;
+ totalLineCount += coverageEntity.totalLineCount;
+ puts.add(coverageEntity.toEntity());
+ }
+ // Process profiling data for test case
+ for (ProfilingReportMessage profiling : testCase.getProfilingList()) {
+ ProfilingPointRunEntity profilingEntity =
+ ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling);
+ if (profilingEntity == null) {
+ logger.log(Level.WARNING, "Invalid profiling report in test run " + testRunKey);
+ }
+ puts.add(profilingEntity.toEntity());
+ }
+
+ int lastIndex = testCases.size() - 1;
+ if (lastIndex < 0 || testCases.get(lastIndex).isFull()) {
+ KeyRange keys = datastore.allocateIds(TestCaseRunEntity.KIND, 1);
+ testCaseIds.add(keys.getStart().getId());
+ testCases.add(new TestCaseRunEntity(keys.getStart()));
+ ++lastIndex;
+ }
+ TestCaseRunEntity testCaseEntity = testCases.get(lastIndex);
+ testCaseEntity.addTestCase(testCaseName, result.getNumber());
+ testCaseEntity.setSystraceUrl(systraceLink);
+ }
+ List<Entity> testCasePuts = new ArrayList<>();
+ for (TestCaseRunEntity testCaseEntity : testCases) {
+ testCasePuts.add(testCaseEntity.toEntity());
+ }
+ datastore.put(testCasePuts);
+
+ // Process device information
+ TestRunType testRunType = null;
+ for (AndroidDeviceInfoMessage device : report.getDeviceInfoList()) {
+ DeviceInfoEntity deviceInfoEntity =
+ DeviceInfoEntity.fromDeviceInfoMessage(testRunKey, device);
+ if (deviceInfoEntity == null) {
+ logger.log(Level.WARNING, "Invalid device info in test run " + testRunKey);
+ }
+
+ // Run type on devices must be the same, else set to OTHER
+ TestRunType runType = TestRunType.fromBuildId(deviceInfoEntity.buildId);
+ if (testRunType == null) {
+ testRunType = runType;
+ } else if (runType != testRunType) {
+ testRunType = TestRunType.OTHER;
+ }
+ puts.add(deviceInfoEntity.toEntity());
+ }
+
+ // Overall run type should be determined by the device builds unless test build is OTHER
+ if (testRunType == null) {
+ testRunType = TestRunType.fromBuildId(testBuildId);
+ } else if (TestRunType.fromBuildId(testBuildId) == TestRunType.OTHER) {
+ testRunType = TestRunType.OTHER;
+ }
+
+ // Process global coverage data
+ for (CoverageReportMessage coverage : report.getCoverageList()) {
+ CoverageEntity coverageEntity =
+ CoverageEntity.fromCoverageReport(testRunKey, new String(), coverage);
+ if (coverageEntity == null) {
+ logger.log(Level.WARNING, "Invalid coverage report in test run " + testRunKey);
+ continue;
+ }
+ coveredLineCount += coverageEntity.coveredLineCount;
+ totalLineCount += coverageEntity.totalLineCount;
+ puts.add(coverageEntity.toEntity());
+ }
+
+ // Process global profiling data
+ for (ProfilingReportMessage profiling : report.getProfilingList()) {
+ ProfilingPointRunEntity profilingEntity =
+ ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling);
+ if (profilingEntity == null) {
+ logger.log(Level.WARNING, "Invalid profiling report in test run " + testRunKey);
+ }
+ puts.add(profilingEntity.toEntity());
+ }
+
+ List<String> logLinks = new ArrayList<>();
+ // Process log data
+ for (LogMessage log : report.getLogList()) {
+ if (!log.hasUrl())
+ continue;
+ logLinks.add(log.getUrl().toStringUtf8());
+ }
+
+ TestRunEntity testRunEntity = new TestRunEntity(testEntity.getKey(), testRunType,
+ startTimestamp, endTimestamp, testBuildId, hostName, passCount, failCount,
+ testCaseIds, logLinks, coveredLineCount, totalLineCount);
+ puts.add(testRunEntity.toEntity());
+
+ int retries = 0;
+ while (true) {
+ Transaction txn = datastore.beginTransaction();
+ try {
+ // Check if test already exists in the database
+ try {
+ datastore.get(testEntity.getKey());
+ } catch (EntityNotFoundException e) {
+ puts.add(testEntity);
+ }
+ datastore.put(puts);
+ txn.commit();
+ break;
+ } catch (ConcurrentModificationException | DatastoreFailureException
+ | DatastoreTimeoutException e) {
+ puts.remove(testEntity);
+ logger.log(Level.WARNING, "Retrying test run insert: " + testEntity.getKey());
+ if (retries++ >= MAX_WRITE_RETRIES) {
+ logger.log(Level.SEVERE,
+ "Exceeded maximum test run retries: " + testEntity.getKey());
+ throw e;
+ }
+ } finally {
+ if (txn.isActive()) {
+ logger.log(Level.WARNING,
+ "Transaction rollback forced for run: " + testRunEntity.key);
+ txn.rollback();
+ }
+ }
+ }
+ }
+
+ /**
+ * Upload data from a test plan report message
+ *
+ * @param report The test plan report containing data to upload.
+ */
+ public static void insertTestPlanReport(TestPlanReportMessage report) {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ List<Entity> puts = new ArrayList<>();
+
+ List<String> testModules = report.getTestModuleNameList();
+ List<Long> testTimes = report.getTestModuleStartTimestampList();
+ if (testModules.size() != testTimes.size() || !report.hasTestPlanName()) {
+ logger.log(Level.WARNING, "TestPlanReportMessage is missing information.");
+ return;
+ }
+
+ String testPlanName = report.getTestPlanName();
+ Entity testPlanEntity = new TestPlanEntity(testPlanName).toEntity();
+ List<Key> testRunKeys = new ArrayList<>();
+ for (int i = 0; i < testModules.size(); i++) {
+ String test = testModules.get(i);
+ long time = testTimes.get(i);
+ Key parentKey = KeyFactory.createKey(TestEntity.KIND, test);
+ Key testRunKey = KeyFactory.createKey(parentKey, TestRunEntity.KIND, time);
+ testRunKeys.add(testRunKey);
+ }
+ Map<Key, Entity> testRuns = datastore.get(testRunKeys);
+ long passCount = 0;
+ long failCount = 0;
+ long startTimestamp = -1;
+ long endTimestamp = -1;
+ String testBuildId = null;
+ TestRunType type = null;
+ Set<DeviceInfoEntity> devices = new HashSet<>();
+ for (Key testRunKey : testRuns.keySet()) {
+ TestRunEntity testRun = TestRunEntity.fromEntity(testRuns.get(testRunKey));
+ if (testRun == null) {
+ continue; // not a valid test run
+ }
+ passCount += testRun.passCount;
+ failCount += testRun.failCount;
+ if (startTimestamp < 0 || testRunKey.getId() < startTimestamp) {
+ startTimestamp = testRunKey.getId();
+ }
+ if (endTimestamp < 0 || testRun.endTimestamp > endTimestamp) {
+ endTimestamp = testRun.endTimestamp;
+ }
+ if (type == null) {
+ type = testRun.type;
+ } else if (type != testRun.type) {
+ type = TestRunType.OTHER;
+ }
+ testBuildId = testRun.testBuildId;
+ Query deviceInfoQuery = new Query(DeviceInfoEntity.KIND).setAncestor(testRunKey);
+ for (Entity deviceInfoEntity : datastore.prepare(deviceInfoQuery).asIterable()) {
+ DeviceInfoEntity device = DeviceInfoEntity.fromEntity(deviceInfoEntity);
+ if (device == null) {
+ continue; // invalid entity
+ }
+ devices.add(device);
+ }
+ }
+ if (startTimestamp < 0 || testBuildId == null || type == null) {
+ logger.log(Level.WARNING, "Couldn't infer test run information from runs.");
+ return;
+ }
+ TestPlanRunEntity testPlanRun = new TestPlanRunEntity(testPlanEntity.getKey(), testPlanName,
+ type, startTimestamp, endTimestamp, testBuildId, passCount, failCount, testRunKeys);
+
+ // Create the device infos.
+ for (DeviceInfoEntity device : devices) {
+ puts.add(device.copyWithParent(testPlanRun.key).toEntity());
+ }
+ puts.add(testPlanRun.toEntity());
+
+ int retries = 0;
+ while (true) {
+ Transaction txn = datastore.beginTransaction();
+ try {
+ // Check if test already exists in the database
+ try {
+ datastore.get(testPlanEntity.getKey());
+ } catch (EntityNotFoundException e) {
+ puts.add(testPlanEntity);
+ }
+ datastore.put(puts);
+ txn.commit();
+ break;
+ } catch (ConcurrentModificationException | DatastoreFailureException
+ | DatastoreTimeoutException e) {
+ puts.remove(testPlanEntity);
+ logger.log(Level.WARNING, "Retrying test plan insert: " + testPlanEntity.getKey());
+ if (retries++ >= MAX_WRITE_RETRIES) {
+ logger.log(Level.SEVERE,
+ "Exceeded maximum test plan retries: " + testPlanEntity.getKey());
+ throw e;
+ }
+ } finally {
+ if (txn.isActive()) {
+ logger.log(Level.WARNING,
+ "Transaction rollback forced for plan run: " + testPlanRun.key);
+ txn.rollback();
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/util/EmailHelper.java b/src/main/java/com/android/vts/util/EmailHelper.java
new file mode 100644
index 0000000..dd14d19
--- /dev/null
+++ b/src/main/java/com/android/vts/util/EmailHelper.java
@@ -0,0 +1,152 @@
+/**
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>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.vts.util;
+
+import com.android.vts.entity.UserFavoriteEntity;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.FilterOperator;
+import com.google.appengine.api.datastore.Query.FilterPredicate;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import org.apache.commons.lang.StringUtils;
+
+/** EmailHelper, a helper class for building and sending emails. */
+public class EmailHelper {
+ protected static final Logger logger = Logger.getLogger(EmailHelper.class.getName());
+ protected static final String DEFAULT_EMAIL = System.getProperty("DEFAULT_EMAIL");
+ protected static final String EMAIL_DOMAIN = System.getProperty("EMAIL_DOMAIN");
+ protected static final String SENDER_EMAIL = System.getProperty("SENDER_EMAIL");
+ private static final String VTS_EMAIL_NAME = "VTS Alert Bot";
+
+ /**
+ * Fetches the list of subscriber email addresses for a test.
+ *
+ * @param testKey The key for the test for which to fetch the email addresses.
+ * @returns List of email addresses (String).
+ * @throws IOException
+ */
+ public static List<String> getSubscriberEmails(Key testKey) throws IOException {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Filter testFilter =
+ new FilterPredicate(UserFavoriteEntity.TEST_KEY, FilterOperator.EQUAL, testKey);
+ Query favoritesQuery = new Query(UserFavoriteEntity.KIND).setFilter(testFilter);
+ Set<String> emailSet = new HashSet<>();
+ if (!StringUtils.isBlank(DEFAULT_EMAIL)) {
+ emailSet.add(DEFAULT_EMAIL);
+ }
+ for (Entity favorite : datastore.prepare(favoritesQuery).asIterable()) {
+ UserFavoriteEntity favoriteEntity = UserFavoriteEntity.fromEntity(favorite);
+ if (favoriteEntity != null && favoriteEntity.user != null
+ && favoriteEntity.user.getEmail().endsWith(EMAIL_DOMAIN)) {
+ emailSet.add(favoriteEntity.user.getEmail());
+ }
+ }
+ return new ArrayList<>(emailSet);
+ }
+
+ /**
+ * Sends an email to the specified email address to notify of a test status change.
+ *
+ * @param emails List of subscriber email addresses (byte[]) to which the email should be sent.
+ * @param subject The email subject field, string.
+ * @param body The html (string) body to send in the email.
+ * @returns The Message object to be sent.
+ * @throws MessagingException, UnsupportedEncodingException
+ */
+ public static Message composeEmail(List<String> emails, String subject, String body)
+ throws MessagingException, UnsupportedEncodingException {
+ if (emails.size() == 0) {
+ throw new MessagingException("No subscriber email addresses provided");
+ }
+ Properties props = new Properties();
+ Session session = Session.getDefaultInstance(props, null);
+
+ Message msg = new MimeMessage(session);
+ for (String email : emails) {
+ try {
+ msg.addRecipient(Message.RecipientType.TO, new InternetAddress(email, email));
+ } catch (MessagingException | UnsupportedEncodingException e) {
+ // Gracefully continue when a subscriber email is invalid.
+ logger.log(Level.WARNING, "Error sending email to recipient " + email + " : ", e);
+ }
+ }
+ msg.setFrom(new InternetAddress(SENDER_EMAIL, VTS_EMAIL_NAME));
+ msg.setSubject(subject);
+ msg.setContent(body, "text/html; charset=utf-8");
+ return msg;
+ }
+
+ /**
+ * Sends an email.
+ *
+ * @param msg Message object to send.
+ * @returns true if the message sends successfully, false otherwise
+ */
+ public static boolean send(Message msg) {
+ try {
+ Transport.send(msg);
+ } catch (MessagingException e) {
+ logger.log(Level.WARNING, "Error sending email : ", e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Sends a list of emails and logs any failures.
+ *
+ * @param messages List of Message objects to be sent.
+ */
+ public static void sendAll(List<Message> messages) {
+ for (Message msg : messages) {
+ send(msg);
+ }
+ }
+
+ /**
+ * Sends an email.
+ *
+ * @param recipients List of email address strings to which an email will be sent.
+ * @param subject The subject of the email.
+ * @param body The body of the email.
+ * @returns true if the message sends successfully, false otherwise
+ */
+ public static boolean send(List<String> recipients, String subject, String body) {
+ try {
+ Message msg = composeEmail(recipients, subject, body);
+ return send(msg);
+ } catch (MessagingException | UnsupportedEncodingException e) {
+ logger.log(Level.WARNING, "Error composing email : ", e);
+ return false;
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/util/FilterUtil.java b/src/main/java/com/android/vts/util/FilterUtil.java
new file mode 100644
index 0000000..5ca1bbb
--- /dev/null
+++ b/src/main/java/com/android/vts/util/FilterUtil.java
@@ -0,0 +1,321 @@
+/**
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>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.vts.util;
+
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.FilterOperator;
+import com.google.appengine.api.datastore.Query.FilterPredicate;
+import com.google.gson.Gson;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.http.HttpServletRequest;
+
+/** FilterUtil, a helper class for parsing and matching search queries to data. */
+public class FilterUtil {
+ protected static final Logger logger = Logger.getLogger(FilterUtil.class.getName());
+ /** Key class to represent a filter token. */
+ public enum FilterKey {
+ DEVICE_BUILD_ID("deviceBuildId", DeviceInfoEntity.BUILD_ID, true),
+ BRANCH("branch", DeviceInfoEntity.BRANCH, true),
+ TARGET("device", DeviceInfoEntity.BUILD_FLAVOR, true),
+ VTS_BUILD_ID("testBuildId", TestRunEntity.TEST_BUILD_ID, false),
+ HOSTNAME("hostname", TestRunEntity.HOST_NAME, false),
+ PASSING("passing", TestRunEntity.PASS_COUNT, false),
+ NONPASSING("nonpassing", TestRunEntity.FAIL_COUNT, false);
+
+ private static final Map<String, FilterKey> keyMap;
+
+ static {
+ keyMap = new HashMap<>();
+ for (FilterKey k : EnumSet.allOf(FilterKey.class)) {
+ keyMap.put(k.keyString, k);
+ }
+ }
+
+ /**
+ * Test if a string is a valid device key.
+ *
+ * @param keyString The key string.
+ * @return True if they key string matches a key and the key is a device filter.
+ */
+ public static boolean isDeviceKey(String keyString) {
+ return keyMap.containsKey(keyString) && keyMap.get(keyString).isDevice;
+ }
+
+ /**
+ * Test if a string is a valid test key.
+ *
+ * @param keyString The key string.
+ * @return True if they key string matches a key and the key is a test filter.
+ */
+ public static boolean isTestKey(String keyString) {
+ return keyMap.containsKey(keyString) && !keyMap.get(keyString).isDevice;
+ }
+
+ /**
+ * Parses a key string into a key.
+ *
+ * @param keyString The key string.
+ * @return The key matching the key string.
+ */
+ public static FilterKey parse(String keyString) {
+ return keyMap.get(keyString);
+ }
+
+ private final String keyString;
+ private final String property;
+ private final boolean isDevice;
+
+ /**
+ * Constructs a key with the specified key string.
+ *
+ * @param keyString The identifying key string.
+ * @param propertyName The name of the property to match.
+ */
+ private FilterKey(String keyString, String propertyName, boolean isDevice) {
+ this.keyString = keyString;
+ this.property = propertyName;
+ this.isDevice = isDevice;
+ }
+
+ public Filter getFilterForString(String matchString) {
+ return new FilterPredicate(this.property, FilterOperator.EQUAL, matchString);
+ }
+
+ public Filter getFilterForNumber(long matchNumber) {
+ return new FilterPredicate(this.property, FilterOperator.EQUAL, matchNumber);
+ }
+ }
+
+ /**
+ * Get a filter on devices from a user search query.
+ *
+ * @param parameterMap The key-value map of url parameters.
+ * @return A filter with the values from the user search parameters.
+ */
+ public static Filter getUserDeviceFilter(Map<String, Object> parameterMap) {
+ Filter deviceFilter = null;
+ for (String key : parameterMap.keySet()) {
+ if (!FilterKey.isDeviceKey(key))
+ continue;
+ String[] values = (String[]) parameterMap.get(key);
+ if (values.length == 0)
+ continue;
+ String value = values[0];
+ FilterKey filterKey = FilterKey.parse(key);
+ Filter f = filterKey.getFilterForString(value);
+ if (deviceFilter == null) {
+ deviceFilter = f;
+ } else {
+ deviceFilter = CompositeFilterOperator.and(deviceFilter, f);
+ }
+ }
+ return deviceFilter;
+ }
+
+ /**
+ * Get a filter on test runs from a user search query.
+ *
+ * @param parameterMap The key-value map of url parameters.
+ * @return A filter with the values from the user search parameters.
+ */
+ public static Filter getUserTestFilter(Map<String, Object> parameterMap) {
+ Filter testFilter = null;
+ for (String key : parameterMap.keySet()) {
+ if (!FilterKey.isTestKey(key))
+ continue;
+ String[] values = (String[]) parameterMap.get(key);
+ if (values.length == 0)
+ continue;
+ String stringValue = values[0];
+ FilterKey filterKey = FilterKey.parse(key);
+ Filter f = null;
+ switch (filterKey) {
+ case NONPASSING:
+ case PASSING:
+ try {
+ Long value = Long.parseLong(stringValue);
+ f = filterKey.getFilterForNumber(value);
+ } catch (NumberFormatException e) {
+ // invalid number
+ }
+ break;
+ case HOSTNAME:
+ case VTS_BUILD_ID:
+ f = filterKey.getFilterForString(stringValue.toLowerCase());
+ break;
+ default:
+ break;
+ }
+ if (testFilter == null) {
+ testFilter = f;
+ } else if (f != null) {
+ testFilter = CompositeFilterOperator.and(testFilter, f);
+ }
+ }
+ return testFilter;
+ }
+
+ /**
+ * Get a filter on the test run type.
+ *
+ * @param showPresubmit True to display presubmit tests.
+ * @param showPostsubmit True to display postsubmit tests.
+ * @param unfiltered True if no filtering should be applied.
+ * @return A filter on the test type.
+ */
+ public static Filter getTestTypeFilter(
+ boolean showPresubmit, boolean showPostsubmit, boolean unfiltered) {
+ if (unfiltered) {
+ return null;
+ } else if (showPresubmit && !showPostsubmit) {
+ return new FilterPredicate(TestRunEntity.TYPE, FilterOperator.EQUAL,
+ TestRunEntity.TestRunType.PRESUBMIT.getNumber());
+ } else if (showPostsubmit && !showPresubmit) {
+ return new FilterPredicate(TestRunEntity.TYPE, FilterOperator.EQUAL,
+ TestRunEntity.TestRunType.POSTSUBMIT.getNumber());
+ } else {
+ List<Integer> types = new ArrayList<>();
+ types.add(TestRunEntity.TestRunType.PRESUBMIT.getNumber());
+ types.add(TestRunEntity.TestRunType.POSTSUBMIT.getNumber());
+ return new FilterPredicate(TestRunEntity.TYPE, FilterOperator.IN, types);
+ }
+ }
+
+ /**
+ * Get the time range filter to apply to a query.
+ *
+ * @param testKey The key of the parent TestEntity object.
+ * @param kind The kind to use for the filters.
+ * @param startTime The start time in microseconds, or null if unbounded.
+ * @param endTime The end time in microseconds, or null if unbounded.
+ * @param testRunFilter The existing filter on test runs to apply, or null.
+ * @return A filter to apply on test runs.
+ */
+ public static Filter getTimeFilter(
+ Key testKey, String kind, Long startTime, Long endTime, Filter testRunFilter) {
+ if (startTime == null && endTime == null) {
+ endTime = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
+ }
+
+ Filter startFilter = null;
+ Filter endFilter = null;
+ Filter filter = null;
+ if (startTime != null) {
+ Key startKey = KeyFactory.createKey(testKey, kind, startTime);
+ startFilter = new FilterPredicate(
+ Entity.KEY_RESERVED_PROPERTY, FilterOperator.GREATER_THAN_OR_EQUAL, startKey);
+ filter = startFilter;
+ }
+ if (endTime != null) {
+ Key endKey = KeyFactory.createKey(testKey, kind, endTime);
+ endFilter = new FilterPredicate(
+ Entity.KEY_RESERVED_PROPERTY, FilterOperator.LESS_THAN_OR_EQUAL, endKey);
+ filter = endFilter;
+ }
+ if (startFilter != null && endFilter != null) {
+ filter = CompositeFilterOperator.and(startFilter, endFilter);
+ }
+ if (testRunFilter != null) {
+ filter = CompositeFilterOperator.and(filter, testRunFilter);
+ }
+ return filter;
+ }
+
+ public static Filter getTimeFilter(Key testKey, String kind, Long startTime, Long endTime) {
+ return getTimeFilter(testKey, kind, startTime, endTime, null);
+ }
+
+ /**
+ * Get the list of keys matching the provided test filter and device filter.
+ *
+ * @param ancestorKey The ancestor key to use in the query.
+ * @param kind The entity kind to use in the test query.
+ * @param testFilter The filter to apply to the test runs.
+ * @param deviceFilter The filter to apply to associated devices.
+ * @param dir The sort direction of the returned list.
+ * @param maxSize The maximum number of entities to return.
+ * @return a list of keys matching the provided test and device filters.
+ */
+ public static List<Key> getMatchingKeys(Key ancestorKey, String kind, Filter testFilter,
+ Filter deviceFilter, Query.SortDirection dir, int maxSize) {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Set<Key> matchingTestKeys = new HashSet<>();
+ Query testQuery =
+ new Query(kind).setAncestor(ancestorKey).setFilter(testFilter).setKeysOnly();
+ for (Entity testRunKey : datastore.prepare(testQuery).asIterable()) {
+ matchingTestKeys.add(testRunKey.getKey());
+ }
+
+ Set<Key> allMatchingKeys;
+ if (deviceFilter == null) {
+ allMatchingKeys = matchingTestKeys;
+ } else {
+ allMatchingKeys = new HashSet<>();
+ Query deviceQuery = new Query(DeviceInfoEntity.KIND)
+ .setAncestor(ancestorKey)
+ .setFilter(deviceFilter)
+ .setKeysOnly();
+ for (Entity device : datastore.prepare(deviceQuery).asIterable()) {
+ if (matchingTestKeys.contains(device.getKey().getParent())) {
+ allMatchingKeys.add(device.getKey().getParent());
+ }
+ }
+ }
+ List<Key> gets = new ArrayList<>(allMatchingKeys);
+ if (dir == Query.SortDirection.DESCENDING) {
+ Collections.sort(gets, Collections.reverseOrder());
+ } else {
+ Collections.sort(gets);
+ }
+ gets = gets.subList(0, Math.min(gets.size(), maxSize));
+ return gets;
+ }
+
+ /**
+ * Set the request with the provided key/value attribute map.
+ * @param request The request whose attributes to set.
+ * @param parameterMap The map from key to (Object) String[] value whose entries to parse.
+ */
+ public static void setAttributes(HttpServletRequest request, Map<String, Object> parameterMap) {
+ for (String key : parameterMap.keySet()) {
+ if (!FilterKey.isDeviceKey(key) && !FilterKey.isTestKey(key))
+ continue;
+ FilterKey filterKey = FilterKey.parse(key);
+ String[] values = (String[]) parameterMap.get(key);
+ if (values.length == 0)
+ continue;
+ String stringValue = values[0];
+ request.setAttribute(filterKey.keyString, new Gson().toJson(stringValue));
+ }
+ }
+}
diff --git a/src/main/java/com/android/vts/util/Graph.java b/src/main/java/com/android/vts/util/Graph.java
new file mode 100644
index 0000000..2fe98bb
--- /dev/null
+++ b/src/main/java/com/android/vts/util/Graph.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+
+/** Helper object for describing graph data. */
+public abstract class Graph {
+ public static final String VALUE_KEY = "values";
+ public static final String X_LABEL_KEY = "x_label";
+ public static final String Y_LABEL_KEY = "y_label";
+ public static final String IDS_KEY = "ids";
+ public static final String NAME_KEY = "name";
+ public static final String TYPE_KEY = "type";
+
+ public static enum GraphType { LINE_GRAPH, HISTOGRAM }
+
+ /**
+ * Get the graph type.
+ *
+ * @return The graph type.
+ */
+ public abstract GraphType getType();
+
+ /**
+ * Get the x axis label.
+ *
+ * @return The x axis label.
+ */
+ public abstract String getXLabel();
+
+ /**
+ * Get the y axis label.
+ *
+ * @return The y axis label.
+ */
+ public abstract String getYLabel();
+
+ /**
+ * Get the name of the graph.
+ *
+ * @return The name of the graph.
+ */
+ public abstract String getName();
+
+ /**
+ * Get the number of data points stored in the graph.
+ *
+ * @return The number of data points stored in the graph.
+ */
+ public abstract int size();
+
+ /**
+ * Add data to the graph.
+ *
+ * @param id The name of the graph.
+ * @param profilingPoint The ProfilingPointEntity containing data to add.
+ */
+ public abstract void addData(String id, ProfilingPointRunEntity profilingPoint);
+
+ /**
+ * Serializes the graph to json format.
+ *
+ * @return A JsonElement object representing the graph object.
+ */
+ public JsonObject toJson() {
+ JsonObject json = new JsonObject();
+ json.add(X_LABEL_KEY, new JsonPrimitive(getXLabel()));
+ json.add(Y_LABEL_KEY, new JsonPrimitive(getYLabel()));
+ json.add(NAME_KEY, new JsonPrimitive(getName()));
+ json.add(TYPE_KEY, new JsonPrimitive(getType().toString()));
+ return json;
+ }
+}
diff --git a/src/main/java/com/android/vts/util/GraphSerializer.java b/src/main/java/com/android/vts/util/GraphSerializer.java
new file mode 100644
index 0000000..722b511
--- /dev/null
+++ b/src/main/java/com/android/vts/util/GraphSerializer.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.Type;
+
+/** Serializer class for Graph objects. */
+public class GraphSerializer implements JsonSerializer<Graph> {
+ @Override
+ public JsonElement serialize(Graph src, Type typeOfSrc, JsonSerializationContext context) {
+ return src.toJson();
+ }
+}
diff --git a/src/main/java/com/android/vts/util/Histogram.java b/src/main/java/com/android/vts/util/Histogram.java
new file mode 100644
index 0000000..450714b
--- /dev/null
+++ b/src/main/java/com/android/vts/util/Histogram.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.google.common.primitives.Doubles;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.math3.stat.descriptive.rank.Percentile;
+
+/** Helper object for describing graph data. */
+public class Histogram extends Graph {
+ public static final String PERCENTILES_KEY = "percentiles";
+ public static final String PERCENTILE_VALUES_KEY = "percentile_values";
+ public static final String MIN_KEY = "min";
+ public static final String MAX_KEY = "max";
+
+ private List<Double> values;
+ private List<String> ids;
+ private String xLabel;
+ private String yLabel;
+ private String name;
+ private GraphType type = GraphType.HISTOGRAM;
+ private Double min = null;
+ private Double max = null;
+
+ public Histogram(String name) {
+ this.name = name;
+ this.values = new ArrayList<>();
+ this.ids = new ArrayList<>();
+ }
+
+ /**
+ * Get the x axis label.
+ *
+ * @return The x axis label.
+ */
+ @Override
+ public String getXLabel() {
+ return xLabel;
+ }
+
+ /**
+ * Get the graph type.
+ *
+ * @return The graph type.
+ */
+ @Override
+ public GraphType getType() {
+ return type;
+ }
+
+ /**
+ * Get the name of the graph.
+ *
+ * @return The name of the graph.
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Get the y axis label.
+ *
+ * @return The y axis label.
+ */
+ @Override
+ public String getYLabel() {
+ return yLabel;
+ }
+
+ /**
+ * Get the number of data points stored in the graph.
+ *
+ * @return The number of data points stored in the graph.
+ */
+ @Override
+ public int size() {
+ return values.size();
+ }
+
+ /**
+ * Get the minimum value.
+ *
+ * @return The minimum value.
+ */
+ public Double getMin() {
+ return min;
+ }
+
+ /**
+ * Get the maximum value.
+ *
+ * @return The maximum value.
+ */
+ public Double getMax() {
+ return max;
+ }
+
+ /**
+ * Add data to the graph.
+ *
+ * @param id The name of the graph.
+ * @param profilingPoint The ProfilingPointRunEntity containing data to add.
+ */
+ @Override
+ public void addData(String id, ProfilingPointRunEntity profilingPoint) {
+ if (profilingPoint.values.size() == 0)
+ return;
+ xLabel = profilingPoint.xLabel;
+ yLabel = profilingPoint.yLabel;
+ for (long v : profilingPoint.values) {
+ double value = v;
+ values.add(value);
+ ids.add(id);
+ if (max == null || value > max)
+ max = value;
+ if (min == null || value < min)
+ min = value;
+ }
+ }
+
+ /**
+ * Serializes the graph to json format.
+ *
+ * @return A JsonElement object representing the graph object.
+ */
+ @Override
+ public JsonObject toJson() {
+ int[] percentiles = {1, 2, 5, 10, 25, 50, 75, 90, 95, 98, 99};
+ double[] percentileValues = new double[percentiles.length];
+ double[] valueList = Doubles.toArray(values);
+ for (int i = 0; i < percentiles.length; i++) {
+ percentileValues[i] =
+ Math.round(new Percentile().evaluate(valueList, percentiles[i]) * 1000d)
+ / 1000d;
+ }
+ JsonObject json = super.toJson();
+ json.add(VALUE_KEY, new Gson().toJsonTree(values).getAsJsonArray());
+ json.add(PERCENTILES_KEY, new Gson().toJsonTree(percentiles).getAsJsonArray());
+ json.add(PERCENTILE_VALUES_KEY, new Gson().toJsonTree(percentileValues).getAsJsonArray());
+ json.add(IDS_KEY, new Gson().toJsonTree(ids).getAsJsonArray());
+ json.add(MIN_KEY, new JsonPrimitive(min));
+ json.add(MAX_KEY, new JsonPrimitive(max));
+ return json;
+ }
+}
diff --git a/src/main/java/com/android/vts/util/LineGraph.java b/src/main/java/com/android/vts/util/LineGraph.java
new file mode 100644
index 0000000..22c64da
--- /dev/null
+++ b/src/main/java/com/android/vts/util/LineGraph.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Helper object for describing graph data. */
+public class LineGraph extends Graph {
+ public static final String TICKS_KEY = "ticks";
+
+ private List<ProfilingPointRunEntity> profilingRuns;
+ private List<String> ids;
+ private String xLabel;
+ private String yLabel;
+ private String name;
+ private GraphType type = GraphType.LINE_GRAPH;
+
+ public LineGraph(String name) {
+ this.name = name;
+ profilingRuns = new ArrayList<>();
+ ids = new ArrayList<>();
+ }
+
+ /**
+ * Get the x axis label.
+ *
+ * @return The x axis label.
+ */
+ @Override
+ public String getXLabel() {
+ return xLabel;
+ }
+
+ /**
+ * Get the graph type.
+ *
+ * @return The graph type.
+ */
+ @Override
+ public GraphType getType() {
+ return type;
+ }
+
+ /**
+ * Get the name of the graph.
+ *
+ * @return The name of the graph.
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Get the y axis label.
+ *
+ * @return The y axis label.
+ */
+ @Override
+ public String getYLabel() {
+ return yLabel;
+ }
+
+ /**
+ * Get the number of data points stored in the graph.
+ *
+ * @return The number of data points stored in the graph.
+ */
+ @Override
+ public int size() {
+ return profilingRuns.size();
+ }
+
+ /**
+ * Add data to the graph.
+ *
+ * @param id The name of the graph.
+ * @param profilingPoint The ProfilingPointRunEntity containing data to add.
+ */
+ @Override
+ public void addData(String id, ProfilingPointRunEntity profilingPoint) {
+ if (profilingPoint.values.size() == 0
+ || profilingPoint.values.size() != profilingPoint.labels.size())
+ return;
+ ids.add(id);
+ profilingRuns.add(profilingPoint);
+ xLabel = profilingPoint.xLabel;
+ yLabel = profilingPoint.yLabel;
+ }
+
+ /**
+ * Serializes the graph to json format.
+ *
+ * @return A JsonElement object representing the graph object.
+ */
+ @Override
+ public JsonObject toJson() {
+ JsonObject json = super.toJson();
+ // Use the most recent profiling vector to generate the labels
+ ProfilingPointRunEntity profilingRun = profilingRuns.get(profilingRuns.size() - 1);
+
+ List<String> axisTicks = new ArrayList<>();
+ Map<String, Integer> tickIndexMap = new HashMap<>();
+ for (int i = 0; i < profilingRun.labels.size(); i++) {
+ String label = profilingRun.labels.get(i);
+ axisTicks.add(label);
+ tickIndexMap.put(label, i);
+ }
+
+ long[][] lineGraphValues = new long[axisTicks.size()][profilingRuns.size()];
+ for (int reportIndex = 0; reportIndex < profilingRuns.size(); reportIndex++) {
+ ProfilingPointRunEntity pt = profilingRuns.get(reportIndex);
+ for (int i = 0; i < pt.labels.size(); i++) {
+ String label = pt.labels.get(i);
+
+ // Skip value if its label is not present
+ if (!tickIndexMap.containsKey(label))
+ continue;
+ int labelIndex = tickIndexMap.get(label);
+
+ lineGraphValues[labelIndex][reportIndex] = pt.values.get(i);
+ }
+ }
+ json.add(VALUE_KEY, new Gson().toJsonTree(lineGraphValues).getAsJsonArray());
+ json.add(IDS_KEY, new Gson().toJsonTree(ids).getAsJsonArray());
+ json.add(TICKS_KEY, new Gson().toJsonTree(axisTicks));
+ return json;
+ }
+}
diff --git a/src/main/java/com/android/vts/util/PerformanceSummary.java b/src/main/java/com/android/vts/util/PerformanceSummary.java
new file mode 100644
index 0000000..05ed0b7
--- /dev/null
+++ b/src/main/java/com/android/vts/util/PerformanceSummary.java
@@ -0,0 +1,143 @@
+/**
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>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.vts.util;
+
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
+import com.google.appengine.api.datastore.Entity;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** PerformanceSummary, an object summarizing performance across profiling points for a test run. */
+public class PerformanceSummary {
+ protected static Logger logger = Logger.getLogger(PerformanceSummary.class.getName());
+ private Map<String, ProfilingPointSummary> summaryMap;
+ private Set<String> optionSplitKeys;
+
+ /** Creates a performance summary object. */
+ public PerformanceSummary() {
+ this.summaryMap = new HashMap<>();
+ this.optionSplitKeys = new HashSet<>();
+ }
+
+ /**
+ * Creates a performance summary object with the specified device name filter. If the specified
+ * name is null, then use no filter.
+ *
+ * @param optionSplitKeys A set of option keys to split on (i.e. profiling data with different
+ * values corresponding to the option key will be analyzed as different profiling points).
+ */
+ public PerformanceSummary(Set<String> optionSplitKeys) {
+ this();
+ this.optionSplitKeys = optionSplitKeys;
+ }
+
+ /**
+ * Add the profiling data from a ProfilingPointRunEntity to the performance summary.
+ *
+ * @param profilingRun The Entity object whose data to add.
+ */
+ public void addData(Entity profilingRun) {
+ ProfilingPointRunEntity pt = ProfilingPointRunEntity.fromEntity(profilingRun);
+ if (pt == null)
+ return;
+ if (pt.regressionMode == VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DISABLED) {
+ return;
+ }
+
+ String name = pt.name;
+ String optionSuffix = PerformanceUtil.getOptionAlias(pt, optionSplitKeys);
+
+ if (pt.labels != null) {
+ if (pt.labels.size() != pt.values.size()) {
+ logger.log(Level.WARNING, "Labels and values are different sizes.");
+ return;
+ }
+ if (!optionSuffix.equals("")) {
+ name += " (" + optionSuffix + ")";
+ }
+ if (!summaryMap.containsKey(name)) {
+ summaryMap.put(name, new ProfilingPointSummary());
+ }
+ summaryMap.get(name).update(pt);
+ } else {
+ // Use the option suffix as the table name.
+ // Group all profiling points together into one table
+ if (!summaryMap.containsKey(optionSuffix)) {
+ summaryMap.put(optionSuffix, new ProfilingPointSummary());
+ }
+ summaryMap.get(optionSuffix).updateLabel(pt, pt.name);
+ }
+ }
+
+ /**
+ * Adds a ProfilingPointSummary object into the summary map only if the key doesn't exist.
+ *
+ * @param key The name of the profiling point.
+ * @param summary The ProfilingPointSummary object to add into the summary map.
+ * @return True if the data was inserted into the performance summary, false otherwise.
+ */
+ public boolean insertProfilingPointSummary(String key, ProfilingPointSummary summary) {
+ if (!summaryMap.containsKey(key)) {
+ summaryMap.put(key, summary);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Gets the number of profiling points.
+ *
+ * @return The number of profiling points in the performance summary.
+ */
+ public int size() {
+ return summaryMap.size();
+ }
+
+ /**
+ * Gets the names of the profiling points.
+ *
+ * @return A string array of profiling point names.
+ */
+ public String[] getProfilingPointNames() {
+ String[] profilingNames = summaryMap.keySet().toArray(new String[summaryMap.size()]);
+ Arrays.sort(profilingNames);
+ return profilingNames;
+ }
+
+ /**
+ * Determines if a profiling point is described by the performance summary.
+ *
+ * @param profilingPointName The name of the profiling point.
+ * @return True if the profiling point is contained in the performance summary, else false.
+ */
+ public boolean hasProfilingPoint(String profilingPointName) {
+ return summaryMap.containsKey(profilingPointName);
+ }
+
+ /**
+ * Gets the profiling point summary by name.
+ *
+ * @param profilingPointName The name of the profiling point to fetch.
+ * @return The ProfilingPointSummary object describing the specified profiling point.
+ */
+ public ProfilingPointSummary getProfilingPointSummary(String profilingPointName) {
+ return summaryMap.get(profilingPointName);
+ }
+}
diff --git a/src/main/java/com/android/vts/util/PerformanceUtil.java b/src/main/java/com/android/vts/util/PerformanceUtil.java
new file mode 100644
index 0000000..02c2afa
--- /dev/null
+++ b/src/main/java/com/android/vts/util/PerformanceUtil.java
@@ -0,0 +1,246 @@
+/**
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>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.vts.util;
+
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.entity.TestEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.datastore.Query.Filter;
+import com.google.appengine.api.datastore.Query.FilterOperator;
+import com.google.appengine.api.datastore.Query.FilterPredicate;
+import java.io.IOException;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+import org.apache.commons.lang.StringUtils;
+
+/** PerformanceUtil, a helper class for analyzing profiling and performance data. */
+public class PerformanceUtil {
+ protected static Logger logger = Logger.getLogger(PerformanceUtil.class.getName());
+
+ private static final DecimalFormat FORMATTER;
+ private static final String NAME_DELIMITER = ", ";
+ private static final String OPTION_DELIMITER = "=";
+
+ /**
+ * Initialize the decimal formatter.
+ */
+ static {
+ FORMATTER = new DecimalFormat("#.##");
+ FORMATTER.setRoundingMode(RoundingMode.HALF_UP);
+ }
+
+ public static class TimeInterval {
+ public final long start;
+ public final long end;
+ public final String label;
+
+ public TimeInterval(long start, long end, String label) {
+ this.start = start;
+ this.end = end;
+ this.label = label;
+ }
+
+ public TimeInterval(long start, long end) {
+ this(start, end, "<span class='date-label'>"
+ + Long.toString(TimeUnit.MICROSECONDS.toMillis(end)) + "</span>");
+ }
+ }
+
+ /**
+ * Creates the HTML for a table cell representing the percent change between two numbers.
+ *
+ * <p>Computes the percent change (after - before)/before * 100 and inserts it into a table cell
+ * with the specified style. The color of the cell is white if 'after' is less than before.
+ * Otherwise, the cell is colored red with opacity according to the percent change (100%+ delta
+ * means 100% opacity). If the before value is 0 and the after value is positive, then the color
+ * of the cell is 100% red to indicate an increase of undefined magnitude.
+ *
+ * @param baseline The baseline value observed.
+ * @param test The value to compare against the baseline.
+ * @param classNames A string containing HTML classes to apply to the table cell.
+ * @param style A string containing additional CSS styles.
+ * @returns An HTML string for a colored table cell containing the percent change.
+ */
+ public static String getPercentChangeHTML(double baseline, double test, String classNames,
+ String style, VtsProfilingRegressionMode mode) {
+ String pctChangeString = "0 %";
+ double alpha = 0;
+ double delta = test - baseline;
+ if (baseline != 0) {
+ double pctChange = delta / baseline;
+ alpha = pctChange * 2;
+ pctChangeString = FORMATTER.format(pctChange * 100) + " %";
+ } else if (delta != 0) {
+ // If the percent change is undefined, the cell will be solid red or white
+ alpha = (int) Math.signum(delta); // get the sign of the delta (+1, 0, -1)
+ pctChangeString = "";
+ }
+ if (mode == VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DECREASING) {
+ alpha = -alpha;
+ }
+ String color = "background-color: rgba(255, 0, 0, " + alpha + "); ";
+ String html = "<td class='" + classNames + "' style='" + color + style + "'>";
+ html += pctChangeString + "</td>";
+ return html;
+ }
+
+ /**
+ * Compares a test StatSummary to a baseline StatSummary using best-case performance.
+ *
+ * @param baseline The StatSummary object containing initial values to compare against
+ * @param test The StatSummary object containing test values to be compared against the baseline
+ * @param innerClasses Class names to apply to cells on the inside of the grid
+ * @param outerClasses Class names to apply to cells on the outside of the grid
+ * @param innerStyles CSS styles to apply to cells on the inside of the grid
+ * @param outerStyles CSS styles to apply to cells on the outside of the grid
+ * @return HTML string representing the performance of the test versus the baseline
+ */
+ public static String getBestCasePerformanceComparisonHTML(StatSummary baseline,
+ StatSummary test, String innerClasses, String outerClasses, String innerStyles,
+ String outerStyles) {
+ if (test == null || baseline == null) {
+ return "<td></td><td></td><td></td><td></td>";
+ }
+ String row = "";
+ // Intensity of red color is a function of the relative (percent) change
+ // in the new value compared to the previous day's. Intensity is a linear function
+ // of percentage change, reaching a ceiling at 100% change (e.g. a doubling).
+ row += getPercentChangeHTML(baseline.getBestCase(), test.getBestCase(), innerClasses,
+ innerStyles, test.getRegressionMode());
+ row += "<td class='" + innerClasses + "' style='" + innerStyles + "'>";
+ row += FORMATTER.format(baseline.getBestCase());
+ row += "<td class='" + innerClasses + "' style='" + innerStyles + "'>";
+ row += FORMATTER.format(baseline.getMean());
+ row += "<td class='" + outerClasses + "' style='" + outerStyles + "'>";
+ row += FORMATTER.format(baseline.getStd()) + "</td>";
+ return row;
+ }
+
+ /**
+ * Compares a test StatSummary to a baseline StatSummary using average-case performance.
+ *
+ * @param baseline The StatSummary object containing initial values to compare against
+ * @param test The StatSummary object containing test values to be compared against the baseline
+ * @param innerClasses Class names to apply to cells on the inside of the grid
+ * @param outerClasses Class names to apply to cells on the outside of the grid
+ * @param innerStyles CSS styles to apply to cells on the inside of the grid
+ * @param outerStyles CSS styles to apply to cells on the outside of the grid
+ * @return HTML string representing the performance of the test versus the baseline
+ */
+ public static String getAvgCasePerformanceComparisonHTML(StatSummary baseline, StatSummary test,
+ String innerClasses, String outerClasses, String innerStyles, String outerStyles) {
+ if (test == null || baseline == null) {
+ return "<td></td><td></td><td></td><td></td>";
+ }
+ String row = "";
+ // Intensity of red color is a function of the relative (percent) change
+ // in the new value compared to the previous day's. Intensity is a linear function
+ // of percentage change, reaching a ceiling at 100% change (e.g. a doubling).
+ row += getPercentChangeHTML(baseline.getMean(), test.getMean(), innerClasses, innerStyles,
+ test.getRegressionMode());
+ row += "<td class='" + innerClasses + "' style='" + innerStyles + "'>";
+ row += FORMATTER.format(baseline.getBestCase());
+ row += "<td class='" + innerClasses + "' style='" + innerStyles + "'>";
+ row += FORMATTER.format(baseline.getMean());
+ row += "<td class='" + outerClasses + "' style='" + outerStyles + "'>";
+ row += FORMATTER.format(baseline.getStd()) + "</td>";
+ return row;
+ }
+
+ /**
+ * Updates a PerformanceSummary object with data in the specified window.
+ *
+ * @param testName The name of the table whose profiling vectors to retrieve.
+ * @param startTime The (inclusive) start time in microseconds to scan from.
+ * @param endTime The (inclusive) end time in microseconds at which to stop scanning.
+ * @param selectedDevice The name of the device whose data to query for, or null for unfiltered.
+ * @param perfSummary The PerformanceSummary object to update with data.
+ * @throws IOException
+ */
+ public static void updatePerformanceSummary(String testName, long startTime, long endTime,
+ String selectedDevice, PerformanceSummary perfSummary) throws IOException {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Key testKey = KeyFactory.createKey(TestEntity.KIND, testName);
+ Filter testTypeFilter = FilterUtil.getTestTypeFilter(false, true, false);
+ Filter runFilter = FilterUtil.getTimeFilter(
+ testKey, TestRunEntity.KIND, startTime, endTime, testTypeFilter);
+
+ Filter deviceFilter = null;
+ if (selectedDevice != null) {
+ deviceFilter = new FilterPredicate(
+ DeviceInfoEntity.PRODUCT, FilterOperator.EQUAL, selectedDevice);
+ }
+ Query testRunQuery = new Query(TestRunEntity.KIND)
+ .setAncestor(testKey)
+ .setFilter(runFilter)
+ .setKeysOnly();
+ for (Entity testRun : datastore.prepare(testRunQuery).asIterable()) {
+ if (deviceFilter != null) {
+ Query deviceQuery = new Query(DeviceInfoEntity.KIND)
+ .setAncestor(testRun.getKey())
+ .setFilter(deviceFilter)
+ .setKeysOnly();
+ if (!DatastoreHelper.hasEntities(deviceQuery))
+ continue;
+ }
+ Query q = new Query(ProfilingPointRunEntity.KIND).setAncestor(testRun.getKey());
+
+ for (Entity profilingRun : datastore.prepare(q).asIterable()) {
+ perfSummary.addData(profilingRun);
+ }
+ }
+ }
+
+ /**
+ * Generates a string of the values in optionsList which have matches in the profiling entity.
+ *
+ * @param profilingRun The entity for a profiling point run.
+ * @param optionKeys A list of keys to match against the optionsList key value pairs.
+ * @return The values in optionsList whose key match a key in optionKeys.
+ */
+ public static String getOptionAlias(
+ ProfilingPointRunEntity profilingRun, Set<String> optionKeys) {
+ String name = "";
+ List<String> nameSuffixes = new ArrayList<>();
+ if (profilingRun.options != null) {
+ for (String optionString : profilingRun.options) {
+ String[] optionParts = optionString.split(OPTION_DELIMITER);
+ if (optionParts.length != 2) {
+ continue;
+ }
+ if (optionKeys.contains(optionParts[0].trim().toLowerCase())) {
+ nameSuffixes.add(optionParts[1].trim().toLowerCase());
+ }
+ }
+ if (nameSuffixes.size() > 0) {
+ StringUtils.join(nameSuffixes, NAME_DELIMITER);
+ name += StringUtils.join(nameSuffixes, NAME_DELIMITER);
+ }
+ }
+ return name;
+ }
+}
diff --git a/src/main/java/com/android/vts/util/ProfilingPointSummary.java b/src/main/java/com/android/vts/util/ProfilingPointSummary.java
new file mode 100644
index 0000000..6e3e8c9
--- /dev/null
+++ b/src/main/java/com/android/vts/util/ProfilingPointSummary.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/** Represents statistical summaries of each profiling point. */
+public class ProfilingPointSummary implements Iterable<StatSummary> {
+ private List<StatSummary> statSummaries;
+ private Map<String, Integer> labelIndices;
+ private List<String> labels;
+ private VtsProfilingRegressionMode regressionMode;
+ public String xLabel;
+ public String yLabel;
+
+ /** Initializes the summary with empty arrays. */
+ public ProfilingPointSummary() {
+ statSummaries = new ArrayList<>();
+ labelIndices = new HashMap<>();
+ labels = new ArrayList<>();
+ }
+
+ /**
+ * Determines if a data label is present in the profiling point.
+ *
+ * @param label The name of the label.
+ * @return true if the label is present, false otherwise.
+ */
+ public boolean hasLabel(String label) {
+ return labelIndices.containsKey(label);
+ }
+
+ /**
+ * Gets the statistical summary for a specified data label.
+ *
+ * @param label The name of the label.
+ * @return The StatSummary object if it exists, or null otherwise.
+ */
+ public StatSummary getStatSummary(String label) {
+ if (!hasLabel(label))
+ return null;
+ return statSummaries.get(labelIndices.get(label));
+ }
+
+ /**
+ * Gets the last-seen regression mode.
+ *
+ * @return The VtsProfilingRegressionMode value.
+ */
+ public VtsProfilingRegressionMode getRegressionMode() {
+ return regressionMode;
+ }
+
+ /**
+ * Updates the profiling summary with the data from a new profiling report.
+ *
+ * @param profilingRun The profiling point run entity object containing profiling data.
+ */
+ public void update(ProfilingPointRunEntity profilingRun) {
+ for (int i = 0; i < profilingRun.labels.size(); i++) {
+ String label = profilingRun.labels.get(i);
+ if (!labelIndices.containsKey(label)) {
+ StatSummary summary = new StatSummary(label, profilingRun.regressionMode);
+ labelIndices.put(label, statSummaries.size());
+ statSummaries.add(summary);
+ }
+ StatSummary summary = getStatSummary(label);
+ summary.updateStats(profilingRun.values.get(i));
+ }
+ this.regressionMode = profilingRun.regressionMode;
+ this.labels = profilingRun.labels;
+ this.xLabel = profilingRun.xLabel;
+ this.yLabel = profilingRun.yLabel;
+ }
+
+ /**
+ * Updates the profiling summary at a label with the data from a new profiling report.
+ *
+ * <p>Updates the summary specified by the label with all values provided in the report. If
+ * labels
+ * are provided in the report, they will be ignored -- all values are updated only to the
+ * provided
+ * label.
+ *
+ * @param profilingEntity The ProfilingPointRunEntity object containing profiling data.
+ * @param label The ByteString label for which all values in the report will be updated.
+ */
+ public void updateLabel(ProfilingPointRunEntity profilingEntity, String label) {
+ if (!labelIndices.containsKey(label)) {
+ StatSummary summary = new StatSummary(label, profilingEntity.regressionMode);
+ labelIndices.put(label, labels.size());
+ labels.add(label);
+ statSummaries.add(summary);
+ }
+ StatSummary summary = getStatSummary(label);
+ for (long value : profilingEntity.values) {
+ summary.updateStats(value);
+ }
+ this.regressionMode = profilingEntity.regressionMode;
+ this.xLabel = profilingEntity.xLabel;
+ this.yLabel = profilingEntity.yLabel;
+ }
+
+ /**
+ * Gets an iterator that returns stat summaries in the ordered the labels were specified in the
+ * ProfilingReportMessage objects.
+ */
+ @Override
+ public Iterator<StatSummary> iterator() {
+ Iterator<StatSummary> it = new Iterator<StatSummary>() {
+ private int currentIndex = 0;
+
+ @Override
+ public boolean hasNext() {
+ return labels != null && currentIndex < labels.size();
+ }
+
+ @Override
+ public StatSummary next() {
+ String label = labels.get(currentIndex++);
+ return statSummaries.get(labelIndices.get(label));
+ }
+ };
+ return it;
+ }
+}
diff --git a/src/main/java/com/android/vts/util/StatSummary.java b/src/main/java/com/android/vts/util/StatSummary.java
new file mode 100644
index 0000000..04db7c4
--- /dev/null
+++ b/src/main/java/com/android/vts/util/StatSummary.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
+
+/** Helper object for storing statistics. */
+public class StatSummary {
+ private String label;
+ private double min;
+ private double max;
+ private double mean;
+ private double var;
+ private int n;
+ private VtsProfilingRegressionMode regression_mode;
+
+ /**
+ * Initializes the statistical summary.
+ *
+ * <p>Sets the label as provided. Initializes the mean, variance, and n (number of values seen)
+ * to
+ * 0.
+ *
+ * @param label The (String) label to assign to the summary.
+ * @param mode The VtsProfilingRegressionMode to use when analyzing performance.
+ */
+ public StatSummary(String label, VtsProfilingRegressionMode mode) {
+ this.label = label;
+ this.min = Double.MAX_VALUE;
+ this.max = Double.MIN_VALUE;
+ this.mean = 0;
+ this.var = 0;
+ this.n = 0;
+ this.regression_mode = mode;
+ }
+
+ /**
+ * Update the mean and variance using Welford's single-pass method.
+ *
+ * @param value The observed value in the stream.
+ */
+ public void updateStats(double value) {
+ n += 1;
+ double oldMean = mean;
+ mean = oldMean + (value - oldMean) / n;
+ var = var + (value - mean) * (value - oldMean);
+ if (value < min)
+ min = value;
+ if (value > max)
+ max = value;
+ }
+
+ /**
+ * Gets the best case of the stream.
+ *
+ * @return The min or max.
+ */
+ public double getBestCase() {
+ switch (regression_mode) {
+ case VTS_REGRESSION_MODE_DECREASING:
+ return getMax();
+ default:
+ return getMin();
+ }
+ }
+
+ /**
+ * Gets the calculated min of the stream.
+ *
+ * @return The min.
+ */
+ public double getMin() {
+ return min;
+ }
+
+ /**
+ * Gets the calculated max of the stream.
+ *
+ * @return The max.
+ */
+ public double getMax() {
+ return max;
+ }
+
+ /**
+ * Gets the calculated mean of the stream.
+ *
+ * @return The mean.
+ */
+ public double getMean() {
+ return mean;
+ }
+
+ /**
+ * Gets the calculated standard deviation of the stream.
+ *
+ * @return The standard deviation.
+ */
+ public double getStd() {
+ return Math.sqrt(var / (n - 1));
+ }
+
+ /**
+ * Gets the number of elements that have passed through the stream.
+ *
+ * @return Number of elements.
+ */
+ public int getCount() {
+ return n;
+ }
+
+ /**
+ * Gets the label for the summarized statistics.
+ *
+ * @return The (string) label.
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * Gets the regression mode.
+ *
+ * @return The VtsProfilingRegressionMode value.
+ */
+ public VtsProfilingRegressionMode getRegressionMode() {
+ return regression_mode;
+ }
+}
diff --git a/src/main/java/com/android/vts/util/TestResults.java b/src/main/java/com/android/vts/util/TestResults.java
new file mode 100644
index 0000000..0591bb6
--- /dev/null
+++ b/src/main/java/com/android/vts/util/TestResults.java
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.TestCaseRunEntity;
+import com.android.vts.entity.TestCaseRunEntity.TestCase;
+import com.android.vts.entity.TestRunEntity;
+import com.android.vts.proto.VtsReportMessage.TestCaseResult;
+import com.android.vts.util.UrlUtil.LinkDisplay;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.commons.lang.StringUtils;
+
+/** Helper object for describing test results data. */
+public class TestResults {
+ private final Logger logger = Logger.getLogger(getClass().getName());
+
+ private List<TestRunEntity> testRuns; // list of all test runs
+ private Map<Key, List<TestCaseRunEntity>>
+ testCaseRunMap; // map from test run key to the test run information
+ private Map<Key, List<DeviceInfoEntity>> deviceInfoMap; // map from test run key to device info
+ private Map<String, Integer> testCaseNameMap; // map from test case name to its order
+ private Set<String> profilingPointNameSet; // set of profiling point names
+
+ public String testName;
+ public String[] headerRow; // row to display above the test results table
+ public String[][] timeGrid; // grid of data storing timestamps to render as dates
+ public String[][] durationGrid; // grid of data storing timestamps to render as time intervals
+ public String[][] summaryGrid; // grid of data displaying a summary of the test run
+ public String[][] resultsGrid; // grid of data displaying test case results
+ public String[] profilingPointNames; // list of profiling point names in the test run
+ public Map<String, List<String[]>> logInfoMap; // map from test run index to url/display pairs
+ public int[] totResultCounts; // array of test result counts for the tip-of-tree runs
+ public String totBuildId = ""; // build ID of tip-of-tree run
+ public long startTime = Long.MAX_VALUE; // oldest timestamp displayed in the results table
+ public long endTime = Long.MIN_VALUE; // newest timestamp displayed in the results table
+
+ // Row labels for the test time-formatted information.
+ private static final String[] TIME_INFO_NAMES = {"Test Start", "Test End"};
+
+ // Row labels for the test duration information.
+ private static final String[] DURATION_INFO_NAMES = {"<b>Test Duration</b>"};
+
+ // Row labels for the test summary grid.
+ private static final String[] SUMMARY_NAMES = {"Total", "Passing #", "Non-Passing #",
+ "Passing %", "Covered Lines", "Coverage %", "Logs"};
+
+ // Row labels for the device summary information in the table header.
+ private static final String[] HEADER_NAMES = {"<b>Stats Type \\ Device Build ID</b>", "Branch",
+ "Build Target", "Device", "ABI Target", "VTS Build ID", "Hostname"};
+
+ /**
+ * Create a test results object.
+ *
+ * @param testName The name of the test.
+ */
+ public TestResults(String testName) {
+ this.testName = testName;
+ this.testRuns = new ArrayList<>();
+ this.deviceInfoMap = new HashMap<>();
+ this.testCaseRunMap = new HashMap<>();
+ this.testCaseNameMap = new HashMap<>();
+ this.logInfoMap = new HashMap<>();
+ this.profilingPointNameSet = new HashSet<>();
+ }
+
+ /**
+ * Add a test run to the test results.
+ *
+ * @param testRun The Entity containing the test run information.
+ * @param testCaseRuns The collection of test case executions within the test run.
+ * @param deviceInfos The collection of device information entities for the test run.
+ * @param profilingPoints The collection of profiling point names for the test run.
+ */
+ public void addTestRun(Entity testRun, Iterable<Entity> testCaseRuns,
+ Iterable<Entity> deviceInfos, Iterable<Entity> profilingPoints) {
+ // Process the devices in the test run
+ List<DeviceInfoEntity> devices = new ArrayList<>();
+ for (Entity e : deviceInfos) {
+ DeviceInfoEntity deviceInfoEntity = DeviceInfoEntity.fromEntity(e);
+ if (deviceInfoEntity == null)
+ continue;
+ devices.add(deviceInfoEntity);
+ }
+
+ // Filter out test runs lacking device information
+ if (devices.size() == 0) {
+ logger.log(Level.WARNING, "No device info found for run: " + testRun.getKey());
+ return;
+ }
+ deviceInfoMap.put(testRun.getKey(), devices);
+
+ TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRun);
+ if (testRunEntity == null)
+ return;
+ if (testRunEntity.startTimestamp < startTime) {
+ startTime = testRunEntity.startTimestamp;
+ }
+ if (testRunEntity.endTimestamp > endTime) {
+ endTime = testRunEntity.endTimestamp;
+ }
+ testRuns.add(testRunEntity);
+ testCaseRunMap.put(testRun.getKey(), new ArrayList<TestCaseRunEntity>());
+
+ // Process the test cases in the test run
+ for (Entity e : testCaseRuns) {
+ TestCaseRunEntity testCaseRunEntity = TestCaseRunEntity.fromEntity(e);
+ if (testCaseRunEntity == null)
+ continue;
+ testCaseRunMap.get(testRun.getKey()).add(testCaseRunEntity);
+ for (TestCase testCase : testCaseRunEntity.testCases) {
+ if (!testCaseNameMap.containsKey(testCase.name)) {
+ testCaseNameMap.put(testCase.name, testCaseNameMap.size());
+ }
+ }
+ }
+
+ // Process the profiling point observations in the test run
+ for (Entity e : profilingPoints) {
+ if (e.getKey().getName() != null) {
+ profilingPointNameSet.add(e.getKey().getName());
+ }
+ }
+ }
+
+ /** Creates a test case breakdown of the most recent test run. */
+ private void generateToTBreakdown() {
+ totResultCounts = new int[TestCaseResult.values().length];
+ if (testRuns.size() == 0)
+ return;
+
+ TestRunEntity mostRecentRun = testRuns.get(0);
+ List<TestCaseRunEntity> testCaseResults = testCaseRunMap.get(mostRecentRun.key);
+ List<DeviceInfoEntity> deviceInfos = deviceInfoMap.get(mostRecentRun.key);
+ if (deviceInfos.size() > 0) {
+ DeviceInfoEntity totDevice = deviceInfos.get(0);
+ totBuildId = totDevice.buildId;
+ }
+ // Count array for each test result
+ for (TestCaseRunEntity testCaseRunEntity : testCaseResults) {
+ for (TestCase testCase : testCaseRunEntity.testCases) {
+ totResultCounts[testCase.result]++;
+ }
+ }
+ }
+
+ /**
+ * Get the number of test runs observed.
+ *
+ * @return The number of test runs observed.
+ */
+ public int getSize() {
+ return testRuns.size();
+ }
+
+ /** Post-process the test runs to generate reports of the results. */
+ public void processReport() {
+ Comparator<TestRunEntity> comparator = new Comparator<TestRunEntity>() {
+ @Override
+ public int compare(TestRunEntity t1, TestRunEntity t2) {
+ return new Long(t2.startTimestamp).compareTo(t1.startTimestamp);
+ }
+ };
+ Collections.sort(testRuns, comparator);
+ generateToTBreakdown();
+
+ headerRow = new String[testRuns.size() + 1];
+ headerRow[0] = StringUtils.join(HEADER_NAMES, "<br>");
+
+ summaryGrid = new String[SUMMARY_NAMES.length][testRuns.size() + 1];
+ for (int i = 0; i < SUMMARY_NAMES.length; i++) {
+ summaryGrid[i][0] = "<b>" + SUMMARY_NAMES[i] + "</b>";
+ }
+
+ timeGrid = new String[TIME_INFO_NAMES.length][testRuns.size() + 1];
+ for (int i = 0; i < TIME_INFO_NAMES.length; i++) {
+ timeGrid[i][0] = "<b>" + TIME_INFO_NAMES[i] + "</b>";
+ }
+
+ durationGrid = new String[DURATION_INFO_NAMES.length][testRuns.size() + 1];
+ for (int i = 0; i < DURATION_INFO_NAMES.length; i++) {
+ durationGrid[i][0] = "<b>" + DURATION_INFO_NAMES[i] + "</b>";
+ }
+
+ resultsGrid = new String[testCaseNameMap.size()][testRuns.size() + 1];
+ // first column for results grid
+ for (String testCaseName : testCaseNameMap.keySet()) {
+ resultsGrid[testCaseNameMap.get(testCaseName)][0] = testCaseName;
+ }
+
+ // Iterate through the test runs
+ for (int col = 0; col < testRuns.size(); col++) {
+ TestRunEntity testRun = testRuns.get(col);
+
+ // Process the device information
+ List<DeviceInfoEntity> devices = deviceInfoMap.get(testRun.key);
+ List<String> buildIdList = new ArrayList<>();
+ List<String> buildAliasList = new ArrayList<>();
+ List<String> buildFlavorList = new ArrayList<>();
+ List<String> productVariantList = new ArrayList<>();
+ List<String> abiInfoList = new ArrayList<>();
+ for (DeviceInfoEntity deviceInfoEntity : devices) {
+ buildAliasList.add(deviceInfoEntity.branch);
+ buildFlavorList.add(deviceInfoEntity.buildFlavor);
+ productVariantList.add(deviceInfoEntity.product);
+ buildIdList.add(deviceInfoEntity.buildId);
+ String abi = "";
+ String abiName = deviceInfoEntity.abiName;
+ String abiBitness = deviceInfoEntity.abiBitness;
+ if (abiName.length() > 0) {
+ abi += abiName;
+ if (abiBitness.length() > 0) {
+ abi += " (" + abiBitness + " bit)";
+ }
+ }
+ abiInfoList.add(abi);
+ }
+
+ String buildAlias = StringUtils.join(buildAliasList, ",");
+ String buildFlavor = StringUtils.join(buildFlavorList, ",");
+ String productVariant = StringUtils.join(productVariantList, ",");
+ String buildIds = StringUtils.join(buildIdList, ",");
+ String abiInfo = StringUtils.join(abiInfoList, ",");
+ String vtsBuildId = testRun.testBuildId;
+
+ int totalCount = 0;
+ int passCount = (int) testRun.passCount;
+ int nonpassCount = (int) testRun.failCount;
+ TestCaseResult aggregateStatus = TestCaseResult.UNKNOWN_RESULT;
+ long totalLineCount = testRun.totalLineCount;
+ long coveredLineCount = testRun.coveredLineCount;
+
+ // Process test case results
+ for (TestCaseRunEntity testCaseEntity : testCaseRunMap.get(testRun.key)) {
+ // Update the aggregated test run status
+ totalCount += testCaseEntity.testCases.size();
+ for (TestCase testCase : testCaseEntity.testCases) {
+ int result = testCase.result;
+ String name = testCase.name;
+ if (result == TestCaseResult.TEST_CASE_RESULT_PASS.getNumber()) {
+ if (aggregateStatus == TestCaseResult.UNKNOWN_RESULT) {
+ aggregateStatus = TestCaseResult.TEST_CASE_RESULT_PASS;
+ }
+ } else if (result != TestCaseResult.TEST_CASE_RESULT_SKIP.getNumber()) {
+ aggregateStatus = TestCaseResult.TEST_CASE_RESULT_FAIL;
+ }
+
+ String systraceUrl = null;
+
+ if (testCaseEntity.getSystraceUrl() != null) {
+ String url = testCaseEntity.getSystraceUrl();
+ LinkDisplay validatedLink = UrlUtil.processUrl(url);
+ if (validatedLink != null) {
+ systraceUrl = validatedLink.url;
+ } else {
+ logger.log(Level.WARNING, "Invalid systrace URL : " + url);
+ }
+ }
+
+ int index = testCaseNameMap.get(name);
+ String classNames = "test-case-status ";
+ String glyph = "";
+ TestCaseResult testCaseResult = TestCaseResult.valueOf(result);
+ if (testCaseResult != null)
+ classNames += testCaseResult.toString();
+ else
+ classNames += TestCaseResult.UNKNOWN_RESULT.toString();
+
+ if (systraceUrl != null) {
+ classNames += " width-1";
+ glyph += "<a href=\"" + systraceUrl + "\" "
+ + "class=\"waves-effect waves-light btn red right inline-btn\">"
+ + "<i class=\"material-icons inline-icon\">info_outline</i></a>";
+ }
+ resultsGrid[index][col + 1] =
+ "<div class=\"" + classNames + "\">&nbsp;</div>" + glyph;
+ }
+ }
+ String passInfo;
+ try {
+ double passPct =
+ Math.round((100 * passCount / (passCount + nonpassCount)) * 100f) / 100f;
+ passInfo = Double.toString(passPct) + "%";
+ } catch (ArithmeticException e) {
+ passInfo = " - ";
+ }
+
+ // Process coverage metadata
+ String coverageInfo;
+ String coveragePctInfo;
+ try {
+ double coveragePct =
+ Math.round((100 * coveredLineCount / totalLineCount) * 100f) / 100f;
+ coveragePctInfo = Double.toString(coveragePct) + "%"
+ + "<a href=\"/show_coverage?testName=" + testName + "&startTime="
+ + testRun.startTimestamp
+ + "\" class=\"waves-effect waves-light btn red right inline-btn\">"
+ + "<i class=\"material-icons inline-icon\">menu</i></a>";
+ coverageInfo = coveredLineCount + "/" + totalLineCount;
+ } catch (ArithmeticException e) {
+ coveragePctInfo = " - ";
+ coverageInfo = " - ";
+ }
+
+ // Process log information
+ String logSummary = " - ";
+ List<String[]> logEntries = new ArrayList<>();
+ logInfoMap.put(Integer.toString(col), logEntries);
+
+ if (testRun.logLinks != null) {
+ for (String rawUrl : testRun.logLinks) {
+ LinkDisplay validatedLink = UrlUtil.processUrl(rawUrl);
+ if (validatedLink == null) {
+ logger.log(Level.WARNING, "Invalid logging URL : " + rawUrl);
+ continue;
+ }
+ String[] logInfo = new String[] {
+ validatedLink.name,
+ validatedLink.url // TODO: process the name from the URL
+ };
+ logEntries.add(logInfo);
+ }
+ }
+ if (logEntries.size() > 0) {
+ logSummary = Integer.toString(logEntries.size());
+ logSummary += "<i class=\"waves-effect waves-light btn red right inline-btn"
+ + " info-btn material-icons inline-icon\""
+ + " data-col=\"" + Integer.toString(col) + "\""
+ + ">launch</i>";
+ }
+
+ String icon = "<div class='status-icon " + aggregateStatus.toString() + "'>&nbsp</div>";
+ String hostname = testRun.hostName;
+
+ // Populate the header row
+ headerRow[col + 1] = "<span class='valign-wrapper'><b>" + buildIds + "</b>" + icon
+ + "</span>" + buildAlias + "<br>" + buildFlavor + "<br>" + productVariant
+ + "<br>" + abiInfo + "<br>" + vtsBuildId + "<br>" + hostname;
+
+ // Populate the test summary grid
+ summaryGrid[0][col + 1] = Integer.toString(totalCount);
+ summaryGrid[1][col + 1] = Integer.toString(passCount);
+ summaryGrid[2][col + 1] = Integer.toString(nonpassCount);
+ summaryGrid[3][col + 1] = passInfo;
+ summaryGrid[4][col + 1] = coverageInfo;
+ summaryGrid[5][col + 1] = coveragePctInfo;
+ summaryGrid[6][col + 1] = logSummary;
+
+ // Populate the test time info grid
+ timeGrid[0][col + 1] = Long.toString(testRun.startTimestamp);
+ timeGrid[1][col + 1] = Long.toString(testRun.endTimestamp);
+
+ // Populate the test duration info grid
+ durationGrid[0][col + 1] = Long.toString(testRun.endTimestamp - testRun.startTimestamp);
+ }
+
+ profilingPointNames =
+ profilingPointNameSet.toArray(new String[profilingPointNameSet.size()]);
+ Arrays.sort(profilingPointNames);
+ }
+}
diff --git a/src/main/java/com/android/vts/util/TestRunDetails.java b/src/main/java/com/android/vts/util/TestRunDetails.java
new file mode 100644
index 0000000..41e20c4
--- /dev/null
+++ b/src/main/java/com/android/vts/util/TestRunDetails.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import com.android.vts.entity.TestCaseRunEntity;
+import com.android.vts.entity.TestCaseRunEntity.TestCase;
+import com.android.vts.proto.VtsReportMessage.TestCaseResult;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/** Helper object for describing test results data. */
+public class TestRunDetails {
+ private static final String NAME_KEY = "name";
+ private static final String DATA_KEY = "data";
+
+ private class ResultColumn {
+ private final String name;
+ private final List<String> testCases;
+
+ public ResultColumn(String name) {
+ this.name = name;
+ this.testCases = new ArrayList<>();
+ }
+
+ public void add(String testCase) {
+ this.testCases.add(testCase);
+ }
+
+ public int size() {
+ return this.testCases.size();
+ }
+
+ public JsonObject toJson() {
+ Collections.sort(testCases);
+ JsonObject json = new JsonObject();
+ json.add(NAME_KEY, new JsonPrimitive(name));
+ json.add(DATA_KEY, new Gson().toJsonTree(testCases));
+ return json;
+ }
+ }
+
+ private final ResultColumn[] columns;
+ public final int[] resultCounts = new int[TestCaseResult.values().length];
+
+ public TestRunDetails() {
+ columns = new ResultColumn[TestCaseResult.values().length];
+ for (TestCaseResult r : TestCaseResult.values()) {
+ columns[r.getNumber()] = new ResultColumn(r.name());
+ }
+ }
+
+ /**
+ * Add a test case entity to the details object.
+ * @param testCaseEntity The TestCaseRunEntity object storing test case results.
+ */
+ public void addTestCase(TestCaseRunEntity testCaseEntity) {
+ for (TestCase testCase : testCaseEntity.testCases) {
+ int result = testCase.result;
+ if (result > resultCounts.length)
+ continue;
+ ++resultCounts[result];
+ ResultColumn column = columns[result];
+ column.add(testCase.name);
+ }
+ }
+
+ /**
+ * Serializes the test run details to json format.
+ *
+ * @return A JsonObject object representing the details object.
+ */
+ public JsonElement toJson() {
+ List<JsonObject> jsonColumns = new ArrayList<>();
+ for (ResultColumn column : columns) {
+ if (column.size() > 0) {
+ jsonColumns.add(column.toJson());
+ }
+ }
+ return new Gson().toJsonTree(jsonColumns);
+ }
+}
diff --git a/src/main/java/com/android/vts/util/TestRunMetadata.java b/src/main/java/com/android/vts/util/TestRunMetadata.java
new file mode 100644
index 0000000..0cc375c
--- /dev/null
+++ b/src/main/java/com/android/vts/util/TestRunMetadata.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.TestRunEntity;
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Query;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang.StringUtils;
+
+/** Helper object for describing test results data. */
+public class TestRunMetadata {
+ private static final String TEST_RUN = "testRun";
+ private static final String TEST_DETAILS = "testDetails";
+ private static final String DEVICE_INFO = "deviceInfo";
+ private static final String ABI_INFO = "abiInfo";
+
+ public final TestRunEntity testRun;
+
+ private String deviceInfo;
+ private String abiInfo;
+ private TestRunDetails details;
+
+ /**
+ * Create a test metadata object.
+ *
+ * @param testName The name of the test.
+ */
+ public TestRunMetadata(String testName, TestRunEntity testRun) {
+ this.testRun = testRun;
+ this.deviceInfo = "";
+ this.abiInfo = "";
+ this.details = null;
+ processDeviceInfo();
+ }
+
+ /**
+ * Get device information for the test run and add it to the metadata message.
+ */
+ private void processDeviceInfo() {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Query deviceInfoQuery = new Query(DeviceInfoEntity.KIND).setAncestor(testRun.key);
+ List<String> deviceInfoList = new ArrayList<>();
+ List<String> abiInfoList = new ArrayList<>();
+
+ for (Entity device : datastore.prepare(deviceInfoQuery).asIterable()) {
+ DeviceInfoEntity deviceInfoEntity = DeviceInfoEntity.fromEntity(device);
+ if (deviceInfoEntity == null) {
+ continue;
+ }
+ String abi = "";
+ String abiName = deviceInfoEntity.abiName;
+ String abiBitness = deviceInfoEntity.abiBitness;
+ if (abiName.length() > 0) {
+ abi += abiName;
+ if (abiBitness.length() > 0) {
+ abi += " (" + abiBitness + " bit)";
+ }
+ }
+ abiInfoList.add(abi);
+ deviceInfoList.add(deviceInfoEntity.branch + "/" + deviceInfoEntity.buildFlavor + " ("
+ + deviceInfoEntity.buildId + ")");
+ }
+ this.abiInfo = StringUtils.join(abiInfoList, ", ");
+ this.deviceInfo = StringUtils.join(deviceInfoList, ", ");
+ }
+
+ /**
+ * Get the device info string in the test metadata.
+ * @return The string descriptor of the devices used in the test run.
+ */
+ public String getDeviceInfo() {
+ return this.deviceInfo;
+ }
+
+ /**
+ * Get the test run details (e.g. test case information) for the test run.
+ * @return The TestRunDetails object stored in the metadata, or null if not set.
+ */
+ public TestRunDetails getDetails() {
+ return this.details;
+ }
+
+ /**
+ * Add test case details to the metadata object.
+ *
+ * Used for prefetching details on initial page load.
+ * @param details The TestRunDetails object storing test case results for the test run.
+ */
+ public void addDetails(TestRunDetails details) {
+ this.details = details;
+ }
+
+ /**
+ * Serializes the test run metadata to json format.
+ *
+ * @return A JsonElement object representing the details object.
+ */
+ public JsonObject toJson() {
+ JsonObject json = new JsonObject();
+ json.add(DEVICE_INFO, new JsonPrimitive(this.deviceInfo));
+ json.add(ABI_INFO, new JsonPrimitive(this.abiInfo));
+ json.add(TEST_RUN, this.testRun.toJson());
+ if (this.details != null) {
+ json.add(TEST_DETAILS, this.details.toJson());
+ }
+ return json;
+ }
+}
diff --git a/src/main/java/com/android/vts/util/UrlUtil.java b/src/main/java/com/android/vts/util/UrlUtil.java
new file mode 100644
index 0000000..03c23eb
--- /dev/null
+++ b/src/main/java/com/android/vts/util/UrlUtil.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright 2017 Google Inc. All Rights Reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>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.vts.util;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+/** UrlUtil, a helper class for formatting and validating URLs. */
+public class UrlUtil {
+ private static final String HTTPS = "https";
+
+ public static class LinkDisplay {
+ public final String name;
+ public final String url;
+
+ /**
+ * Create a link display object.
+ *
+ * @param uri The hyperlink URI.
+ */
+ public LinkDisplay(URI uri) {
+ this.url = uri.toString();
+
+ // Parse the name from the URI path
+ int lastSeparator = uri.getPath().lastIndexOf('/');
+ if (lastSeparator < 0) {
+ this.name = uri.toString();
+ } else {
+ this.name = uri.getPath().substring(lastSeparator + 1);
+ }
+ }
+ }
+
+ /**
+ * Validates and formats a URL.
+ *
+ * <p>Ensures that the protocol is HTTPs and the URL is properly formatted. This avoids link
+ * issues in the UI and possible vulnerabilities due to embedded JS in URLs.
+ *
+ * @param urlString The url string to validate.
+ * @returns The validated LinkDisplay object.
+ */
+ public static LinkDisplay processUrl(String urlString) {
+ try {
+ URL url = new URL(urlString);
+ String scheme = url.getProtocol();
+ String userInfo = url.getUserInfo();
+ String host = url.getHost();
+ int port = url.getPort();
+ String path = url.getPath();
+ String query = url.getQuery();
+ String fragment = url.getRef();
+ if (!url.getProtocol().equals(HTTPS))
+ throw new MalformedURLException();
+ URI uri = new URI(scheme, userInfo, host, port, path, query, fragment);
+ return new LinkDisplay(uri);
+ } catch (MalformedURLException | URISyntaxException e) {
+ return null;
+ }
+ }
+}
diff --git a/src/main/webapp/WEB-INF/appengine-web.xml b/src/main/webapp/WEB-INF/appengine-web.xml
new file mode 100644
index 0000000..6c7632c
--- /dev/null
+++ b/src/main/webapp/WEB-INF/appengine-web.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2016 Google Inc.
+ 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.
+-->
+
+<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
+ <application>s~google.com:android-vts-staging</application>
+ <version>4</version>
+ <threadsafe>true</threadsafe>
+
+ <system-properties>
+ <property name="EMAIL_DOMAIN" value="${appengine.emailDomain}" />
+ <property name="SENDER_EMAIL" value="${appengine.senderEmail}" />
+ <property name="DEFAULT_EMAIL" value="${appengine.defaultEmail}" />
+ <property name="SERVICE_CLIENT_ID" value="${appengine.serviceClientID}" />
+ <property name="CLIENT_ID" value="${appengine.clientID}" />
+ <property name="GERRIT_URI" value="${gerrit.uri}" />
+ <property name="GERRIT_SCOPE" value="${gerrit.scope}" />
+ <property name="ANALYTICS_ID" value="${analytics.id}" />
+ </system-properties>
+
+</appengine-web-app> \ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/cron.xml b/src/main/webapp/WEB-INF/cron.xml
new file mode 100644
index 0000000..d8dc49e
--- /dev/null
+++ b/src/main/webapp/WEB-INF/cron.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright 2016 Google Inc. All Rights Reserved.
+
+ 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.
+-->
+<cronentries>
+ <cron>
+ <url>/cron/vts_alert_job</url>
+ <description>Send test failure emails.</description>
+ <schedule>every 2 minutes</schedule>
+ </cron>
+ <cron>
+ <url>/cron/vts_performance_job</url>
+ <description>Send daily performance digests.</description>
+ <schedule>every day 07:30</schedule>
+ <timezone>America/Los_Angeles</timezone>
+ </cron>
+</cronentries> \ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/datastore-indexes.xml b/src/main/webapp/WEB-INF/datastore-indexes.xml
new file mode 100644
index 0000000..01983f5
--- /dev/null
+++ b/src/main/webapp/WEB-INF/datastore-indexes.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2017 Google Inc.
+ 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.
+-->
+
+<datastore-indexes autoGenerate="true">
+
+ <datastore-index kind="TestPlanRun" ancestor="true" source="manual">
+ <property name="type" direction="asc"/>
+ <property name="__key__" direction="desc"/>
+ </datastore-index>
+
+ <datastore-index kind="TestPlanRun" ancestor="true" source="manual">
+ <property name="type" direction="asc"/>
+ <property name="__key__" direction="asc"/>
+ </datastore-index>
+
+ <datastore-index kind="TestPlanRun" ancestor="true" source="manual">
+ <property name="__key__" direction="desc"/>
+ </datastore-index>
+
+ <datastore-index kind="Test" ancestor="false" source="manual">
+ <property name="failCount" direction="asc"/>
+ <property name="passCount" direction="asc"/>
+ </datastore-index>
+
+ <datastore-index kind="TestRun" ancestor="true" source="manual">
+ <property name="type" direction="asc"/>
+ <property name="__key__" direction="desc"/>
+ </datastore-index>
+
+ <datastore-index kind="TestRun" ancestor="true" source="manual">
+ <property name="type" direction="asc"/>
+ <property name="__key__" direction="asc"/>
+ </datastore-index>
+
+ <datastore-index kind="TestRun" ancestor="true" source="manual">
+ <property name="__key__" direction="desc"/>
+ </datastore-index>
+
+ <datastore-index kind="TestRun" ancestor="true" source="manual">
+ <property name="hasCoverage" direction="asc"/>
+ <property name="__key__" direction="desc"/>
+ </datastore-index>
+
+ <datastore-index kind="TestRun" ancestor="false" source="manual">
+ <property name="testName" direction="asc"/>
+ <property name="startTimestamp" direction="asc"/>
+ </datastore-index>
+
+ <datastore-index kind="TestRun" ancestor="false" source="manual">
+ <property name="testName" direction="asc"/>
+ <property name="startTimestamp" direction="desc"/>
+ </datastore-index>
+
+ <datastore-index kind="TestRun" ancestor="false" source="manual">
+ <property name="testName" direction="asc"/>
+ <property name="type" direction="asc"/>
+ <property name="startTimestamp" direction="asc"/>
+ </datastore-index>
+
+ <datastore-index kind="TestRun" ancestor="false" source="manual">
+ <property name="testName" direction="asc"/>
+ <property name="type" direction="asc"/>
+ <property name="startTimestamp" direction="desc"/>
+ </datastore-index>
+
+</datastore-indexes> \ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/jsp/dashboard_main.jsp b/src/main/webapp/WEB-INF/jsp/dashboard_main.jsp
new file mode 100644
index 0000000..3b72110
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/dashboard_main.jsp
@@ -0,0 +1,177 @@
+<%--
+ ~ Copyright (c) 2016 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<html>
+ <link rel='stylesheet' href='/css/dashboard_main.css'>
+ <%@ include file='header.jsp' %>
+ <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js'></script>
+ <body>
+ <script>
+ var allTests = ${allTestsJson};
+ var testSet = new Set(allTests);
+ var subscriptionMap = ${subscriptionMapJson};
+
+ var addFavorite = function() {
+ if ($(this).hasClass('disabled')) {
+ return;
+ }
+ var test = $('#input-box').val();
+ if (!testSet.has(test) || test in subscriptionMap) {
+ return;
+ }
+ $('#add-button').addClass('disabled');
+ $.post('/api/favorites/' + test).then(function(data) {
+ if (!data.key) {
+ return;
+ }
+ subscriptionMap[test] = data.key;
+ var wrapper = $('<div></div>');
+ var a = $('<a></a>')
+ .attr('href', '/show_table?testName=' + test);
+ var div = $('<div class="col s11 card hoverable option"></div>');
+ div.addClass('valign-wrapper waves-effect');
+ div.appendTo(a);
+ var span = $('<span class="entry valign"></span>').text(test);
+ span.appendTo(div);
+ a.appendTo(wrapper);
+ var clear = $('<a class="col s1 btn-flat center"></a>');
+ clear.addClass('clear-button');
+ clear.append('<i class="material-icons">clear</i>');
+ clear.attr('test', test);
+ clear.appendTo(wrapper);
+ clear.click(removeFavorite);
+ wrapper.prependTo('#options').hide()
+ .slideDown(150);
+ $('#input-box').val(null);
+ Materialize.updateTextFields();
+ }).always(function() {
+ $('#add-button').removeClass('disabled');
+ });
+ }
+
+ var removeFavorite = function() {
+ var self = $(this);
+ if (self.hasClass('disabled')) {
+ return;
+ }
+ var test = self.attr('test');
+ if (!(test in subscriptionMap)) {
+ return;
+ }
+ self.addClass('disabled');
+ $.ajax({
+ url: '/api/favorites/' + subscriptionMap[test],
+ type: 'DELETE'
+ }).always(function() {
+ self.removeClass('disabled');
+ }).then(function() {
+ delete subscriptionMap[test];
+ self.parent().slideUp(150, function() {
+ self.remove();
+ });
+ });
+ }
+
+ $.widget('custom.sizedAutocomplete', $.ui.autocomplete, {
+ _resizeMenu: function() {
+ this.menu.element.outerWidth($('#input-box').width());
+ }
+ });
+
+ $(function() {
+ $('#input-box').sizedAutocomplete({
+ source: allTests,
+ classes: {
+ 'ui-autocomplete': 'card'
+ }
+ });
+
+ $('#input-box').keyup(function(event) {
+ if (event.keyCode == 13) { // return button
+ $('#add-button').click();
+ }
+ });
+
+ $('.clear-button').click(removeFavorite);
+ $('#add-button').click(addFavorite);
+ });
+ </script>
+ <div class='container'>
+ <c:choose>
+ <c:when test='${not empty error}'>
+ <div id='error-container' class='row card'>
+ <div class='col s12 center-align'>
+ <h5>${error}</h5>
+ </div>
+ </div>
+ </c:when>
+ <c:otherwise>
+ <c:set var='width' value='${showAll ? 12 : 11}' />
+ <c:if test='${not showAll}'>
+ <div class='row'>
+ <div class='input-field col s8'>
+ <input type='text' id='input-box'></input>
+ <label for='input-box'>Search for tests to add to favorites</label>
+ </div>
+ <div id='add-button-wrapper' class='col s1 valign-wrapper'>
+ <a id='add-button' class='btn-floating btn waves-effect waves-light red valign'><i class='material-icons'>add</i></a>
+ </div>
+ </div>
+ </c:if>
+ <div class='row'>
+ <div class='col s12'>
+ <h4 id='section-header'>${headerLabel}</h4>
+ </div>
+ </div>
+ <div class='row' id='options'>
+ <c:forEach items='${testNames}' var='test'>
+ <div>
+ <a href='/show_table?testName=${test.name}'>
+ <div class='col s${width} card hoverable option valign-wrapper waves-effect'>
+ <span class='entry valign'>${test.name}
+ <c:if test='${test.failCount >= 0 && test.passCount >= 0}'>
+ <c:set var='color' value='${test.failCount > 0 ? "red" : (test.passCount > 0 ? "green" : "grey")}' />
+ <span class='indicator center ${color}'>
+ ${test.passCount} / ${test.passCount + test.failCount}
+ </span>
+ </c:if>
+ </span>
+ </div>
+ </a>
+ <c:if test='${not showAll}'>
+ <a class='col s1 btn-flat center clear-button' test='${test.name}'>
+ <i class='material-icons'>clear</i>
+ </a>
+ </c:if>
+ </div>
+ </c:forEach>
+ </div>
+ </c:otherwise>
+ </c:choose>
+ </div>
+ <c:if test='${empty error}'>
+ <div class='center'>
+ <a href='${buttonLink}' id='show-button' class='btn waves-effect red'>${buttonLabel}
+ <i id='show-button-arrow' class='material-icons right'>${buttonIcon}</i>
+ </a>
+ </div>
+ </c:if>
+ <%@ include file='footer.jsp' %>
+ </body>
+</html>
diff --git a/src/main/webapp/WEB-INF/jsp/footer.jsp b/src/main/webapp/WEB-INF/jsp/footer.jsp
new file mode 100644
index 0000000..ed2d950
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/footer.jsp
@@ -0,0 +1,25 @@
+<%--
+ ~ Copyright (c) 2017 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+<footer class='page-footer'>
+ <div class='footer-copyright'>
+ <div class='container'>
+ © 2017 - The Android Open Source Project
+ </div>
+ </div>
+</footer>
diff --git a/src/main/webapp/WEB-INF/jsp/header.jsp b/src/main/webapp/WEB-INF/jsp/header.jsp
new file mode 100644
index 0000000..77ec600
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/header.jsp
@@ -0,0 +1,70 @@
+<%--
+ ~ Copyright (c) 2017 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<head>
+ <link rel='stylesheet' href='https://www.gstatic.com/external_hosted/materialize/all_styles-bundle.css'>
+ <link rel='icon' href='https://www.gstatic.com/images/branding/googleg/1x/googleg_standard_color_32dp.png' sizes='32x32'>
+ <link rel='stylesheet' href='https://fonts.googleapis.com/icon?family=Material+Icons'>
+ <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700'>
+ <link rel='stylesheet' href='/css/navbar.css'>
+ <link rel='stylesheet' href='/css/common.css'>
+ <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
+ <script src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js'></script>
+ <script src='https://www.gstatic.com/external_hosted/materialize/materialize.min.js'></script>
+ <script type='text/javascript'>
+ if (${analyticsID}) {
+ // Autogenerated from Google Analytics
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
+ ga('create', ${analyticsID}, 'auto');
+ ga('send', 'pageview');
+ }
+ </script>
+ <title>VTS Dashboard</title>
+</head>
+<body>
+ <nav id='navbar'>
+ <div class='nav-wrapper'>
+ <a href='#' class='brand-logo center'>VTS Dashboard</a>
+ <ul class='nav-list'>
+ <c:forEach items='${navbarLinks}' var='link' varStatus='loop'>
+ <li class='${loop.index == activeIndex ? "active" : ""}'>
+ <a class='nav-list-item' href='${link.url}'>${link.name}</a>
+ </li>
+ </c:forEach>
+ </ul>
+ <ul class='right'><li>
+ <a id='dropdown-button' class='dropdown-button btn red lighten-3' href='#' data-activates='dropdown'>
+ ${email}
+ </a>
+ </li></ul>
+ <ul id='dropdown' class='dropdown-content'>
+ <li><a href='${logoutURL}'>Log out</a></li>
+ </ul>
+ <c:if test='${breadcrumbLinks != null}'>
+ <div id='nav-sublist'>
+ <c:forEach items='${breadcrumbLinks}' var='link'>
+ <a href='${link.url}' class='nav-sublist-item breadcrumb'>${link.name}</a>
+ </c:forEach>
+ </div>
+ </c:if>
+ </div>
+ </nav>
+</body>
diff --git a/src/main/webapp/WEB-INF/jsp/show_coverage.jsp b/src/main/webapp/WEB-INF/jsp/show_coverage.jsp
new file mode 100644
index 0000000..790590d
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/show_coverage.jsp
@@ -0,0 +1,171 @@
+<%--
+ ~ Copyright (c) 2016 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<html>
+ <%@ include file="header.jsp" %>
+ <link rel="stylesheet" href="/css/show_coverage.css">
+ <script src="https://apis.google.com/js/api.js" type="text/javascript"></script>
+ <body>
+ <script type="text/javascript">
+ var coverageVectors = ${coverageVectors};
+ $(document).ready(function() {
+ // Initialize AJAX for CORS
+ $.ajaxSetup({
+ xhrFields : {
+ withCredentials: true
+ }
+ });
+
+ // Initialize auth2 client and scope for requests to Gerrit
+ gapi.load('auth2', function() {
+ var auth2 = gapi.auth2.init({
+ client_id: ${clientId},
+ scope: ${gerritScope}
+ });
+ auth2.then(displayEntries);
+ });
+ });
+
+ /* Open a window to Gerrit so that user can login.
+ Minimize the previously clicked entry.
+ */
+ var gerritLogin = function(element) {
+ window.open(${gerritURI}, "Ratting", "toolbar=0,status=0");
+ element.click();
+ }
+
+ /* Loads source code for a particular entry and displays it with
+ coverage information as the accordion entry expands.
+ */
+ var onClick = function() {
+ // Remove source code from the accordion entry that was open before
+ var self = $(this);
+ var prev = self.parent().siblings('li.active');
+ if (prev.length > 0) {
+ prev.find('.table-container').empty();
+ }
+ var url = self.parent().attr('url');
+ var i = self.parent().attr('index');
+ var container = self.parent().find('.table-container');
+ container.html('<div class="center-align">Loading...</div>');
+ if (self.parent().hasClass('active')) {
+ // Remove the code from display
+ container.empty();
+ } else {
+ /* Fetch and display the code.
+ Note: a coverageVector may be shorter than sourceContents due
+ to non-executable (i.e. comments or language-specific syntax)
+ lines in the code. Trailing source lines that have no
+ coverage information are assumed to be non-executable.
+ */
+ $.ajax({
+ url: url,
+ dataType: 'text'
+ }).promise().done(function(src) {
+ src = atob(src);
+ if (!src) return;
+ srcLines = src.split('\n');
+ covered = 0;
+ total = 0;
+ var table = $('<table class="table"></table>');
+ var rows = srcLines.forEach(function(line, j) {
+ var count = coverageVectors[i][j];
+ var row = $('<tr></tr>');
+ if (typeof count == 'undefined' || count < 0) {
+ count = "--";
+ } else if (count == 0) {
+ row.addClass('uncovered');
+ total += 1;
+ } else {
+ row.addClass('covered');
+ total += 1;
+ }
+ row.append('<td class="count">' + String(count) + '</td>');
+ row.append('<td class="line_no">' + String(j+1) + '</td>');
+ code = $('<td class="code"></td>');
+ code.text(String(line));
+ code.appendTo(row);
+ row.appendTo(table);
+ });
+ container.empty();
+ container.append(table);
+ }).fail(function(error) {
+ if (error.status == 0) { // origin error, refresh cookie
+ container.empty();
+ container.html('<div class="center-align">' +
+ '<span class="login-button">' +
+ 'Click to authorize Gerrit access' +
+ '</span></div>');
+ container.find('.login-button').click(function() {
+ gerritLogin(self);
+ });
+ } else {
+ container.html('<div class="center-align">' +
+ 'Not found.</div>');
+ }
+ });
+ }
+ }
+
+ /* Appends a row to the display with test name and aggregated coverage
+ information. On expansion, source code is loaded with coverage
+ highlighted by calling 'onClick'.
+ */
+ var displayEntries = function() {
+ var sourceFilenames = ${sourceFiles};
+ var sectionMap = ${sectionMap};
+ var gerritURI = ${gerritURI};
+ var projects = ${projects};
+ var commits = ${commits};
+ var indicators = ${indicators};
+ Object.keys(sectionMap).forEach(function(section) {
+ var indices = sectionMap[section];
+ var html = String();
+ indices.forEach(function(i) {
+ var url = gerritURI + '/projects/' +
+ encodeURIComponent(projects[i]) + '/commits/' +
+ encodeURIComponent(commits[i]) + '/files/' +
+ encodeURIComponent(sourceFilenames[i]) +
+ '/content';
+ html += '<li url="' + url + '" index="' + i + '">' +
+ '<div class="collapsible-header">' +
+ '<i class="material-icons">library_books</i>' +
+ sourceFilenames[i] + indicators[i] + '</div>';
+ html += '<div class="collapsible-body row">' +
+ '<div class="html-container">' +
+ '<div class="table-container"></div>' +
+ '</div></div></li>';
+ });
+ if (html) {
+ html = '<h4 class="section-title"><b>Coverage:</b> ' +
+ section + '</h4><ul class="collapsible popout" ' +
+ 'data-collapsible="accordion">' + html + '</ul>';
+ $('#coverage-container').append(html);
+ }
+ });
+ $('.collapsible.popout').collapsible({
+ accordion : true
+ }).find('.collapsible-header').click(onClick);
+ }
+ </script>
+ <div id='coverage-container' class='wide container'>
+ </div>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
diff --git a/src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp b/src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp
new file mode 100644
index 0000000..b06e9df
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp
@@ -0,0 +1,168 @@
+<%--
+ ~ Copyright (c) 2017 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<html>
+ <!-- <link rel='stylesheet' href='/css/dashboard_main.css'> -->
+ <%@ include file='header.jsp' %>
+ <link type='text/css' href='/css/show_test_runs_common.css' rel='stylesheet'>
+ <link type='text/css' href='/css/test_results.css' rel='stylesheet'>
+ <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
+ <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script>
+ <script src='js/time.js'></script>
+ <script src='js/test_results.js'></script>
+ <script type='text/javascript'>
+ google.charts.load('current', {'packages':['table', 'corechart']});
+ google.charts.setOnLoadCallback(drawStatsChart);
+ google.charts.setOnLoadCallback(drawCoverageCharts);
+
+ $(document).ready(function() {
+ $('#test-results-container').showTests(${testRuns}, true);
+ });
+
+ // draw test statistics chart
+ function drawStatsChart() {
+ var testStats = ${testStats};
+ if (testStats.length < 1) {
+ return;
+ }
+ var resultNames = ${resultNamesJson};
+ var rows = resultNames.map(function(res, i) {
+ nickname = res.replace('TEST_CASE_RESULT_', '').replace('_', ' ')
+ .trim().toLowerCase();
+ return [nickname, parseInt(testStats[i])];
+ });
+ rows.unshift(['Result', 'Count']);
+
+ // Get CSS color definitions (or default to white)
+ var colors = resultNames.map(function(res) {
+ return $('.' + res).css('background-color') || 'white';
+ });
+
+ var data = google.visualization.arrayToDataTable(rows);
+ var options = {
+ is3D: false,
+ colors: colors,
+ fontName: 'Roboto',
+ fontSize: '14px',
+ legend: {position: 'labeled'},
+ tooltip: {showColorCode: true, ignoreBounds: false},
+ chartArea: {height: '80%', width: '90%'},
+ pieHole: 0.4
+ };
+
+ var chart = new google.visualization.PieChart(document.getElementById('pie-chart-stats'));
+ chart.draw(data, options);
+ }
+
+ // draw the coverage pie charts
+ function drawCoverageCharts() {
+ var coveredLines = ${coveredLines};
+ var uncoveredLines = ${uncoveredLines};
+ var rows = [
+ ["Result", "Count"],
+ ["Covered Lines", coveredLines],
+ ["Uncovered Lines", uncoveredLines]
+ ];
+
+ // Get CSS color definitions (or default to white)
+ var colors = [
+ $('.TEST_CASE_RESULT_PASS').css('background-color') || 'white',
+ $('.TEST_CASE_RESULT_FAIL').css('background-color') || 'white'
+ ]
+
+ var data = google.visualization.arrayToDataTable(rows);
+
+
+ var optionsRaw = {
+ is3D: false,
+ colors: colors,
+ fontName: 'Roboto',
+ fontSize: '14px',
+ pieSliceText: 'value',
+ legend: {position: 'bottom'},
+ chartArea: {height: '80%', width: '90%'},
+ tooltip: {showColorCode: true, ignoreBounds: false, text: 'value'},
+ pieHole: 0.4
+ };
+
+ var optionsNormalized = {
+ is3D: false,
+ colors: colors,
+ fontName: 'Roboto',
+ fontSize: '14px',
+ legend: {position: 'bottom'},
+ tooltip: {showColorCode: true, ignoreBounds: false, text: 'percentage'},
+ chartArea: {height: '80%', width: '90%'},
+ pieHole: 0.4
+ };
+
+ var chart = new google.visualization.PieChart(document.getElementById('pie-chart-coverage-raw'));
+ chart.draw(data, optionsRaw);
+
+ chart = new google.visualization.PieChart(document.getElementById('pie-chart-coverage-normalized'));
+ chart.draw(data, optionsNormalized);
+ }
+
+ </script>
+
+ <body>
+ <div class='wide container'>
+ <div class='row'>
+ <div class='col s12'>
+ <div class='col s12 card center-align'>
+ <div id='legend-wrapper'>
+ <c:forEach items='${resultNames}' var='res'>
+ <div class='center-align legend-entry'>
+ <c:set var='trimmed' value='${fn:replace(res, "TEST_CASE_RESULT_", "")}'/>
+ <c:set var='nickname' value='${fn:replace(trimmed, "_", " ")}'/>
+ <label for='${res}'>${nickname}</label>
+ <div id='${res}' class='${res} legend-bubble'></div>
+ </div>
+ </c:forEach>
+ </div>
+ </div>
+ </div>
+ <div class='col s4 valign-wrapper'>
+ <!-- pie chart -->
+ <div class='pie-chart-wrapper col s12 valign center-align card'>
+ <h6 class='pie-chart-title'>Test Statistics</h6>
+ <div id='pie-chart-stats' class='pie-chart-div'></div>
+ </div>
+ </div>
+ <div class='col s4 valign-wrapper'>
+ <!-- pie chart -->
+ <div class='pie-chart-wrapper col s12 valign center-align card'>
+ <h6 class='pie-chart-title'>Coverage (Raw)</h6>
+ <div id='pie-chart-coverage-raw' class='pie-chart-div'></div>
+ </div>
+ </div>
+ <div class='col s4 valign-wrapper'>
+ <!-- pie chart -->
+ <div class='pie-chart-wrapper col s12 valign center-align card'>
+ <h6 class='pie-chart-title'>Coverage (Normalized)</h6>
+ <div id='pie-chart-coverage-normalized' class='pie-chart-div'></div>
+ </div>
+ </div>
+ </div>
+ <div class='col s12' id='test-results-container'>
+ </div>
+ </div>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
diff --git a/src/main/webapp/WEB-INF/jsp/show_graph.jsp b/src/main/webapp/WEB-INF/jsp/show_graph.jsp
new file mode 100644
index 0000000..7111f58
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/show_graph.jsp
@@ -0,0 +1,292 @@
+<%--
+ ~ Copyright (c) 2016 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<html>
+ <%@ include file="header.jsp" %>
+ <link type='text/css' href='/css/datepicker.css' rel='stylesheet'>
+ <link type='text/css' href='/css/show_graph.css' rel='stylesheet'>
+ <link rel='stylesheet' href='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.css'>
+ <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
+ <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js'></script>
+ <body>
+ <script type='text/javascript'>
+ google.charts.load('current', {packages:['corechart', 'table', 'line']});
+ google.charts.setOnLoadCallback(drawAllGraphs);
+
+ ONE_DAY = 86400000000;
+ MICRO_PER_MILLI = 1000;
+ N_BUCKETS = 200;
+
+ var graphs = ${graphs};
+
+ $(function() {
+ $('select').material_select();
+ var date = $('#date').datepicker({
+ showAnim: 'slideDown',
+ maxDate: new Date()
+ });
+ date.datepicker('setDate', new Date(${endTime} / MICRO_PER_MILLI));
+ $('#load').click(load);
+ $('#outlier-select').change(drawAllGraphs);
+ });
+
+ // Draw all graphs.
+ function drawAllGraphs() {
+ $('#profiling-container').empty();
+ var percentileIndex = Number($('#outlier-select').val());
+
+ // Get histogram extrema
+ var histMin = null;
+ var histMax = null;
+ graphs.forEach(function(g) {
+ if (g.type != 'HISTOGRAM') return;
+ var minVal;
+ var maxVal;
+ if (percentileIndex == -1) {
+ minVal = g.min;
+ maxVal = g.max;
+ } else {
+ minVal = g.percentile_values[percentileIndex];
+ var endIndex = g.percentiles.length - percentileIndex - 1
+ maxVal = g.percentile_values[endIndex];
+ }
+ if (!histMin || minVal < histMin) histMin = minVal;
+ if (!histMax || maxVal > histMax) histMax = maxVal;
+ });
+
+ graphs.forEach(function(graph) {
+ if (graph.type == 'LINE_GRAPH') drawLineGraph(graph);
+ else if (graph.type == 'HISTOGRAM')
+ drawHistogram(graph, histMin, histMax);
+ });
+ }
+
+ /**
+ * Draw a line graph.
+ *
+ * Args:
+ * lineGraph: a JSON object containing the following fields:
+ * - name: the name of the graph
+ * - values: an array of numbers
+ * - ticks: an array of strings to use as x-axis labels
+ * - ids: an array of string labels for each point (e.g. the
+ * build info for the run that produced the point)
+ * - x_label: the string label for the x axis
+ * - y_label: the string label for the y axis
+ */
+ function drawLineGraph(lineGraph) {
+ if (!lineGraph.ticks || lineGraph.ticks.length < 1) {
+ return;
+ }
+ var title = 'Performance';
+ if (lineGraph.name) title += ' (' + lineGraph.name + ')';
+ lineGraph.ticks.forEach(function (label, i) {
+ lineGraph.values[i].unshift(label);
+ });
+ var data = new google.visualization.DataTable();
+ data.addColumn('string', lineGraph.x_label);
+ lineGraph.ids.forEach(function(id) {
+ data.addColumn('number', id);
+ });
+ data.addRows(lineGraph.values);
+ var options = {
+ chart: {
+ title: title,
+ subtitle: lineGraph.y_label
+ },
+ legend: { position: 'none' }
+ };
+ var container = $('<div class="row card center-align col s12 graph-wrapper"></div>');
+ container.appendTo('#profiling-container');
+ var chartDiv = $('<div class="col s12 graph"></div>');
+ chartDiv.appendTo(container);
+ var chart = new google.charts.Line(chartDiv[0]);
+ chart.draw(data, options);
+ }
+
+ /**
+ * Draw a histogram.
+ *
+ * Args:
+ * hist: a JSON object containing the following fields:
+ * - name: the name of the graph
+ * - values: an array of numbers
+ * - ids: an array of string labels for each point (e.g. the
+ * build info for the run that produced the point)
+ * - x_label: the string label for the x axis
+ * - y_label: the string label for the y axis
+ * min: the minimum value to display
+ * max: the maximum value to display
+ */
+ function drawHistogram(hist, min, max) {
+ if (!hist.values || hist.values.length == 0) return;
+ var title = 'Performance';
+ if (hist.name) title += ' (' + hist.name + ')';
+ var values = hist.values;
+ var histogramData = values.reduce(function(result, d, i) {
+ if (d <= max && d >= min) result.push([hist.ids[i], d]);
+ return result;
+ }, []);
+
+ var data = google.visualization.arrayToDataTable(histogramData, true);
+ var bucketSize = (max - min) / N_BUCKETS;
+
+ var options = {
+ title: title,
+ titleTextStyle: {
+ color: '#757575',
+ fontSize: 16,
+ bold: false
+ },
+ legend: { position: 'none' },
+ colors: ['#4285F4'],
+ fontName: 'Roboto',
+ vAxis:{
+ title: hist.y_label,
+ titleTextStyle: {
+ color: '#424242',
+ fontSize: 12,
+ italic: false
+ },
+ textStyle: {
+ fontSize: 12,
+ color: '#757575'
+ },
+ },
+ hAxis: {
+ title: hist.x_label,
+ textStyle: {
+ fontSize: 12,
+ color: '#757575'
+ },
+ titleTextStyle: {
+ color: '#424242',
+ fontSize: 12,
+ italic: false
+ }
+ },
+ bar: { gap: 0 },
+ histogram: {
+ minValue: min,
+ maxValue: max,
+ maxNumBuckets: N_BUCKETS,
+ bucketSize: bucketSize
+ },
+ chartArea: {
+ width: '100%',
+ top: 40,
+ left: 60,
+ height: 375
+ }
+ };
+ var container = $('<div class="row card col s12 graph-wrapper"></div>');
+ container.appendTo('#profiling-container');
+
+ var chartDiv = $('<div class="col s12 graph"></div>');
+ chartDiv.appendTo(container);
+ var chart = new google.visualization.Histogram(chartDiv[0]);
+ chart.draw(data, options);
+
+ var tableDiv = $('<div class="col s12"></div>');
+ tableDiv.appendTo(container);
+
+ var tableHtml = '<table class="percentile-table"><thead><tr>';
+ hist.percentiles.forEach(function(p) {
+ tableHtml += '<th data-field="id">' + p + '%</th>';
+ });
+ tableHtml += '</tr></thead><tbody><tr>';
+ hist.percentile_values.forEach(function(v) {
+ tableHtml += '<td>' + v + '</td>';
+ });
+ tableHtml += '</tbody></table>';
+ $(tableHtml).appendTo(tableDiv);
+ }
+
+ // Reload the page.
+ function load() {
+ var endTime = $('#date').datepicker('getDate').getTime();
+ endTime = endTime + (ONE_DAY / MICRO_PER_MILLI) - 1;
+ var filterVal = $('#outlier-select').val();
+ var ctx = '${pageContext.request.contextPath}';
+ var link = ctx + '/show_graph?profilingPoint=${profilingPointName}' +
+ '&testName=${testName}' +
+ '&endTime=' + (endTime * MICRO_PER_MILLI) +
+ '&filterVal=' + filterVal;
+ if ($('#device-select').prop('selectedIndex') > 1) {
+ link += '&device=' + $('#device-select').val();
+ }
+ window.open(link,'_self');
+ }
+ </script>
+ <div id='download' class='fixed-action-btn'>
+ <a id='b' class='btn-floating btn-large red waves-effect waves-light'>
+ <i class='large material-icons'>file_download</i>
+ </a>
+ </div>
+ <div class='container wide'>
+ <div class='row card'>
+ <div id='header-container' class='valign-wrapper col s12'>
+ <div class='col s3 valign'>
+ <h5>Profiling Point:</h5>
+ </div>
+ <div class='col s9 right-align valign'>
+ <h5 class='profiling-name truncate'>${profilingPointName}</h5>
+ </div>
+ </div>
+ <div id='date-container' class='col s12'>
+ <c:set var='offset' value='${showFilterDropdown ? 0 : 2}' />
+ <c:if test='${showFilterDropdown}'>
+ <div id='outlier-select-wrapper' class='col s2'>
+ <select id='outlier-select'>
+ <option value='-1' ${filterVal eq -1 ? 'selected' : ''}>Show outliers</option>
+ <option value='0' ${filterVal eq 0 ? 'selected' : ''}>Filter outliers (1%)</option>
+ <option value='1' ${filterVal eq 1 ? 'selected' : ''}>Filter outliers (2%)</option>
+ <option value='2' ${filterVal eq 2 ? 'selected' : ''}>Filter outliers (5%)</option>
+ </select>
+ </div>
+ </c:if>
+ <div id='device-select-wrapper' class='input-field col s5 m3 offset-m${offset + 4} offset-s${offset}'>
+ <select id='device-select'>
+ <option value='' disabled>Select device</option>
+ <option value='0' ${empty selectedDevice ? 'selected' : ''}>All Devices</option>
+ <c:forEach items='${devices}' var='device' varStatus='loop'>
+ <option value=${device} ${selectedDevice eq device ? 'selected' : ''}>${device}</option>
+ </c:forEach>
+ </select>
+ </div>
+ <input type='text' id='date' name='date' class='col s4 m2'>
+ <a id='load' class='btn-floating btn-medium red right waves-effect waves-light'>
+ <i class='medium material-icons'>cached</i>
+ </a>
+ </div>
+ </div>
+ <div id='profiling-container'>
+ </div>
+ <c:if test='${not empty error}'>
+ <div id='error-container' class='row card'>
+ <div class='col s10 offset-s1 center-align'>
+ <!-- Error in case of profiling data is missing -->
+ <h5>${error}</h5>
+ </div>
+ </div>
+ </c:if>
+ </div>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
diff --git a/src/main/webapp/WEB-INF/jsp/show_performance_digest.jsp b/src/main/webapp/WEB-INF/jsp/show_performance_digest.jsp
new file mode 100644
index 0000000..224d847
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/show_performance_digest.jsp
@@ -0,0 +1,100 @@
+<%--
+ ~ Copyright (c) 2016 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<html>
+ <%@ include file="header.jsp" %>
+ <link type='text/css' href='/css/datepicker.css' rel='stylesheet'>
+ <link type='text/css' href='/css/show_performance_digest.css' rel='stylesheet'>
+ <link rel='stylesheet' href='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.css'>
+ <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script>
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
+ <body>
+ <script type='text/javascript'>
+ ONE_DAY = 86400000000;
+ MICRO_PER_MILLI = 1000;
+
+ function load() {
+ var time = $('#date').datepicker('getDate').getTime() - 1;
+ time = time * MICRO_PER_MILLI + ONE_DAY; // end of day
+ var ctx = '${pageContext.request.contextPath}';
+ var link = ctx + '/show_performance_digest?profilingPoint=${profilingPointName}' +
+ '&testName=${testName}' +
+ '&startTime=' + time;
+ if ($('#device-select').prop('selectedIndex') > 1) {
+ link += '&device=' + $('#device-select').val();
+ }
+ window.open(link,'_self');
+ }
+
+ $(function() {
+ var date = $('#date').datepicker({
+ showAnim: "slideDown",
+ maxDate: new Date()
+ });
+ date.datepicker('setDate', new Date(${startTime} / MICRO_PER_MILLI));
+ $('#load').click(load);
+
+ $('.date-label').each(function(i) {
+ var label = $(this);
+ label.html(moment(parseInt(label.html())).format('M/D/YY'));
+ });
+ $('select').material_select();
+ });
+ </script>
+ <div class='wide container'>
+ <div class='row card'>
+ <div id='header-container' class='col s12'>
+ <div class='col s12'>
+ <h4>Daily Performance Digest</h4>
+ </div>
+ <div id='device-select-wrapper' class='input-field col s6 m3 offset-m6'>
+ <select id='device-select'>
+ <option value='' disabled>Select device</option>
+ <option value='0' ${empty selectedDevice ? 'selected' : ''}>All Devices</option>
+ <c:forEach items='${devices}' var='device' varStatus='loop'>
+ <option value=${device} ${selectedDevice eq device ? 'selected' : ''}>${device}</option>
+ </c:forEach>
+ </select>
+ </div>
+ <input type='text' id='date' name='date' class='col s5 m2'>
+ <a id='load' class='btn-floating btn-medium red right waves-effect waves-light'>
+ <i class='medium material-icons'>cached</i>
+ </a>
+ </div>
+ </div>
+ <div class='row'>
+ <c:forEach items='${tables}' var='table' varStatus='loop'>
+ <div class='col s12 card summary'>
+ <div class='col s3 valign'>
+ <h5>Profiling Point:</h5>
+ </div>
+ <div class='col s9 right-align valign'>
+ <h5 class="profiling-name truncate">${tableTitles[loop.index]}</h5>
+ </div>
+ ${table}
+ <span class='profiling-subtitle'>
+ ${tableSubtitles[loop.index]}
+ </span>
+ </div>
+ </c:forEach>
+ </div>
+ </div>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
diff --git a/src/main/webapp/WEB-INF/jsp/show_plan_release.jsp b/src/main/webapp/WEB-INF/jsp/show_plan_release.jsp
new file mode 100644
index 0000000..b202d04
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/show_plan_release.jsp
@@ -0,0 +1,109 @@
+<%--
+ ~ Copyright (c) 2017 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<html>
+ <%@ include file="header.jsp" %>
+ <link rel='stylesheet' href='/css/show_plan_release.css'>
+ <link rel='stylesheet' href='/css/plan_runs.css'>
+ <link rel='stylesheet' href='/css/search_header.css'>
+ <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script>
+ <script src='js/time.js'></script>
+ <script src='js/plan_runs.js'></script>
+ <script src='js/search_header.js'></script>
+ <script type='text/javascript'>
+ var search;
+ $(document).ready(function() {
+ // disable buttons on load
+ if (!${hasNewer}) {
+ $('#newer-button').toggleClass('disabled');
+ }
+ if (!${hasOlder}) {
+ $('#older-button').toggleClass('disabled');
+ }
+
+ $('#newer-button').click(prev);
+ $('#older-button').click(next);
+ search = $('#filter-bar').createSearchHeader('Plan: ', '${plan}', refresh);
+ search.addFilter('Branch', 'branch', {
+ corpus: ${branches}
+ }, ${branch});
+ search.addFilter('Device', 'device', {
+ corpus: ${devices}
+ }, ${device});
+ search.addFilter('Device Build ID', 'deviceBuildId', {}, ${deviceBuildId});
+ search.addRunTypeCheckboxes(${showPresubmit}, ${showPostsubmit});
+ search.display();
+ $('#release-container').showPlanRuns(${planRuns});
+ });
+
+ // view older data
+ function next() {
+ if($(this).hasClass('disabled')) return;
+ var endTime = ${startTime};
+ var link = '${pageContext.request.contextPath}' +
+ '/show_plan_release?plan=${plan}&endTime=' + endTime +
+ search.args();
+ if (${unfiltered}) {
+ link += '&unfiltered=';
+ }
+ window.open(link,'_self');
+ }
+
+ // view newer data
+ function prev() {
+ if($(this).hasClass('disabled')) return;
+ var startTime = ${endTime};
+ var link = '${pageContext.request.contextPath}' +
+ '/show_plan_release?plan=${plan}&startTime=' + startTime +
+ search.args();
+ if (${unfiltered}) {
+ link += '&unfiltered=';
+ }
+ window.open(link,'_self');
+ }
+
+ // refresh the page to see the runs matching the specified filter
+ function refresh() {
+ var link = '${pageContext.request.contextPath}' +
+ '/show_plan_release?plan=${plan}' + search.args();
+ if (${unfiltered}) {
+ link += '&unfiltered=';
+ }
+ window.open(link,'_self');
+ }
+ </script>
+
+ <body>
+ <div class='wide container'>
+ <div id='filter-bar'></div>
+ <div class='row' id='release-container'></div>
+ <div id='newer-wrapper' class='page-button-wrapper fixed-action-btn'>
+ <a id='newer-button' class='btn-floating btn red waves-effect'>
+ <i class='large material-icons'>keyboard_arrow_left</i>
+ </a>
+ </div>
+ <div id='older-wrapper' class='page-button-wrapper fixed-action-btn'>
+ <a id='older-button' class='btn-floating btn red waves-effect'>
+ <i class='large material-icons'>keyboard_arrow_right</i>
+ </a>
+ </div>
+ </div>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
diff --git a/src/main/webapp/WEB-INF/jsp/show_plan_run.jsp b/src/main/webapp/WEB-INF/jsp/show_plan_run.jsp
new file mode 100644
index 0000000..491703a
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/show_plan_run.jsp
@@ -0,0 +1,131 @@
+<%--
+ ~ Copyright (c) 2017 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<html>
+ <%@ include file="header.jsp" %>
+ <link type='text/css' href='/css/show_test_runs_common.css' rel='stylesheet'>
+ <link type='text/css' href='/css/test_results.css' rel='stylesheet'>
+ <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
+ <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script>
+ <script src='js/time.js'></script>
+ <script src='js/test_results.js'></script>
+ <script type='text/javascript'>
+ google.charts.load('current', {'packages':['table', 'corechart']});
+ google.charts.setOnLoadCallback(drawPieChart);
+
+ $(document).ready(function() {
+ $('#test-results-container').showTests(${testRuns}, true);
+ });
+
+ // to draw pie chart
+ function drawPieChart() {
+ var topBuildResultCounts = ${topBuildResultCounts};
+ if (topBuildResultCounts.length < 1) {
+ return;
+ }
+ var resultNames = ${resultNamesJson};
+ var rows = resultNames.map(function(res, i) {
+ nickname = res.replace('TEST_CASE_RESULT_', '').replace('_', ' ')
+ .trim().toLowerCase();
+ return [nickname, parseInt(topBuildResultCounts[i])];
+ });
+ rows.unshift(['Result', 'Count']);
+
+ // Get CSS color definitions (or default to white)
+ var colors = resultNames.map(function(res) {
+ return $('.' + res).css('background-color') || 'white';
+ });
+
+ var data = google.visualization.arrayToDataTable(rows);
+ var options = {
+ is3D: false,
+ colors: colors,
+ fontName: 'Roboto',
+ fontSize: '14px',
+ legend: 'none',
+ tooltip: {showColorCode: true, ignoreBounds: true},
+ chartArea: {height: '90%'}
+ };
+
+ var chart = new google.visualization.PieChart(document.getElementById('pie-chart-div'));
+ chart.draw(data, options);
+ }
+ </script>
+
+ <body>
+ <div class='wide container'>
+ <div class='row'>
+ <div class='col s7'>
+ <div class='col s12 card center-align'>
+ <div id='legend-wrapper'>
+ <c:forEach items='${resultNames}' var='res'>
+ <div class='center-align legend-entry'>
+ <c:set var='trimmed' value='${fn:replace(res, "TEST_CASE_RESULT_", "")}'/>
+ <c:set var='nickname' value='${fn:replace(trimmed, "_", " ")}'/>
+ <label for='${res}'>${nickname}</label>
+ <div id='${res}' class='${res} legend-bubble'></div>
+ </div>
+ </c:forEach>
+ </div>
+ </div>
+ <div id='profiling-container' class='col s12'>
+ <c:choose>
+ <c:when test='${empty profilingPointNames}'>
+ <div id='error-div' class='center-align card'><h5>${error}</h5></div>
+ </c:when>
+ <c:otherwise>
+ <ul id='profiling-body' class='collapsible' data-collapsible='accordion'>
+ <li>
+ <div class='collapsible-header'><i class='material-icons'>timeline</i>Profiling Graphs</div>
+ <div class='collapsible-body'>
+ <ul id='profiling-list' class='collection'>
+ <c:forEach items='${profilingPointNames}' var='pt'>
+ <c:set var='profPointArgs' value='testName=${testName}&profilingPoint=${pt}'/>
+ <c:set var='timeArgs' value='endTime=${endTime}'/>
+ <a href='/show_graph?${profPointArgs}&${timeArgs}'
+ class='collection-item profiling-point-name'>${pt}
+ </a>
+ </c:forEach>
+ </ul>
+ </div>
+ </li>
+ <li>
+ <a class='collapsible-link' href='/show_performance_digest?testName=${testName}'>
+ <div class='collapsible-header'><i class='material-icons'>toc</i>Performance Digest</div>
+ </a>
+ </li>
+ </ul>
+ </c:otherwise>
+ </c:choose>
+ </div>
+ </div>
+ <div class='col s5 valign-wrapper'>
+ <!-- pie chart -->
+ <div id='pie-chart-wrapper' class='col s12 valign center-align card'>
+ <div id='pie-chart-div'></div>
+ </div>
+ </div>
+ </div>
+
+ <div class='col s12' id='test-results-container'>
+ </div>
+ </div>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
diff --git a/src/main/webapp/WEB-INF/jsp/show_release.jsp b/src/main/webapp/WEB-INF/jsp/show_release.jsp
new file mode 100644
index 0000000..b3da353
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/show_release.jsp
@@ -0,0 +1,45 @@
+<%--
+ ~ Copyright (c) 2017 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<html>
+ <link rel='stylesheet' href='/css/show_release.css'>
+ <%@ include file='header.jsp' %>
+ <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js'></script>
+ <body>
+ <div class='container'>
+ <div class='row'>
+ <div class='col s12'>
+ <h4 id='section-header'>Test Plans</h4>
+ </div>
+ </div>
+ <div class='row' id='options'>
+ <c:forEach items='${planNames}' var='plan'>
+ <div>
+ <a href='/show_plan_release?plan=${plan}'>
+ <div class='col s12 card hoverable option valign-wrapper waves-effect'>
+ <span class='entry valign'>${plan}</span>
+ </div>
+ </a>
+ </div>
+ </c:forEach>
+ </div>
+ </div>
+ <%@ include file='footer.jsp' %>
+ </body>
+</html>
diff --git a/src/main/webapp/WEB-INF/jsp/show_table.jsp b/src/main/webapp/WEB-INF/jsp/show_table.jsp
new file mode 100644
index 0000000..be71ee8
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/show_table.jsp
@@ -0,0 +1,340 @@
+<%--
+ ~ Copyright (c) 2016 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<html>
+ <%@ include file="header.jsp" %>
+ <link type='text/css' href='/css/show_table.css' rel='stylesheet'>
+ <link type='text/css' href='/css/show_test_runs_common.css' rel='stylesheet'>
+ <link type='text/css' href='/css/search_header.css' rel='stylesheet'>
+ <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
+ <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script>
+ <script src='js/search_header.js'></script>
+ <script type='text/javascript'>
+ google.charts.load('current', {'packages':['table', 'corechart']});
+ google.charts.setOnLoadCallback(drawGridTable);
+ google.charts.setOnLoadCallback(activateLogLinks);
+ google.charts.setOnLoadCallback(drawPieChart);
+ google.charts.setOnLoadCallback(function() {
+ $('.gradient').removeClass('gradient');
+ });
+
+ var search;
+
+ $(document).ready(function() {
+ search = $('#filter-bar').createSearchHeader('Module: ', '${testName}', refresh);
+ search.addFilter('Branch', 'branch', {
+ corpus: ${branches}
+ }, ${branch});
+ search.addFilter('Device', 'device', {
+ corpus: ${devices}
+ }, ${device});
+ search.addFilter('Device Build ID', 'deviceBuildId', {}, ${deviceBuildId});
+ search.addFilter('Test Build ID', 'testBuildId', {}, ${testBuildId});
+ search.addFilter('Host', 'hostname', {}, ${hostname});
+ search.addFilter('Passing Count', 'passing', {
+ type: 'number',
+ width: 's2'
+ }, ${passing});
+ search.addFilter('Non-Passing Count', 'nonpassing', {
+ type: 'number',
+ width: 's2'
+ }, ${nonpassing});
+ search.addRunTypeCheckboxes(${showPresubmit}, ${showPostsubmit});
+ search.display();
+
+ // disable buttons on load
+ if (!${hasNewer}) {
+ $('#newer-button').toggleClass('disabled');
+ }
+ if (!${hasOlder}) {
+ $('#older-button').toggleClass('disabled');
+ }
+ $('#treeLink').click(function() {
+ window.open('/show_tree?testName=${testName}', '_self');
+ });
+ $('#newer-button').click(prev);
+ $('#older-button').click(next);
+ });
+
+ // Actives the log links to display the log info modal when clicked.
+ function activateLogLinks() {
+ $('.info-btn').click(function(e) {
+ showLog(${logInfoMap}[$(this).data('col')]);
+ });
+ }
+
+ /** Displays a modal window with the specified log entries.
+ *
+ * @param logEntries Array of string arrays. Each entry in the outer array
+ * must contain (1) name string, and (2) url string.
+ */
+ function showLog(logEntries) {
+ if (!logEntries || logEntries.length == 0) return;
+
+ var logList = $('<ul class="collection"></ul>');
+ var entries = logEntries.reduce(function(acc, entry) {
+ if (!entry || entry.length == 0) return acc;
+ var link = '<a href="' + entry[1] + '"';
+ link += 'class="collection-item">' + entry[0] + '</li>';
+ return acc + link;
+ }, '');
+ logList.html(entries);
+ var infoContainer = $('#info-modal>.modal-content>.info-container');
+ infoContainer.empty();
+ logList.appendTo(infoContainer);
+ $('#info-modal').openModal();
+ }
+
+ // refresh the page to see the selected test types (pre-/post-submit)
+ function refresh() {
+ if($(this).hasClass('disabled')) return;
+ var link = '${pageContext.request.contextPath}' +
+ '/show_table?testName=${testName}' + search.args();
+ if (${unfiltered}) {
+ link += '&unfiltered=';
+ }
+ window.open(link,'_self');
+ }
+
+ // view older data
+ function next() {
+ if($(this).hasClass('disabled')) return;
+ var endTime = ${startTime};
+ var link = '${pageContext.request.contextPath}' +
+ '/show_table?testName=${testName}&endTime=' + endTime +
+ search.args();
+ if (${unfiltered}) {
+ link += '&unfiltered=';
+ }
+ window.open(link,'_self');
+ }
+
+ // view newer data
+ function prev() {
+ if($(this).hasClass('disabled')) return;
+ var startTime = ${endTime};
+ var link = '${pageContext.request.contextPath}' +
+ '/show_table?testName=${testName}&startTime=' + startTime +
+ search.args();
+ if (${unfiltered}) {
+ link += '&unfiltered=';
+ }
+ window.open(link,'_self');
+ }
+
+ // to draw pie chart
+ function drawPieChart() {
+ var topBuildResultCounts = ${topBuildResultCounts};
+ if (topBuildResultCounts.length < 1) {
+ return;
+ }
+ var resultNames = ${resultNamesJson};
+ var rows = resultNames.map(function(res, i) {
+ nickname = res.replace('TEST_CASE_RESULT_', '').replace('_', ' ')
+ .trim().toLowerCase();
+ return [nickname, parseInt(topBuildResultCounts[i])];
+ });
+ rows.unshift(['Result', 'Count']);
+
+ // Get CSS color definitions (or default to white)
+ var colors = resultNames.map(function(res) {
+ return $('.' + res).css('background-color') || 'white';
+ });
+
+ var data = google.visualization.arrayToDataTable(rows);
+ var options = {
+ is3D: false,
+ colors: colors,
+ fontName: 'Roboto',
+ fontSize: '14px',
+ legend: 'none',
+ tooltip: {showColorCode: true, ignoreBounds: true},
+ chartArea: {height: '90%'}
+ };
+
+ var chart = new google.visualization.PieChart(document.getElementById('pie-chart-div'));
+ chart.draw(data, options);
+ }
+
+ // table for grid data
+ function drawGridTable() {
+ var data = new google.visualization.DataTable();
+
+ // Add column headers.
+ headerRow = ${headerRow};
+ headerRow.forEach(function(d, i) {
+ var classNames = 'table-header-content';
+ if (i == 0) classNames += ' table-header-legend';
+ data.addColumn('string', '<span class="' + classNames + '">' +
+ d + '</span>');
+ });
+
+ var timeGrid = ${timeGrid};
+ var durationGrid = ${durationGrid};
+ var summaryGrid = ${summaryGrid};
+ var resultsGrid = ${resultsGrid};
+
+ // Format time grid to a formatted date
+ timeGrid = timeGrid.map(function(row) {
+ return row.map(function(cell, j) {
+ if (j == 0) return cell;
+ var time = moment(cell/1000);
+ // If today, don't display the date
+ if (time.isSame(moment(), 'd')) {
+ return time.format('H:mm:ssZZ');
+ } else {
+ return time.format('M/D/YY H:mm:ssZZ');
+ }
+ });
+ });
+
+ // Format duration grid to HH:mm:ss.SSS
+ durationGrid = durationGrid.map(function(row) {
+ return row.map(function(cell, j) {
+ if (j == 0) return cell;
+ return moment.utc(cell/1000).format("HH:mm:ss.SSS");
+ });
+ });
+
+ // add rows to the data.
+ data.addRows(timeGrid);
+ data.addRows(durationGrid);
+ data.addRows(summaryGrid);
+ data.addRows(resultsGrid);
+
+ var table = new google.visualization.Table(document.getElementById('grid-table-div'));
+ var classNames = {
+ headerRow : 'table-header',
+ headerCell : 'table-header-cell'
+ };
+ var options = {
+ showRowNumber: false,
+ alternatingRowStyle: true,
+ allowHtml: true,
+ frozenColumns: 1,
+ cssClassNames: classNames,
+ sort: 'disable'
+ };
+ table.draw(data, options);
+ }
+ </script>
+
+ <body>
+ <div class='wide container'>
+ <div class='row'>
+ <div class='col s12'>
+ <div class='card'>
+ <ul class='tabs'>
+ <li class='tab col s6'><a class='active'>Table</a></li>
+ <li class='tab col s6' id='treeLink'><a>Tree</a></li>
+ </ul>
+ </div>
+ <div id='filter-bar'></div>
+ </div>
+ <div class='col s7'>
+ <div class='col s12 card center-align'>
+ <div id='legend-wrapper'>
+ <c:forEach items='${resultNames}' var='res'>
+ <div class='center-align legend-entry'>
+ <c:set var='trimmed' value='${fn:replace(res, "TEST_CASE_RESULT_", "")}'/>
+ <c:set var='nickname' value='${fn:replace(trimmed, "_", " ")}'/>
+ <label for='${res}'>${nickname}</label>
+ <div id='${res}' class='${res} legend-bubble'></div>
+ </div>
+ </c:forEach>
+ </div>
+ </div>
+ <div id='profiling-container' class='col s12'>
+ <c:choose>
+ <c:when test='${empty profilingPointNames}'>
+ <div id='error-div' class='center-align card'><h5>${error}</h5></div>
+ </c:when>
+ <c:otherwise>
+ <ul id='profiling-body' class='collapsible' data-collapsible='accordion'>
+ <li>
+ <div class='collapsible-header'><i class='material-icons'>timeline</i>Profiling Graphs</div>
+ <div class='collapsible-body'>
+ <ul id='profiling-list' class='collection'>
+ <c:forEach items='${profilingPointNames}' var='pt'>
+ <c:set var='profPointArgs' value='testName=${testName}&profilingPoint=${pt}'/>
+ <c:set var='timeArgs' value='endTime=${endTime}'/>
+ <a href='/show_graph?${profPointArgs}&${timeArgs}'
+ class='collection-item profiling-point-name'>${pt}
+ </a>
+ </c:forEach>
+ </ul>
+ </div>
+ </li>
+ <li>
+ <a class='collapsible-link' href='/show_performance_digest?testName=${testName}'>
+ <div class='collapsible-header'><i class='material-icons'>toc</i>Performance Digest</div>
+ </a>
+ </li>
+ </ul>
+ </c:otherwise>
+ </c:choose>
+ </div>
+ </div>
+ <div class='col s5 valign-wrapper'>
+ <!-- pie chart -->
+ <div id='pie-chart-wrapper' class='col s12 valign center-align card'>
+ <h6 class='pie-chart-title'>Test Status for Device Build ID: ${topBuildId}</h6>
+ <div id='pie-chart-div'></div>
+ </div>
+ </div>
+ </div>
+
+ <div class='col s12'>
+ <div id='chart-holder' class='col s12 card'>
+ <!-- Grid tables-->
+ <div id='grid-table-div'></div>
+ </div>
+ </div>
+ <div id='newer-wrapper' class='page-button-wrapper fixed-action-btn'>
+ <a id='newer-button' class='btn-floating btn red waves-effect'>
+ <i class='large material-icons'>keyboard_arrow_left</i>
+ </a>
+ </div>
+ <div id='older-wrapper' class='page-button-wrapper fixed-action-btn'>
+ <a id='older-button' class='btn-floating btn red waves-effect'>
+ <i class='large material-icons'>keyboard_arrow_right</i>
+ </a>
+ </div>
+ </div>
+ <div id="help-modal" class="modal">
+ <div class="modal-content">
+ <h4>${searchHelpHeader}</h4>
+ <p>${searchHelpBody}</p>
+ </div>
+ <div class="modal-footer">
+ <a href="#!" class="modal-action modal-close waves-effect btn-flat">Close</a>
+ </div>
+ </div>
+ <div id="info-modal" class="modal">
+ <div class="modal-content">
+ <h4>Logs</h4>
+ <div class="info-container"></div>
+ </div>
+ <div class="modal-footer">
+ <a href="#!" class="modal-action modal-close waves-effect btn-flat">Close</a>
+ </div>
+ </div>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
diff --git a/src/main/webapp/WEB-INF/jsp/show_tree.jsp b/src/main/webapp/WEB-INF/jsp/show_tree.jsp
new file mode 100644
index 0000000..8d237a3
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/show_tree.jsp
@@ -0,0 +1,225 @@
+<%--
+ ~ Copyright (c) 2016 Google Inc. All Rights Reserved.
+ ~
+ ~ 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.
+ --%>
+<%@ page contentType='text/html;charset=UTF-8' language='java' %>
+<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %>
+<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
+
+<html>
+ <%@ include file="header.jsp" %>
+ <link type='text/css' href='/css/show_test_runs_common.css' rel='stylesheet'>
+ <link type='text/css' href='/css/test_results.css' rel='stylesheet'>
+ <link rel='stylesheet' href='/css/search_header.css'>
+ <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
+ <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script>
+ <script src='js/search_header.js'></script>
+ <script src='js/time.js'></script>
+ <script src='js/test_results.js'></script>
+ <script type='text/javascript'>
+ google.charts.load('current', {'packages':['table', 'corechart']});
+ google.charts.setOnLoadCallback(drawPieChart);
+
+ var search;
+
+ $(document).ready(function() {
+ search = $('#filter-bar').createSearchHeader('Module: ', '${testName}', refresh);
+ search.addFilter('Branch', 'branch', {
+ corpus: ${branches}
+ }, ${branch});
+ search.addFilter('Device', 'device', {
+ corpus: ${devices}
+ }, ${device});
+ search.addFilter('Device Build ID', 'deviceBuildId', {}, ${deviceBuildId});
+ search.addFilter('Test Build ID', 'testBuildId', {}, ${testBuildId});
+ search.addFilter('Host', 'hostname', {}, ${hostname});
+ search.addFilter('Passing Count', 'passing', {
+ type: 'number',
+ width: 's2'
+ }, ${passing});
+ search.addFilter('Non-Passing Count', 'nonpassing', {
+ type: 'number',
+ width: 's2'
+ }, ${nonpassing});
+ search.addRunTypeCheckboxes(${showPresubmit}, ${showPostsubmit});
+ search.display();
+
+ // disable buttons on load
+ if (!${hasNewer}) {
+ $('#newer-button').toggleClass('disabled');
+ }
+ if (!${hasOlder}) {
+ $('#older-button').toggleClass('disabled');
+ }
+ $('#tableLink').click(function() {
+ window.open('/show_table?testName=${testName}', '_self');
+ });
+ $('#newer-button').click(prev);
+ $('#older-button').click(next);
+ $('#test-results-container').showTests(${testRuns});
+ });
+
+ // refresh the page to see the selected test types (pre-/post-submit)
+ function refresh() {
+ if($(this).hasClass('disabled')) return;
+ var link = '${pageContext.request.contextPath}' +
+ '/show_tree?testName=${testName}' + search.args();
+ if (${unfiltered}) {
+ link += '&unfiltered=';
+ }
+ window.open(link,'_self');
+ }
+
+ // view older data
+ function next() {
+ if($(this).hasClass('disabled')) return;
+ var endTime = ${startTime};
+ var link = '${pageContext.request.contextPath}' +
+ '/show_tree?testName=${testName}&endTime=' + endTime +
+ search.args();
+ if (${unfiltered}) {
+ link += '&unfiltered=';
+ }
+ window.open(link,'_self');
+ }
+
+ // view newer data
+ function prev() {
+ if($(this).hasClass('disabled')) return;
+ var startTime = ${endTime};
+ var link = '${pageContext.request.contextPath}' +
+ '/show_tree?testName=${testName}&startTime=' + startTime +
+ search.args();
+ if (${unfiltered}) {
+ link += '&unfiltered=';
+ }
+ window.open(link,'_self');
+ }
+
+ // to draw pie chart
+ function drawPieChart() {
+ var topBuildResultCounts = ${topBuildResultCounts};
+ if (topBuildResultCounts.length < 1) {
+ return;
+ }
+ var resultNames = ${resultNamesJson};
+ var rows = resultNames.map(function(res, i) {
+ nickname = res.replace('TEST_CASE_RESULT_', '').replace('_', ' ')
+ .trim().toLowerCase();
+ return [nickname, parseInt(topBuildResultCounts[i])];
+ });
+ rows.unshift(['Result', 'Count']);
+
+ // Get CSS color definitions (or default to white)
+ var colors = resultNames.map(function(res) {
+ return $('.' + res).css('background-color') || 'white';
+ });
+
+ var data = google.visualization.arrayToDataTable(rows);
+ var options = {
+ is3D: false,
+ colors: colors,
+ fontName: 'Roboto',
+ fontSize: '14px',
+ legend: 'none',
+ tooltip: {showColorCode: true, ignoreBounds: true},
+ chartArea: {height: '90%'}
+ };
+
+ var chart = new google.visualization.PieChart(document.getElementById('pie-chart-div'));
+ chart.draw(data, options);
+ }
+ </script>
+
+ <body>
+ <div class='wide container'>
+ <div class='row'>
+ <div class='col s12'>
+ <div class='card'>
+ <ul class='tabs'>
+ <li class='tab col s6' id='tableLink'><a>Table</a></li>
+ <li class='tab col s6'><a class='active'>Tree</a></li>
+ </ul>
+ </div>
+ <div id='filter-bar'></div>
+ </div>
+ <div class='col s7'>
+ <div class='col s12 card center-align'>
+ <div id='legend-wrapper'>
+ <c:forEach items='${resultNames}' var='res'>
+ <div class='center-align legend-entry'>
+ <c:set var='trimmed' value='${fn:replace(res, "TEST_CASE_RESULT_", "")}'/>
+ <c:set var='nickname' value='${fn:replace(trimmed, "_", " ")}'/>
+ <label for='${res}'>${nickname}</label>
+ <div id='${res}' class='${res} legend-bubble'></div>
+ </div>
+ </c:forEach>
+ </div>
+ </div>
+ <div id='profiling-container' class='col s12'>
+ <c:choose>
+ <c:when test='${empty profilingPointNames}'>
+ <div id='error-div' class='center-align card'><h5>${error}</h5></div>
+ </c:when>
+ <c:otherwise>
+ <ul id='profiling-body' class='collapsible' data-collapsible='accordion'>
+ <li>
+ <div class='collapsible-header'><i class='material-icons'>timeline</i>Profiling Graphs</div>
+ <div class='collapsible-body'>
+ <ul id='profiling-list' class='collection'>
+ <c:forEach items='${profilingPointNames}' var='pt'>
+ <c:set var='profPointArgs' value='testName=${testName}&profilingPoint=${pt}'/>
+ <c:set var='timeArgs' value='endTime=${endTime}'/>
+ <a href='/show_graph?${profPointArgs}&${timeArgs}'
+ class='collection-item profiling-point-name'>${pt}
+ </a>
+ </c:forEach>
+ </ul>
+ </div>
+ </li>
+ <li>
+ <a class='collapsible-link' href='/show_performance_digest?testName=${testName}'>
+ <div class='collapsible-header'><i class='material-icons'>toc</i>Performance Digest</div>
+ </a>
+ </li>
+ </ul>
+ </c:otherwise>
+ </c:choose>
+ </div>
+ </div>
+ <div class='col s5 valign-wrapper'>
+ <!-- pie chart -->
+ <div id='pie-chart-wrapper' class='col s12 valign center-align card'>
+ <h6 class='pie-chart-title'>${topBuildId}</h6>
+ <div id='pie-chart-div'></div>
+ </div>
+ </div>
+ </div>
+
+ <div class='col s12' id='test-results-container'>
+ </div>
+ <div id='newer-wrapper' class='page-button-wrapper fixed-action-btn'>
+ <a id='newer-button' class='btn-floating btn red waves-effect'>
+ <i class='large material-icons'>keyboard_arrow_left</i>
+ </a>
+ </div>
+ <div id='older-wrapper' class='page-button-wrapper fixed-action-btn'>
+ <a id='older-button' class='btn-floating btn red waves-effect'>
+ <i class='large material-icons'>keyboard_arrow_right</i>
+ </a>
+ </div>
+ </div>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..e5ed62c
--- /dev/null
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,197 @@
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
+<!--
+Copyright 2016 Google Inc. All Rights Reserved.
+
+ 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.
+-->
+
+<servlet>
+ <servlet-name>dashboard_main</servlet-name>
+ <servlet-class>com.android.vts.servlet.DashboardMainServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>show_release</servlet-name>
+ <servlet-class>com.android.vts.servlet.ShowReleaseServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>show_coverage_overview</servlet-name>
+ <servlet-class>com.android.vts.servlet.ShowCoverageOverviewServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>show_tree</servlet-name>
+ <servlet-class>com.android.vts.servlet.ShowTreeServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>show_table</servlet-name>
+ <servlet-class>com.android.vts.servlet.ShowTableServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>show_graph</servlet-name>
+ <servlet-class>com.android.vts.servlet.ShowGraphServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>show_plan_release</servlet-name>
+ <servlet-class>com.android.vts.servlet.ShowPlanReleaseServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>show_plan_run</servlet-name>
+ <servlet-class>com.android.vts.servlet.ShowPlanRunServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>show_performance_digest</servlet-name>
+ <servlet-class>com.android.vts.servlet.ShowPerformanceDigestServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>show_coverage</servlet-name>
+ <servlet-class>com.android.vts.servlet.ShowCoverageServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>datastore</servlet-name>
+ <servlet-class>com.android.vts.api.DatastoreRestServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>test_run</servlet-name>
+ <servlet-class>com.android.vts.api.TestRunRestServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>favorites</servlet-name>
+ <servlet-class>com.android.vts.api.UserFavoriteRestServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>bigtable_legacy</servlet-name>
+ <servlet-class>com.android.vts.api.BigtableLegacyJsonServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>vts_alert_job</servlet-name>
+ <servlet-class>com.android.vts.servlet.VtsAlertJobServlet</servlet-class>
+</servlet>
+
+<servlet>
+ <servlet-name>vts_performance_job</servlet-name>
+ <servlet-class>com.android.vts.servlet.VtsPerformanceJobServlet</servlet-class>
+</servlet>
+
+<servlet-mapping>
+ <servlet-name>dashboard_main</servlet-name>
+ <url-pattern>/</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>show_release</servlet-name>
+ <url-pattern>/show_release/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>show_coverage_overview</servlet-name>
+ <url-pattern>/show_coverage_overview/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>show_tree</servlet-name>
+ <url-pattern>/show_tree/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>show_table</servlet-name>
+ <url-pattern>/show_table/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>show_graph</servlet-name>
+ <url-pattern>/show_graph/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>show_plan_release</servlet-name>
+ <url-pattern>/show_plan_release/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>show_plan_run</servlet-name>
+ <url-pattern>/show_plan_run/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>show_performance_digest</servlet-name>
+ <url-pattern>/show_performance_digest/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>show_coverage</servlet-name>
+ <url-pattern>/show_coverage/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>bigtable_legacy</servlet-name>
+ <url-pattern>/api/bigtable/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>datastore</servlet-name>
+ <url-pattern>/api/datastore/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>test_run</servlet-name>
+ <url-pattern>/api/test_run/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>favorites</servlet-name>
+ <url-pattern>/api/favorites/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>vts_alert_job</servlet-name>
+ <url-pattern>/cron/vts_alert_job/*</url-pattern>
+</servlet-mapping>
+
+<servlet-mapping>
+ <servlet-name>vts_performance_job</servlet-name>
+ <url-pattern>/cron/vts_performance_job/*</url-pattern>
+</servlet-mapping>
+
+<security-constraint>
+ <web-resource-collection>
+ <web-resource-name>cron</web-resource-name>
+ <url-pattern>/cron/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>admin</role-name>
+ </auth-constraint>
+</security-constraint>
+
+<security-constraint>
+ <web-resource-collection>
+ <web-resource-name>all</web-resource-name>
+ <url-pattern>/show_*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>*</role-name>
+ </auth-constraint>
+</security-constraint>
+</web-app>
diff --git a/src/main/webapp/css/common.css b/src/main/webapp/css/common.css
new file mode 100644
index 0000000..974f129
--- /dev/null
+++ b/src/main/webapp/css/common.css
@@ -0,0 +1,25 @@
+/* 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.
+*/
+
+.container {
+ min-height: 80%;
+}
+
+@media only screen and (min-width: 993px) {
+ .wide.container {
+ width: 80%;
+ max-width: 1600px;
+ }
+}
diff --git a/src/main/webapp/css/dashboard_main.css b/src/main/webapp/css/dashboard_main.css
new file mode 100644
index 0000000..e6e899f
--- /dev/null
+++ b/src/main/webapp/css/dashboard_main.css
@@ -0,0 +1,109 @@
+/* Copyright (C) 2016 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.
+*/
+
+#edit-button-wrapper {
+ bottom: 25px;
+ right: 25px;
+}
+
+.input-field {
+ margin-bottom: 50px;
+}
+
+#add-button-wrapper {
+ margin-top: 10px;
+ height: 61px;
+}
+
+.btn-flat.clear-button {
+ margin-top: 8px;
+ user-select: none;
+ color: grey;
+}
+
+.row .col.card.option {
+ padding: 6px 15px 6px 15px;
+ margin: 5px 0;
+ border-radius: 25px;
+}
+
+#error-container {
+ padding-top: 50px;
+ padding-bottom: 50px;
+}
+
+.entry {
+ font-size: 20px;
+ font-weight: 300;
+ position: relative;
+}
+
+.indicator {
+ color: white;
+ font-size: 12px;
+ font-weight: bold;
+ padding: 1px 6px;
+ position: absolute;
+ right: 0;
+ min-width: 40px;
+ border-radius: 10px;
+ margin-top: 5px;
+}
+
+#show-button {
+ border-radius: 100px;
+}
+
+#show-button-arrow {
+ margin-left: 3px;
+}
+
+#section-header {
+ cursor: default;
+ user-select: none;
+ color: #ee6e73;
+}
+
+#section-header:after {
+ border: 1px solid #ee6e73;
+ margin-top: 10px;
+ margin-bottom: 0;
+ display: block;
+ content: " ";
+}
+
+.ui-menu {
+ overflow-y: auto;
+ z-index: 100;
+ max-height: 50%;
+}
+
+.ui-menu-item {
+ font-size: 16px;
+ padding: 4px 10px;
+ transition: background-color .25s;
+}
+
+.ui-menu-item:hover {
+ background-color: #e0f2f1;
+}
+
+.ui-menu-item:active {
+ background-color: #b2dfdb;
+}
+
+.ui-helper-hidden-accessible {
+ display: none;
+}
diff --git a/src/main/webapp/css/datepicker.css b/src/main/webapp/css/datepicker.css
new file mode 100644
index 0000000..b98dd80
--- /dev/null
+++ b/src/main/webapp/css/datepicker.css
@@ -0,0 +1,70 @@
+/* Copyright (C) 2016 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.
+*/
+.ui-datepicker table {
+ font-family: Roboto !important;
+ font-size: 13px !important;
+ white-space: nowrap !important;
+}
+
+#ui-datepicker-div {
+ font-family: "Roboto", sans-serif;
+ padding: 0;
+}
+
+.ui-corner-all {
+ border-bottom-right-radius: 0 !important;
+ border-bottom-left-radius: 0 !important;
+ border-top-right-radius: 0 !important;
+ border-top-left-radius: 0 !important;
+}
+
+.ui-datepicker td span.ui-state-default, .ui-datepicker td a.ui-state-default {
+ text-align: center;
+ padding: 0.7em 0.4em;
+ border: none;
+ border-radius: 10em;
+ background: none;
+}
+
+.ui-datepicker td span.ui-state-hover, .ui-datepicker td a.ui-state-hover {
+ background: #e0f2f1;
+}
+
+.ui-datepicker td span.ui-state-active, .ui-datepicker td a.ui-state-active {
+ color: white;
+ font-weight: 600;
+ background: #009688;
+}
+
+.ui-datepicker-header.ui-widget-header.ui-helper-clearfix.ui-corner-all {
+ background: #009688;
+ border: none;
+ color: white;
+}
+
+.ui-datepicker-next.ui-state-hover.ui-datepicker-next-hover {
+ right: 2px;
+ top: 2px;
+}
+
+.ui-datepicker-prev.ui-state-hover.ui-datepicker-prev-hover {
+ left: 2px;
+ top: 2px;
+}
+
+.ui-datepicker-next.ui-corner-all.ui-state-hover, .ui-datepicker-prev.ui-corner-all.ui-state-hover {
+ background: none;
+ border: none;
+}
diff --git a/src/main/webapp/css/navbar.css b/src/main/webapp/css/navbar.css
new file mode 100644
index 0000000..9395d1b
--- /dev/null
+++ b/src/main/webapp/css/navbar.css
@@ -0,0 +1,69 @@
+/* Copyright (C) 2016 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.
+*/
+nav#navbar {
+ height: auto;
+ margin-bottom: 30px;
+ user-select: none;
+}
+nav#navbar .nav-wrapper {
+ height: auto;
+}
+nav#navbar ul.nav-list {
+ display: inline-block;
+}
+nav#navbar ul li {
+ transition: background-color .3s;
+ float: left;
+ padding: 0;
+}
+nav#navbar ul li.active {
+ background-color: rgba(0,0,0,0.1);
+}
+nav#navbar ul li a:hover, nav#navbar ul li.active {
+ background-color: #ea454b;
+}
+nav#navbar ul a.nav-list-item {
+ font-size: 1.2rem;
+}
+nav#navbar #nav-sublist {
+ line-height: 35px;
+ background: white;
+ padding-left: 15px;
+ width: 100%;
+ display: inline-block;
+ position: relative;
+}
+nav#navbar #nav-sublist .breadcrumb.nav-sublist-item {
+ font-size: 15px;
+ font-weight: 400;
+ color: rgba(238, 110, 115, 0.85);
+ line-height: 35px;
+}
+nav#navbar #nav-sublist .breadcrumb.nav-sublist-item:last-child {
+ color: rgb(238, 110, 115);
+ font-weight: 500;
+}
+nav#navbar #nav-sublist .breadcrumb.nav-sublist-item::before {
+ font-size: 22px;
+ color: rgba(238, 110, 115, 0.85);
+ line-height: 35px;
+ margin: 0 5px;
+}
+nav#navbar #dropdown-button {
+ font-style: italic;
+ color: rgba(255, 255, 255, 0.75);
+ margin-left: 0;
+ margin-top: 0;
+}
diff --git a/src/main/webapp/css/plan_runs.css b/src/main/webapp/css/plan_runs.css
new file mode 100644
index 0000000..3c9eeb9
--- /dev/null
+++ b/src/main/webapp/css/plan_runs.css
@@ -0,0 +1,30 @@
+/* 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.
+*/
+.plan-run-metadata {
+ display: inline-block;
+ font-size: 13px;
+ line-height: 16px;
+ padding: 10px;
+}
+.release-entry {
+ border-radius: 5px 5px 10px 10px;
+}
+.counter {
+ color: white;
+ font-size: 12px;
+ font-weight: bold;
+ display: block;
+ border-radius: 0 0 10px 10px;
+} \ No newline at end of file
diff --git a/src/main/webapp/css/search_header.css b/src/main/webapp/css/search_header.css
new file mode 100644
index 0000000..90573e1
--- /dev/null
+++ b/src/main/webapp/css/search_header.css
@@ -0,0 +1,80 @@
+/* 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.
+*/
+.row.card.search-bar {
+ margin-left: 0;
+ margin-right: 0;
+}
+.search-bar .header-wrapper {
+ border-bottom: 1px solid rgb(221, 221, 221);;
+}
+.search-bar .section-header {
+ color: rgb(97, 97, 97);
+ font-weight: 300;
+ padding: 15px 20px 15px;
+ margin: 0;
+ cursor: default;
+ user-select: none;
+ display: inline-block;
+}
+.search-bar .section-header b {
+ color: #ee6e73;
+}
+.search-bar .search-icon-wrapper {
+ text-align: center;
+ display: inline-block;
+ position: absolute;
+ right: 0;
+ height: 57px;
+ width: 57px;
+ cursor: pointer;
+ user-select: none;
+}
+.search-bar .search-icon-wrapper i {
+ line-height: 57px;
+ color: rgb(97, 97, 97);
+}
+.search-bar .search-wrapper .refresh-wrapper a {
+ float: right;
+ margin-top: 17px;
+}
+.search-bar .input-field input[type=text].invalid {
+ color: #F44336;
+}
+.search-bar .search-wrapper .run-type-wrapper {
+ margin: 20px 0;
+}
+.search-bar .search-wrapper .run-type-wrapper [type="checkbox"]+label {
+ margin-right: 35px;
+}
+.search-bar-menu .ui-menu {
+ overflow-y: auto;
+ z-index: 100;
+ max-height: 50%;
+}
+.search-bar-menu .ui-menu-item {
+ font-size: 16px;
+ padding: 4px 10px;
+ transition: background-color .25s;
+}
+.search-bar-menu .ui-menu-item:hover {
+ background-color: #e0f2f1;
+}
+
+.search-bar-menu .ui-menu-item:active {
+ background-color: #b2dfdb;
+}
+.search-bar-menu .ui-helper-hidden-accessible {
+ display: none;
+}
diff --git a/src/main/webapp/css/show_coverage.css b/src/main/webapp/css/show_coverage.css
new file mode 100644
index 0000000..c187fd3
--- /dev/null
+++ b/src/main/webapp/css/show_coverage.css
@@ -0,0 +1,104 @@
+/* Copyright (C) 2016 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.
+*/
+
+.collapsible.popout {
+ margin-bottom: 50px;
+}
+
+.table {
+ font-size: 12px;
+ border: none;
+ width: 100%;
+ word-spacing: 4px;
+ font-family: monospace;
+ white-space: PRE;
+ border-collapse: collapse;
+}
+
+.section-title {
+ margin-left: 24px;
+}
+
+.html-container {
+ padding: 25px 25px;
+}
+
+.login-button {
+ border: 1px solid gray;
+ color: gray;
+ border-radius: 15px;
+ padding: 4px 15px;
+ cursor: pointer;
+}
+
+td {
+ padding: 0;
+}
+
+.count {
+ white-space: nowrap;
+ text-align: right;
+ border-right: 1px solid black;
+ padding-right: 5px;
+}
+
+.line_no {
+ padding-left: 35px;
+ white-space: nowrap;
+ padding-right: 5px;
+ border-right: 1px dotted gray;
+}
+
+.code {
+ padding-left: 10px;
+ width: 99%;
+}
+
+.indicator {
+ display: inline-block;
+ width: 50px;
+ margin-top: 12px;
+ line-height: 18px;
+ border-radius: 10px;
+ padding: 2px 5px;
+ text-align: center;
+ font-size: 12px;
+ font-weight: bold;
+ color: white;
+}
+
+.total-count {
+ margin-top: 12px;
+ margin-right: 8px;
+ padding-right: 5px;
+ line-height: 22px;
+ border-right: 1px solid gray;
+ font-size: 12px;
+ font-weight: bold;
+ color: gray;
+}
+
+.uncovered {
+ background-color: LightPink;
+}
+
+.covered {
+ background-color: LightGreen;
+}
+
+.source-name {
+ margin-top: -25px;
+ padding-left: 45px;
+}
diff --git a/src/main/webapp/css/show_graph.css b/src/main/webapp/css/show_graph.css
new file mode 100644
index 0000000..51e4c04
--- /dev/null
+++ b/src/main/webapp/css/show_graph.css
@@ -0,0 +1,70 @@
+/* Copyright (C) 2016 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.
+*/
+
+#download {
+ bottom: 25px;
+ right: 25px;
+}
+
+#header-container {
+ padding: 50px;
+ padding-bottom: 30px;
+}
+
+#device-select-wrapper {
+ margin-top: 0;
+}
+
+#date-container {
+ padding: 0 50px;
+ padding-bottom: 25px;
+}
+
+#load {
+ margin-top: 5px;
+}
+
+.profiling-name {
+ font-weight: 200;
+ font-style: italic;
+ font-size: 1.4rem
+}
+
+#error-container {
+ padding-top: 25px;
+ padding-bottom: 25px;
+}
+
+.graph-wrapper {
+ padding: 30px;
+}
+
+.graph {
+ height: 500px;
+ padding-bottom: 30px;
+}
+
+.percentile-table {
+ width: auto;
+ margin: auto;
+ margin-top: 20px;
+}
+
+.percentile-table td, th{
+ font-size: 11px;
+ text-align: center;
+ padding: 5px 10px;
+}
+
diff --git a/src/main/webapp/css/show_performance_digest.css b/src/main/webapp/css/show_performance_digest.css
new file mode 100644
index 0000000..5d0c0e6
--- /dev/null
+++ b/src/main/webapp/css/show_performance_digest.css
@@ -0,0 +1,82 @@
+/* Copyright (C) 2016 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.
+*/
+
+#header-container {
+ padding: 25px;
+}
+
+#load {
+ margin-top: 15px;
+}
+
+#device-select-wrapper {
+ margin-top: 9px;
+}
+
+#date {
+ margin-bottom: 0;
+ margin-top: 10px;
+}
+
+div.col.card.summary {
+ padding: 0 20px 20px;
+}
+
+.profiling-name {
+ font-weight: 200;
+ font-style: italic;
+ font-size: 1.4rem
+}
+
+.profiling-subtitle {
+ font-style: italic;
+ font-size: 12px;
+ margin-left: 2px;
+}
+
+.summary table {
+ width: 100%;
+ border-collapse: collapse;
+ border: 1px solid black;
+ font-size: 12px;
+ font-family: Roboto !important;
+}
+
+.summary table td, th {
+ padding: 2px;
+}
+
+.section-label {
+ border: 1px solid black;
+}
+
+.axis-label {
+ border-top: 1px solid lightgray;
+ border-right: 1px solid black;
+ text-align: right;
+}
+
+.cell {
+ border-top: 1px solid lightgray;
+ text-align: right;
+}
+
+.inner-cell {
+ border-right: 1px solid lightgray;
+}
+
+.outer-cell {
+ border-right: 1px solid black;
+}
diff --git a/src/main/webapp/css/show_plan_release.css b/src/main/webapp/css/show_plan_release.css
new file mode 100644
index 0000000..f55b8da
--- /dev/null
+++ b/src/main/webapp/css/show_plan_release.css
@@ -0,0 +1,23 @@
+/* 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.
+*/
+.page-button-wrapper {
+ top: 50%;
+ bottom: auto;
+ padding: 0;
+}
+#newer-wrapper {
+ left: 23px;
+ right: auto;
+}
diff --git a/src/main/webapp/css/show_release.css b/src/main/webapp/css/show_release.css
new file mode 100644
index 0000000..1f1758b
--- /dev/null
+++ b/src/main/webapp/css/show_release.css
@@ -0,0 +1,40 @@
+/* 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.
+*/
+
+.row .col.card.option {
+ padding: 10px 15px 10px 25px;
+ margin: 5px 0;
+ border-radius: 25px;
+}
+.entry {
+ font-size: 20px;
+ font-weight: 300;
+ position: relative;
+}
+#show-button-arrow {
+ margin-left: 3px;
+}
+#section-header {
+ cursor: default;
+ user-select: none;
+ color: #ee6e73;
+}
+#section-header:after {
+ border: 1px solid #ee6e73;
+ margin-top: 10px;
+ margin-bottom: 0;
+ display: block;
+ content: " ";
+}
diff --git a/src/main/webapp/css/show_table.css b/src/main/webapp/css/show_table.css
new file mode 100644
index 0000000..76d4379
--- /dev/null
+++ b/src/main/webapp/css/show_table.css
@@ -0,0 +1,156 @@
+/* Copyright (C) 2016 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.
+*/
+
+table {
+ font-family: Roboto !important;
+ font-size: 13px !important;
+ white-space: nowrap !important;
+}
+.table-header-cell {
+ background-color: white;
+ transition: max-width 1s;
+ max-width: 150px;
+}
+.table-header-cell:hover {
+ transition-delay: 0.5s;
+ max-width: 1000px;
+}
+.table-header-content.table-header-legend {
+ max-width: none;
+}
+.table-header-content {
+ font-weight: initial;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: inline-block;
+ max-width: inherit;
+ width: 100%;
+}
+.page-button-wrapper {
+ top: 50%;
+ bottom: auto;
+ padding: 0;
+}
+#newer-wrapper {
+ left: 23px;
+ right: auto;
+}
+#chart-holder {
+ padding: 30px 5px;
+}
+#pie-chart-div {
+ width: 100%;
+ height: 300px;
+}
+#profiling-container {
+ padding: 0;
+}
+#error-div {
+ padding: 30px 25px;
+}
+#profiling-body {
+ border: none;
+}
+#profiling-list {
+ max-height: 200px;
+ overflow-y: scroll;
+}
+.collapsible-header {
+ user-select: none;
+}
+.collapsible-link {
+ color: inherit;
+}
+.collection a.collection-item.profiling-point-name {
+ color: #616161;
+ font-size: 13px;
+ padding: 2px 0 2px 25px;
+}
+#legend-wrapper {
+ display: inline-block;
+ padding: 10px 15px 12px;
+}
+.btn.inline-btn {
+ border-radius: 50px;
+ height: auto;
+ line-height: inherit;
+ padding: 1px;
+ margin-left: 2px;
+}
+i.material-icons.inline-icon {
+ font-size: inherit;
+}
+a.legend-circle {
+ width: 15px;
+ height: 15px;
+ padding: 0;
+ border-radius: 15px;
+}
+.legend-header-cell {
+ text-transform: capitalize;
+}
+.legend-entry {
+ display: inline-block;
+ margin: 0 5px;
+ min-width: 50px;
+}
+.legend-bubble {
+ border-radius: 20px;
+ height: 20px;
+ width: 20px;
+ margin: 0 auto;
+}
+#pie-chart-wrapper {
+ padding: 25px 0;
+}
+.pie-chart-title {
+ cursor: default;
+}
+div.status-icon {
+ width: 10px;
+ height: 10px;
+ border-radius: 10px;
+ display: inline-block;
+ margin-left: 5px;
+}
+.test-case-status {
+ border-radius: 50px;
+ display: inline-block;
+ height: 100%;
+ width: 100%;
+}
+.test-case-status.width-1 {
+ width: calc(100% - 18px);
+}
+.TEST_CASE_RESULT_PASS {
+ background-color: #7FFF00;
+}
+.TEST_CASE_RESULT_FAIL {
+ background-color: #ff4d4d;
+}
+.TEST_CASE_RESULT_SKIP {
+ background-color: #A8A8A8;
+}
+.TEST_CASE_RESULT_EXCEPTION {
+ background-color: black;
+}
+.TEST_CASE_RESULT_TIMEOUT {
+ background-color: #9900CC;
+}
+.UNKNOWN_RESULT {
+ background-color: white;
+ border: 1px #A8A8A8 solid;
+}
diff --git a/src/main/webapp/css/show_test_runs_common.css b/src/main/webapp/css/show_test_runs_common.css
new file mode 100644
index 0000000..63d5301
--- /dev/null
+++ b/src/main/webapp/css/show_test_runs_common.css
@@ -0,0 +1,136 @@
+/* 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.
+*/
+.page-button-wrapper {
+ top: 50%;
+ bottom: auto;
+ padding: 0;
+}
+#newer-wrapper {
+ left: 23px;
+ right: auto;
+}
+#chart-holder {
+ padding: 30px 5px;
+}
+#pie-chart-div {
+ width: 100%;
+ height: 300px;
+}
+.row .col div.pie-chart-div {
+ width: 100%;
+ height: 255px;
+}
+#profiling-container {
+ padding: 0;
+}
+#error-div {
+ padding: 30px 25px;
+}
+#profiling-body {
+ border: none;
+}
+#profiling-list {
+ max-height: 200px;
+ overflow-y: scroll;
+}
+.collapsible-header {
+ user-select: none;
+}
+.collapsible-link {
+ color: inherit;
+}
+.collection a.collection-item.profiling-point-name {
+ color: #616161;
+ font-size: 13px;
+ padding: 2px 0 2px 25px;
+}
+#legend-wrapper {
+ display: inline-block;
+ padding: 10px 15px 12px;
+}
+.btn.inline-btn {
+ border-radius: 50px;
+ height: auto;
+ line-height: inherit;
+ padding: 1px;
+ margin-left: 2px;
+}
+i.material-icons.inline-icon {
+ font-size: inherit;
+}
+a.legend-circle {
+ width: 15px;
+ height: 15px;
+ padding: 0;
+ border-radius: 15px;
+}
+.legend-header-cell {
+ text-transform: capitalize;
+}
+.legend-entry {
+ display: inline-block;
+ margin: 0 5px;
+ min-width: 50px;
+}
+.legend-bubble {
+ border-radius: 20px;
+ height: 20px;
+ width: 20px;
+ margin: 0 auto;
+}
+#pie-chart-wrapper, .row .col.pie-chart-wrapper {
+ padding: 25px 0;
+}
+.pie-chart-title {
+ cursor: default;
+}
+div.status-icon {
+ width: 10px;
+ height: 10px;
+ border-radius: 10px;
+ display: inline-block;
+ margin-left: 5px;
+}
+.test-case-status {
+ border-radius: 50px;
+ display: inline-block;
+ height: 100%;
+ width: 100%;
+}
+.test-case-status.width-1 {
+ width: calc(100% - 18px);
+}
+.TEST_CASE_RESULT_PASS {
+ background-color: #4CAF50;
+}
+.TEST_CASE_RESULT_FAIL {
+ background-color: #F44336;
+}
+.TEST_CASE_RESULT_SKIP {
+ background-color: #A8A8A8;
+}
+.TEST_CASE_RESULT_EXCEPTION {
+ background-color: black;
+}
+.TEST_CASE_RESULT_TIMEOUT {
+ background-color: #9900CC;
+}
+.UNKNOWN_RESULT {
+ background-color: white;
+ border: 1px #A8A8A8 solid;
+}
+.tabs > div.indicator {
+ height: 3px;
+}
diff --git a/src/main/webapp/css/test_results.css b/src/main/webapp/css/test_results.css
new file mode 100644
index 0000000..f717e79
--- /dev/null
+++ b/src/main/webapp/css/test_results.css
@@ -0,0 +1,78 @@
+/* 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.
+*/
+li.test-run-container.active {
+ border-radius: 0 0 10px 10px;
+}
+.collapsible-header {
+ user-select: none;
+}
+.collapsible-header.disabled {
+ pointer-events: none;
+}
+.collapsible-header.test-run {
+ position: relative;
+}
+.test-run-metadata {
+ font-size: 13px;
+ line-height: 15px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+ position: relative;
+ display: inline-block;
+ cursor: text;
+ user-select: initial;
+}
+.test-results.row {
+ margin: 0;
+ border-radius: 0 0 10px 10px;
+}
+.test-case-container {
+ border: 1px solid lightgray;
+ background: white;
+ padding: 10px;
+ margin-bottom: 25px;
+ max-height: 80%;
+ overflow: auto;
+}
+.indicator {
+ color: white;
+ font-size: 12px;
+ line-height: 20px;
+ font-weight: bold;
+ padding: 1px 6px;
+ margin-top: 10px;
+ min-width: 40px;
+ border-radius: 10px;
+}
+.indicator.padded {
+ margin-right: 5px;
+}
+.material-icons.expand-arrow {
+ right: 3px;
+ bottom: 0px;
+ position: absolute;
+ transition: transform 0.2s;
+}
+.rotate {
+ transform: rotate(-180deg);
+}
+i.material-icons.inline-icon {
+ font-size: inherit;
+}
+.test-run-label {
+ font-size: 18px;
+ line-height: 35px;
+ font-weight: 300;
+}
diff --git a/src/main/webapp/js/plan_runs.js b/src/main/webapp/js/plan_runs.js
new file mode 100644
index 0000000..6898389
--- /dev/null
+++ b/src/main/webapp/js/plan_runs.js
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+(function ($, moment) {
+
+ /**
+ * Display test plan metadata in a vertical popout.
+ * @param container The jquery object in which to insert the plan metadata.
+ * @param metadataList The list of metadata objects to render on the display.
+ */
+ function renderCard(container, entry) {
+ var card = $('<div class="col s12 m6 l4"></div>');
+ card.appendTo(container);
+ var div = $('<div class="hoverable card release-entry"></div>');
+ var startTime = entry.testPlanRun.startTimestamp;
+ var endTime = entry.testPlanRun.endTimestamp;
+ div.appendTo(card);
+ var span = $('<span></span>');
+ span.addClass('plan-run-metadata');
+ span.appendTo(div);
+ $('<b></b>').text(entry.deviceInfo).appendTo(span);
+ span.append('<br>');
+ $('<b></b>').text('VTS Build: ').appendTo(span);
+ span.append(entry.testPlanRun.testBuildId).append('<br>');
+ var timeString = (
+ moment().renderTime(startTime, false) + ' - ' +
+ moment().renderTime(endTime, true) + ' (' +
+ moment().renderDuration(endTime - startTime) + ')');
+ span.append(timeString);
+ var counter = $('<span></span>');
+ var color = entry.testPlanRun.failCount > 0 ? 'red' : 'green';
+ counter.addClass('counter center ' + color);
+ counter.append(
+ entry.testPlanRun.passCount + '/' +
+ (entry.testPlanRun.passCount + entry.testPlanRun.failCount));
+ counter.appendTo(div);
+ div.click(function () {
+ window.location.href = (
+ '/show_plan_run?plan=' + entry.testPlanRun.testPlanName +
+ '&time=' + entry.testPlanRun.startTimestamp);
+ })
+ }
+
+ $.fn.showPlanRuns = function(data) {
+ var self = $(this);
+ data.forEach(function (entry) {
+ renderCard(self, entry);
+ })
+ }
+
+})(jQuery, moment);
diff --git a/src/main/webapp/js/search_header.js b/src/main/webapp/js/search_header.js
new file mode 100644
index 0000000..0244815
--- /dev/null
+++ b/src/main/webapp/js/search_header.js
@@ -0,0 +1,242 @@
+/**
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+(function ($) {
+
+ function _validate(input, valueSet) {
+ var value = input.val();
+ if (valueSet.has(value) || !value) {
+ input.removeClass('invalid');
+ } else {
+ input.addClass('invalid');
+ }
+ }
+
+ function _createInput(key, config) {
+ var value = config.value;
+ var values = config.options.corpus;
+ var displayName = config.displayName;
+ var width = config.options.width || 's4';
+ var div = $('<div class="input-field col"></div>');
+ div.addClass(width);
+ var input = $('<input class="filter-input"></input>');
+ input.attr('type', config.options.type || 'text');
+ input.appendTo(div);
+ var label = $('<label></label>').text(displayName).appendTo(div);
+ if (value) {
+ input.attr('value', value);
+ label.addClass('active');
+ }
+ input.focusout(function() {
+ config.value = input.val();
+ });
+ if (values && values.length > 0) {
+ var valueSet = new Set(values);
+ input.sizedAutocomplete({
+ source: values,
+ classes: {
+ 'ui-autocomplete': 'card search-bar-menu'
+ }
+ });
+ input.focusout(function() {
+ _validate(input, valueSet);
+ });
+ }
+ if (values && values.length > 0 && value) {
+ _validate(input, valueSet);
+ }
+ return div;
+ }
+
+ function _verifyCheckboxes(checkboxes, refreshObject) {
+ var oneChecked = checkboxes.presubmit || checkboxes.postsubmit;
+ if (!oneChecked) {
+ refreshObject.addClass('disabled');
+ } else {
+ refreshObject.removeClass('disabled');
+ }
+ }
+
+ function _createRunTypeBoxes(checkboxes, refreshObject) {
+ var container = $('<div class="run-type-wrapper col s12"></div>');
+ var presubmit = $('<input type="checkbox" id="presubmit"></input>');
+ presubmit.appendTo(container);
+ if (checkboxes.presubmit) {
+ presubmit.prop('checked', true);
+ }
+ container.append('<label for="presubmit">Presubmit</label>');
+ var postsubmit = $('<input type="checkbox" id="postsubmit"></input>');
+ postsubmit.appendTo(container);
+ if (checkboxes.postsubmit) {
+ postsubmit.prop('checked', true);
+ }
+ container.append('<label for="postsubmit">Postsubmit</label>');
+ presubmit.change(function() {
+ checkboxes.presubmit = presubmit.prop('checked');
+ _verifyCheckboxes(checkboxes, refreshObject);
+ });
+ postsubmit.change(function() {
+ checkboxes.postsubmit = postsubmit.prop('checked');
+ _verifyCheckboxes(checkboxes, refreshObject);
+ });
+ return container;
+ }
+
+ function _expand(
+ container, filters, checkboxes, onRefreshCallback, animate=true) {
+ var wrapper = $('<div class="search-wrapper"></div>');
+ var col = $('<div class="col s9"></div>');
+ col.appendTo(wrapper);
+ Object.keys(filters).forEach(function(key) {
+ col.append(_createInput(key, filters[key]));
+ });
+ var refreshCol = $('<div class="col s3 refresh-wrapper"></div>');
+ var refresh = $('<a class="btn-floating btn-medium red right waves-effect waves-light"></a>')
+ .append($('<i class="medium material-icons">cached</i>'))
+ .appendTo(refreshCol);
+ refresh.click(onRefreshCallback);
+ refreshCol.appendTo(wrapper);
+ if (Object.keys(checkboxes).length > 0) {
+ col.append(_createRunTypeBoxes(checkboxes, refresh));
+ }
+ if (animate) {
+ wrapper.hide().appendTo(container).slideDown({
+ duration: 350,
+ easing: "easeOutQuart",
+ queue: false
+ });
+ } else {
+ wrapper.appendTo(container);
+ }
+ }
+
+ function _renderHeader(
+ container, label, value, filters, checkboxes, expand, onRefreshCallback) {
+ var div = $('<div class="row card search-bar"></div>');
+ var wrapper = $('<div class="header-wrapper"></div>');
+ var header = $('<h5 class="section-header"></h5>');
+ $('<b></b>').text(label).appendTo(header);
+ $('<span></span>').text(value).appendTo(header);
+ header.appendTo(wrapper);
+ var iconWrapper = $('<div class="search-icon-wrapper"></div>');
+ $('<i class="material-icons">search</i>').appendTo(iconWrapper);
+ iconWrapper.appendTo(wrapper);
+ wrapper.appendTo(div);
+ if (expand) {
+ _expand(div, filters, checkboxes, onRefreshCallback, false);
+ } else {
+ var expanded = false;
+ iconWrapper.click(function() {
+ if (expanded) return;
+ expanded = true;
+ _expand(div, filters, checkboxes, onRefreshCallback);
+ });
+ }
+ div.appendTo(container);
+ }
+
+ function _addFilter(filters, displayName, keyName, options, defaultValue) {
+ filters[keyName] = {};
+ filters[keyName].displayName = displayName;
+ filters[keyName].value = defaultValue;
+ filters[keyName].options = options;
+ }
+
+ function _getOptionString(filters, checkboxes) {
+ var args = Object.keys(filters).reduce(function(acc, key) {
+ if (filters[key].value) {
+ return acc + '&' + key + '=' + encodeURIComponent(filters[key].value);
+ }
+ return acc;
+ }, '');
+ if (checkboxes.presubmit != undefined && checkboxes.presubmit) {
+ args += '&showPresubmit='
+ }
+ if (checkboxes.postsubmit != undefined && checkboxes.postsubmit) {
+ args += '&showPostsubmit='
+ }
+ return args;
+ }
+
+ /**
+ * Create a search header element.
+ * @param label The header label.
+ * @param value The value to display next to the label.
+ * @param onRefreshCallback The function to call on refresh.
+ */
+ $.fn.createSearchHeader = function(label, value, onRefreshCallback) {
+ var self = $(this);
+ $.widget('custom.sizedAutocomplete', $.ui.autocomplete, {
+ _resizeMenu : function() {
+ this.menu.element.outerWidth($('.search-bar .filter-input').width());
+ }
+ });
+ var filters = {};
+ var checkboxes = {};
+ var expandOnRender = false;
+ var displayed = false;
+ return {
+ /**
+ * Add a filter to the display.
+ * @param displayName The input placeholder/label text.
+ * @param keyName The URL key to use for the filter options.
+ * @param options A dict of additional options (e.g. width, type).
+ * @param defaultValue A default filter value.
+ */
+ addFilter : function(displayName, keyName, options, defaultValue) {
+ if (displayed) return;
+ _addFilter(filters, displayName, keyName, options, defaultValue);
+ if (defaultValue) expandOnRender = true;
+ },
+ /**
+ * Enable run type checkboxes in the filter options.
+ *
+ * This will display two checkboxes for selecting pre-/postsubmit runs.
+ * @param showPresubmit True if presubmit runs are selected.
+ * @param showPostsubmit True if postsubmit runs are selected.
+ *
+ */
+ addRunTypeCheckboxes: function(showPresubmit, showPostsubmit) {
+ if (displayed) return;
+ checkboxes['presubmit'] = showPresubmit;
+ checkboxes['postsubmit'] = showPostsubmit;
+ if (!showPostsubmit || showPresubmit) {
+ expandOnRender = true;
+ }
+ },
+ /**
+ * Display the created search bar.
+ *
+ * This must be called after filters have been added. After displaying, no
+ * modifications to the filter options will take effect.
+ */
+ display : function() {
+ displayed = true;
+ _renderHeader(
+ self, label, value, filters, checkboxes, expandOnRender,
+ onRefreshCallback);
+ },
+ /**
+ * Get the URL arguments string for the current set of filters.
+ * @returns a URI-encoded component with the search bar keys and values.
+ */
+ args : function () {
+ return _getOptionString(filters, checkboxes);
+ }
+ }
+ }
+
+})(jQuery);
diff --git a/src/main/webapp/js/test_results.js b/src/main/webapp/js/test_results.js
new file mode 100644
index 0000000..8f923fb
--- /dev/null
+++ b/src/main/webapp/js/test_results.js
@@ -0,0 +1,272 @@
+/**
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+(function ($, moment) {
+
+ /**
+ * Display the log links in a modal window.
+ * @param logList A list of [name, url] tuples representing log links.
+ */
+ function showLogs(container, logList) {
+ if (!logList || logList.length == 0) return;
+
+ var logCollection = $('<ul class="collection"></ul>');
+ var entries = logList.reduce(function(acc, entry) {
+ if (!entry || entry.length == 0) return acc;
+ var link = '<a href="' + entry[1] + '"';
+ link += 'class="collection-item">' + entry[0] + '</li>';
+ return acc + link;
+ }, '');
+ logCollection.html(entries);
+
+ if (container.find('#info-modal').length == 0) {
+ var modal = $('<div id="info-modal" class="modal"></div>');
+ var content = $('<div class="modal-content"></div>');
+ content.append('<h4>Logs</h4>');
+ content.append('<div class="info-container"></div>');
+ content.appendTo(modal);
+ modal.appendTo(container);
+ }
+ var infoContainer = $('#info-modal>.modal-content>.info-container');
+ infoContainer.empty();
+ logCollection.appendTo(infoContainer);
+ $('#info-modal').openModal();
+ }
+
+ /**
+ * Get the nickname for a test case result.
+ *
+ * Removes the result prefix and suffix, extracting only the result name.
+ *
+ * @param testCaseResult The string name of a VtsReportMessage.TestCaseResult.
+ * @returns the string nickname of the result.
+ */
+ function getNickname(testCaseResult) {
+ return testCaseResult
+ .replace('TEST_CASE_RESULT_', '')
+ .replace('_RESULT', '')
+ .trim().toLowerCase();
+ }
+
+ /**
+ * Display test data in the body beneath a test run's metadata.
+ * @param container The jquery object in which to insert the test metadata.
+ * @param data The json object containing the columns to display.
+ * @param lineHeight The height of each list element.
+ */
+ function displayTestDetails(container, data, lineHeight) {
+ var nCol = data.length;
+ var width = 12 / nCol;
+ test = container;
+ var maxLines = 0;
+ data.forEach(function (column) {
+ if (column.data == undefined || column.name == undefined) {
+ return;
+ }
+ var colContainer =
+ $('<div class="col s' + width + ' test-col"></div>');
+ var col = $('<div class="test-case-container"></div>');
+ colContainer.appendTo(container);
+ var count = column.data.length;
+ $('<h5>' + getNickname(column.name) + ' (' + count + ')' + '</h5>')
+ .appendTo(colContainer).css('text-transform', 'capitalize');
+ col.appendTo(colContainer);
+ var list = $('<ul></ul>').appendTo(col);
+ column.data.forEach(function (testCase) {
+ $('<li></li>')
+ .text(testCase)
+ .addClass('test-case')
+ .css('font-size', lineHeight - 2)
+ .css('line-height', lineHeight + 'px')
+ .appendTo(list);
+ });
+ if (count > maxLines) {
+ maxLines = count;
+ }
+ });
+ var containers = container.find('.test-case-container');
+ containers.height(maxLines * lineHeight);
+ }
+
+ /**
+ * Click handler for displaying test run details.
+ * @param e The click event.
+ */
+ function testRunClick(e) {
+ var header = $(this);
+ var icon = header.find('.material-icons.expand-arrow');
+ var container = header.parent().find('.test-results');
+ var test = header.attr('test');
+ var time = header.attr('time');
+ var url = '/api/test_run?test=' + test + '&timestamp=' + time;
+ if (header.parent().hasClass('active')) {
+ header.parent().removeClass('active');
+ header.removeClass('active');
+ icon.removeClass('rotate');
+ header.siblings('.collapsible-body').stop(true, false).slideUp({
+ duration: 100,
+ easing: "easeOutQuart",
+ queue: false,
+ complete: function() { header.css('height', ''); }
+ });
+ } else {
+ container.empty();
+ header.parent().addClass('active');
+ header.addClass('active');
+ header.addClass('disabled');
+ icon.addClass('rotate');
+ $.get(url).done(function(data) {
+ displayTestDetails(container, data, 16);
+ header.siblings('.collapsible-body').stop(true, false).slideDown({
+ duration: 100,
+ easing: "easeOutQuart",
+ queue: false,
+ complete: function() { header.css('height', ''); }
+ });
+ }).fail(function() {
+ icon.removeClass('rotate');
+ }).always(function() {
+ header.removeClass('disabled');
+ });
+ }
+ }
+
+ /**
+ * Append a clickable indicator link to the container.
+ * @param container The jquery object to append the indicator to.
+ * @param content The text to display in the indicator.
+ * @param classes Additional space-delimited classes to add to the indicator.
+ * @param click The click handler to assign to the indicator.
+ * @returns The jquery object for the indicator.
+ */
+ function createClickableIndicator(container, content, classes, click) {
+ var link = $('<a></a>');
+ link.addClass('indicator right center padded hoverable waves-effect');
+ link.addClass(classes)
+ link.append(content);
+ link.appendTo(container);
+ link.click(click);
+ return link;
+ }
+
+ function displayTestMetadata(container, metadataList, showTestNames=false) {
+ var popout = $('<ul></ul>');
+ popout.attr('data-collapsible', 'expandable');
+ popout.addClass('collapsible popout test-runs');
+ popout.appendTo(container);
+ popout.unbind();
+ metadataList.forEach(function (metadata) {
+ var li = $('<li class="test-run-container"></li>');
+ li.appendTo(popout);
+ var div = $('<div></div>');
+ var test = metadata.testRun.testName;
+ var startTime = metadata.testRun.startTimestamp;
+ var endTime = metadata.testRun.endTimestamp;
+ div.attr('test', test);
+ div.attr('time', startTime);
+ div.addClass('collapsible-header test-run');
+ div.appendTo(li);
+ div.unbind().click(testRunClick);
+ var span = $('<span></span>');
+ span.addClass('test-run-metadata');
+ span.appendTo(div);
+ span.click(function() { return false; });
+ if (showTestNames) {
+ $('<span class="test-run-label"></span>').text(test).appendTo(span);
+ span.append('<br>');
+ }
+ $('<b></b>').text(metadata.deviceInfo).appendTo(span);
+ span.append('<br>');
+ $('<b></b>').text('ABI: ')
+ .appendTo(span)
+ span.append(metadata.abiInfo).append('<br>');
+ $('<b></b>').text('VTS Build: ')
+ .appendTo(span)
+ span.append(metadata.testRun.testBuildId).append('<br>');
+ $('<b></b>').text('Host: ')
+ .appendTo(span)
+ span.append(metadata.testRun.hostName).append('<br>');
+ var timeString = (
+ moment().renderTime(startTime, false) + ' - ' +
+ moment().renderTime(endTime, true) + ' (' +
+ moment().renderDuration(endTime - startTime) + ')');
+ span.append(timeString);
+ var indicator = $('<span></span>');
+ var color = metadata.testRun.failCount > 0 ? 'red' : 'green';
+ indicator.addClass('indicator right center ' + color);
+ indicator.append(
+ metadata.testRun.passCount + '/' +
+ (metadata.testRun.passCount + metadata.testRun.failCount));
+ indicator.appendTo(div);
+ if (metadata.testRun.coveredLineCount != undefined &&
+ metadata.testRun.totalLineCount != undefined) {
+ var url = (
+ '/show_coverage?testName=' + test + '&startTime=' + startTime);
+ covered = metadata.testRun.coveredLineCount;
+ total = metadata.testRun.totalLineCount;
+ covPct = Math.round(covered / total * 1000) / 10;
+ var color = 'red';
+ if (covPct > 20 && covPct < 70) {
+ color = 'orange';
+ } else if (covPct >= 70) {
+ color = 'green';
+ }
+ var coverage = (
+ 'Coverage: ' + covered + '/' + total + ' (' + covPct + '%)');
+ createClickableIndicator(
+ div, coverage, color,
+ function () { window.location.href = url; return false; });
+ }
+ if (metadata.testRun.logLinks != undefined) {
+ createClickableIndicator(
+ div, 'Logs', 'grey lighten-1',
+ function () {
+ showLogs(popout, metadata.testRun.logLinks);
+ return false;
+ });
+ }
+ var expand = $('<i></i>');
+ expand.addClass('material-icons expand-arrow')
+ expand.text('expand_more');
+ expand.appendTo(div);
+ var body = $('<div></div>')
+ .addClass('collapsible-body test-results row grey lighten-4')
+ .appendTo(li);
+ if (metadata.testDetails != undefined) {
+ expand.addClass('rotate');
+ li.addClass('active');
+ div.addClass('active');
+ displayTestDetails(body, metadata.testDetails, 16);
+ div.siblings('.collapsible-body').stop(true, false).slideDown({
+ duration: 0,
+ queue: false,
+ complete: function() { div.css('height', ''); }
+ });
+ }
+ });
+ }
+
+ /**
+ * Display test metadata in a vertical popout.
+ * @param container The jquery object in which to insert the test metadata.
+ * @param metadataList The list of metadata objects to render on the display.
+ * @param showTestNames True to label each entry with the test module name.
+ */
+ $.fn.showTests = function(metadataList, showTestNames=false) {
+ displayTestMetadata($(this), metadataList, showTestNames);
+ }
+
+})(jQuery, moment);
diff --git a/src/main/webapp/js/time.js b/src/main/webapp/js/time.js
new file mode 100644
index 0000000..c5fbef6
--- /dev/null
+++ b/src/main/webapp/js/time.js
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2017 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+(function (moment) {
+
+ /**
+ * Renders a timestamp in the user timezone.
+ * @param timestamp The long timestamp to render (in microseconds).
+ * @param showTimezone True if the timezone should be rendered, false otherwise.
+ * @returns the string-formatted version of the provided timestamp.
+ */
+ moment.prototype.renderTime = function (timestamp, showTimezone) {
+ var time = moment(timestamp / 1000);
+ var format = 'H:mm:ss';
+ if (!time.isSame(moment(), 'd')) {
+ format = 'M/D/YY ' + format;
+ }
+ if (!!showTimezone) {
+ format = format + 'ZZ';
+ }
+ return time.format(format);
+ }
+
+ /**
+ * Renders a duration in the user timezone.
+ * @param durationTimestamp The long duration to render (in microseconds).
+ * @returns the string-formatted duration of the provided duration timestamp.
+ */
+ moment.prototype.renderDuration = function (durationTimestamp) {
+ var fmt = 's[s]';
+ var duration = moment.utc(durationTimestamp / 1000);
+ if (duration.hours() > 0) {
+ fmt = 'H[h], m[m], ' + fmt;
+ } else if (duration.minutes() > 0) {
+ fmt = 'm[m], ' + fmt;
+ }
+ return duration.format(fmt);
+ }
+
+})(moment);
diff --git a/src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java b/src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java
new file mode 100644
index 0000000..c8adb69
--- /dev/null
+++ b/src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.servlet;
+
+import static org.junit.Assert.*;
+
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.entity.TestEntity;
+import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
+import com.android.vts.util.PerformanceSummary;
+import com.android.vts.util.ProfilingPointSummary;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
+import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class VtsPerformanceJobServletTest {
+ private final LocalServiceTestHelper helper =
+ new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
+
+ private static final String LABEL = "testLabel";
+ private static final String ROOT = "src/test/res/servlet";
+ private static final String[] LABELS = new String[] {"label1", "label2", "label3"};
+ private static final long[] HIGH_VALS = new long[] {10, 20, 30};
+ private static final long[] LOW_VALS = new long[] {1, 2, 3};
+
+ List<PerformanceSummary> dailySummaries;
+ List<String> legendLabels;
+
+ /**
+ * Helper method for creating ProfilingPointRunEntity objects.
+ *
+ * @param labels The list of data labels.
+ * @param values The list of data values. Must be equal in size to the labels list.
+ * @param regressionMode The regression mode.
+ * @return A ProfilingPointRunEntity with specified arguments.
+ */
+ private static ProfilingPointRunEntity createProfilingReport(
+ String[] labels, long[] values, VtsProfilingRegressionMode regressionMode) {
+ List<String> labelList = Arrays.asList(labels);
+ List<Long> valueList = new ArrayList<>();
+ for (long value : values) {
+ valueList.add(value);
+ }
+ return new ProfilingPointRunEntity(KeyFactory.createKey(TestEntity.KIND, "test"), "name", 0,
+ regressionMode.getNumber(), labelList, valueList, "", "", null);
+ }
+
+ /** Asserts whether text is the same as the contents in the baseline file specified. */
+ private static void compareToBaseline(String text, String baselineFilename)
+ throws FileNotFoundException, IOException {
+ File f = new File(ROOT, baselineFilename);
+ String baseline = "";
+ try (BufferedReader br = new BufferedReader(new FileReader(f))) {
+ StringBuilder sb = new StringBuilder();
+ String line = br.readLine();
+
+ while (line != null) {
+ sb.append(line);
+ line = br.readLine();
+ }
+ baseline = sb.toString();
+ }
+ assertEquals(baseline, text);
+ }
+
+ @Before
+ public void setUp() {
+ helper.setUp();
+ }
+
+ @After
+ public void tearDown() {
+ helper.tearDown();
+ }
+
+ public void setUp(boolean grouped) {
+ dailySummaries = new ArrayList<>();
+ legendLabels = new ArrayList<>();
+ legendLabels.add("");
+
+ // Add today's data
+ PerformanceSummary today = new PerformanceSummary();
+ ProfilingPointSummary summary = new ProfilingPointSummary();
+ VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING;
+ ProfilingPointRunEntity pt = createProfilingReport(LABELS, HIGH_VALS, mode);
+ if (grouped) {
+ summary.updateLabel(pt, LABEL);
+ summary.updateLabel(pt, LABEL);
+ } else {
+ summary.update(pt);
+ summary.update(pt);
+ }
+ today.insertProfilingPointSummary("p1", summary);
+
+ summary = new ProfilingPointSummary();
+ mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DECREASING;
+ pt = createProfilingReport(LABELS, LOW_VALS, mode);
+ if (grouped) {
+ summary.updateLabel(pt, LABEL);
+ summary.updateLabel(pt, LABEL);
+ } else {
+ summary.update(pt);
+ summary.update(pt);
+ }
+ today.insertProfilingPointSummary("p2", summary);
+ dailySummaries.add(today);
+ legendLabels.add("today");
+
+ // Add yesterday data with regressions
+ PerformanceSummary yesterday = new PerformanceSummary();
+ summary = new ProfilingPointSummary();
+ mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING;
+ pt = createProfilingReport(LABELS, LOW_VALS, mode);
+ if (grouped) {
+ summary.updateLabel(pt, LABEL);
+ summary.updateLabel(pt, LABEL);
+ } else {
+ summary.update(pt);
+ summary.update(pt);
+ }
+ yesterday.insertProfilingPointSummary("p1", summary);
+
+ summary = new ProfilingPointSummary();
+ mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DECREASING;
+ pt = createProfilingReport(LABELS, HIGH_VALS, mode);
+ if (grouped) {
+ summary.updateLabel(pt, LABEL);
+ summary.updateLabel(pt, LABEL);
+ } else {
+ summary.update(pt);
+ summary.update(pt);
+ }
+ yesterday.insertProfilingPointSummary("p2", summary);
+ dailySummaries.add(yesterday);
+ legendLabels.add("yesterday");
+
+ // Add last week data without regressions
+ PerformanceSummary lastWeek = new PerformanceSummary();
+ summary = new ProfilingPointSummary();
+ mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING;
+ pt = createProfilingReport(LABELS, HIGH_VALS, mode);
+ summary.update(pt);
+ summary.update(pt);
+ lastWeek.insertProfilingPointSummary("p1", summary);
+
+ summary = new ProfilingPointSummary();
+ mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DECREASING;
+ pt = createProfilingReport(LABELS, LOW_VALS, mode);
+ summary.update(pt);
+ summary.update(pt);
+ lastWeek.insertProfilingPointSummary("p2", summary);
+ dailySummaries.add(lastWeek);
+ legendLabels.add("last week");
+ }
+
+ /**
+ * End-to-end test of performance report in the normal case. The normal case is when a profiling
+ * point is added or removed from the test.
+ */
+ @Test
+ public void testPerformanceSummaryNormal() throws FileNotFoundException, IOException {
+ setUp(false);
+ String output =
+ VtsPerformanceJobServlet.getPeformanceSummary("test", dailySummaries, legendLabels);
+ compareToBaseline(output, "performanceSummary1.html");
+ }
+
+ /** End-to-end test of performance report when a profiling point was removed in the latest run.
+ */
+ @Test
+ public void testPerformanceSummaryDroppedProfilingPoint()
+ throws FileNotFoundException, IOException {
+ setUp(false);
+ PerformanceSummary yesterday = dailySummaries.get(dailySummaries.size() - 1);
+ ProfilingPointSummary summary = new ProfilingPointSummary();
+ VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING;
+ ProfilingPointRunEntity pt = createProfilingReport(LABELS, HIGH_VALS, mode);
+ summary.update(pt);
+ summary.update(pt);
+ yesterday.insertProfilingPointSummary("p3", summary);
+ String output =
+ VtsPerformanceJobServlet.getPeformanceSummary("test", dailySummaries, legendLabels);
+ compareToBaseline(output, "performanceSummary2.html");
+ }
+
+ /** End-to-end test of performance report when a profiling point was added in the latest run. */
+ @Test
+ public void testPerformanceSummaryAddedProfilingPoint()
+ throws FileNotFoundException, IOException {
+ setUp(false);
+ PerformanceSummary today = dailySummaries.get(0);
+ ProfilingPointSummary summary = new ProfilingPointSummary();
+ VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING;
+ ProfilingPointRunEntity pt = createProfilingReport(LABELS, HIGH_VALS, mode);
+ summary.update(pt);
+ summary.update(pt);
+ today.insertProfilingPointSummary("p3", summary);
+ String output =
+ VtsPerformanceJobServlet.getPeformanceSummary("test", dailySummaries, legendLabels);
+ compareToBaseline(output, "performanceSummary3.html");
+ }
+
+ /** End-to-end test of performance report labels are grouped (e.g. as if using unlabeled data)
+ */
+ @Test
+ public void testPerformanceSummaryGroupedNormal() throws FileNotFoundException, IOException {
+ setUp(true);
+ String output =
+ VtsPerformanceJobServlet.getPeformanceSummary("test", dailySummaries, legendLabels);
+ compareToBaseline(output, "performanceSummary4.html");
+ }
+}
diff --git a/src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java b/src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java
new file mode 100644
index 0000000..cc529be
--- /dev/null
+++ b/src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import static org.junit.Assert.*;
+
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.entity.TestEntity;
+import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
+import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ProfilingPointSummaryTest {
+ private final LocalServiceTestHelper helper =
+ new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
+ private static String[] labels = new String[] {"label1", "label2", "label3"};
+ private static long[] values = new long[] {1, 2, 3};
+ private static ProfilingPointSummary summary;
+
+ /**
+ * Helper method for creating ProfilingPointRunEntity objects.
+ *
+ * @param labels The list of data labels.
+ * @param values The list of data values. Must be equal in size to the labels list.
+ * @param regressionMode The regression mode.
+ * @return A ProfilingPointRunEntity with specified arguments.
+ */
+ private static ProfilingPointRunEntity createProfilingReport(
+ String[] labels, long[] values, VtsProfilingRegressionMode regressionMode) {
+ List<String> labelList = Arrays.asList(labels);
+ List<Long> valueList = new ArrayList<>();
+ for (long value : values) {
+ valueList.add(value);
+ }
+ return new ProfilingPointRunEntity(KeyFactory.createKey(TestEntity.KIND, "test"), "name", 0,
+ regressionMode.getNumber(), labelList, valueList, "x", "y", null);
+ }
+
+ @Before
+ public void setUp() {
+ helper.setUp();
+ summary = new ProfilingPointSummary();
+ VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING;
+ ProfilingPointRunEntity pt = createProfilingReport(labels, values, mode);
+ summary.update(pt);
+ }
+
+ @After
+ public void tearDown() {
+ helper.tearDown();
+ }
+
+ /** Test that all labels are found by hasLabel. */
+ @Test
+ public void testHasLabel() {
+ for (String label : labels) {
+ assertTrue(summary.hasLabel(label));
+ }
+ }
+
+ /** Test that invalid labels are not found by hasLabel. */
+ @Test
+ public void testInvalidHasLabel() {
+ assertFalse(summary.hasLabel("bad label"));
+ }
+
+ /** Test that all stat summaries can be retrieved by profiling point label. */
+ @Test
+ public void testGetStatSummary() {
+ for (String label : labels) {
+ StatSummary stats = summary.getStatSummary(label);
+ assertNotNull(stats);
+ assertEquals(label, stats.getLabel());
+ }
+ }
+
+ /** Test that the getStatSummary method returns null when the label is not present. */
+ @Test
+ public void testInvalidGetStatSummary() {
+ StatSummary stats = summary.getStatSummary("bad label");
+ assertNull(stats);
+ }
+
+ /** Test that StatSummary objects are iterated in the order that the labels were provided. */
+ @Test
+ public void testIterator() {
+ VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING;
+ ProfilingPointRunEntity pt = createProfilingReport(labels, values, mode);
+ summary.update(pt);
+
+ int i = 0;
+ for (StatSummary stats : summary) {
+ assertEquals(labels[i++], stats.getLabel());
+ }
+ }
+
+ /** Test that the updateLabel method updates the StatSummary for just the label provided. */
+ @Test
+ public void testUpdateLabelGrouped() {
+ summary = new ProfilingPointSummary();
+ VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING;
+ ProfilingPointRunEntity pt = createProfilingReport(labels, values, mode);
+ summary.updateLabel(pt, labels[0]);
+
+ // Ensure the label specified is present and has been updated for each data point.
+ assertTrue(summary.hasLabel(labels[0]));
+ assertNotNull(summary.getStatSummary(labels[0]));
+ assertEquals(summary.getStatSummary(labels[0]).getCount(), labels.length);
+
+ // Check that the other labels were not updated.
+ for (int i = 1; i < labels.length; i++) {
+ assertFalse(summary.hasLabel(labels[i]));
+ }
+ }
+}
diff --git a/src/test/java/com/android/vts/util/StatSummaryTest.java b/src/test/java/com/android/vts/util/StatSummaryTest.java
new file mode 100644
index 0000000..333e3b5
--- /dev/null
+++ b/src/test/java/com/android/vts/util/StatSummaryTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016 Google Inc. All Rights Reserved.
+ *
+ * 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.vts.util;
+
+import static org.junit.Assert.*;
+
+import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
+import java.util.Random;
+import org.junit.Before;
+import org.junit.Test;
+
+public class StatSummaryTest {
+ private static double threshold = 0.0000000001;
+ private StatSummary test;
+
+ @Before
+ public void setUp() {
+ test = new StatSummary("label", VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DECREASING);
+ }
+
+ /** Test computation of average. */
+ @Test
+ public void testAverage() {
+ int n = 1000;
+ double mean = (n - 1) / 2.0;
+ for (int i = 0; i < n; i++) {
+ test.updateStats(i);
+ }
+ assertEquals(n, test.getCount(), threshold);
+ assertEquals(mean, test.getMean(), threshold);
+ }
+
+ /** Test computation of minimum. */
+ @Test
+ public void testMin() {
+ double min = Double.MAX_VALUE;
+ int n = 1000;
+ Random rand = new Random();
+ for (int i = 0; i < n; i++) {
+ double value = rand.nextInt(1000);
+ if (value < min)
+ min = value;
+ test.updateStats(value);
+ }
+ assertEquals(n, test.getCount(), threshold);
+ assertEquals(min, test.getMin(), threshold);
+ }
+
+ /** Test computation of maximum. */
+ @Test
+ public void testMax() {
+ double max = Double.MIN_VALUE;
+ int n = 1000;
+ Random rand = new Random();
+ for (int i = 0; i < n; i++) {
+ double value = rand.nextInt(1000);
+ if (value > max)
+ max = value;
+ test.updateStats(value);
+ }
+ assertEquals(max, test.getMax(), threshold);
+ }
+
+ /** Test computation of standard deviation. */
+ @Test
+ public void testStd() {
+ int n = 1000;
+ double[] values = new double[n];
+ Random rand = new Random();
+ double sum = 0.0;
+ for (int i = 0; i < n; i++) {
+ values[i] = rand.nextInt(1000);
+ sum += values[i];
+ test.updateStats(values[i]);
+ }
+ double mean = sum / n;
+ double sumSq = 0;
+ for (int i = 0; i < n; i++) {
+ sumSq += (values[i] - mean) * (values[i] - mean);
+ }
+ double std = Math.sqrt(sumSq / (n - 1));
+ assertEquals(std, test.getStd(), threshold);
+ }
+}
diff --git a/src/test/res/driver/chromedriver b/src/test/res/driver/chromedriver
new file mode 100755
index 0000000..bbb06c3
--- /dev/null
+++ b/src/test/res/driver/chromedriver
Binary files differ
diff --git a/src/test/res/driver/config.properties b/src/test/res/driver/config.properties
new file mode 100644
index 0000000..939fa90
--- /dev/null
+++ b/src/test/res/driver/config.properties
@@ -0,0 +1 @@
+LOCALHOST=localhost:8080 \ No newline at end of file
diff --git a/src/test/res/servlet/performanceSummary1.html b/src/test/res/servlet/performanceSummary1.html
new file mode 100644
index 0000000..3b01593
--- /dev/null
+++ b/src/test/res/servlet/performanceSummary1.html
@@ -0,0 +1 @@
+<p style='font-family: arial'><b>test</b></p><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p1</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Min (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Min (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Lower values are better. Minimum is the best-case performance.</i><br><br><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p2</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Max (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Max (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Higher values are better. Maximum is the best-case performance.</i><br><br> \ No newline at end of file
diff --git a/src/test/res/servlet/performanceSummary2.html b/src/test/res/servlet/performanceSummary2.html
new file mode 100644
index 0000000..3b01593
--- /dev/null
+++ b/src/test/res/servlet/performanceSummary2.html
@@ -0,0 +1 @@
+<p style='font-family: arial'><b>test</b></p><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p1</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Min (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Min (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Lower values are better. Minimum is the best-case performance.</i><br><br><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p2</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Max (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Max (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Higher values are better. Maximum is the best-case performance.</i><br><br> \ No newline at end of file
diff --git a/src/test/res/servlet/performanceSummary3.html b/src/test/res/servlet/performanceSummary3.html
new file mode 100644
index 0000000..1ff1028
--- /dev/null
+++ b/src/test/res/servlet/performanceSummary3.html
@@ -0,0 +1 @@
+<p style='font-family: arial'><b>test</b></p><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p1</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Min (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Min (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Lower values are better. Minimum is the best-case performance.</i><br><br><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p2</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Max (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Max (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Higher values are better. Maximum is the best-case performance.</i><br><br><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p3</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Min (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Min (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Lower values are better. Minimum is the best-case performance.</i><br><br> \ No newline at end of file
diff --git a/src/test/res/servlet/performanceSummary4.html b/src/test/res/servlet/performanceSummary4.html
new file mode 100644
index 0000000..8fc8997
--- /dev/null
+++ b/src/test/res/servlet/performanceSummary4.html
@@ -0,0 +1 @@
+<p style='font-family: arial'><b>test</b></p><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p1</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Min (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Min (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>testLabel</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>8.94</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0.89</td><td></td><td></td><td></td><td></td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Lower values are better. Minimum is the best-case performance.</i><br><br><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p2</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Max (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>&Delta;Max (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>testLabel</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0.89</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>8.94</td><td></td><td></td><td></td><td></td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Higher values are better. Maximum is the best-case performance.</i><br><br> \ No newline at end of file