Merge "Fix vtsc for TYPE_MASK."
diff --git a/create-image-angler.sh b/create-image-angler.sh
deleted file mode 100755
index 7b0d71a..0000000
--- a/create-image-angler.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#
-# 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.
-
-source create-image.sh
-
-vts_multidevice_create_image angler
diff --git a/create-image-angler_treble.sh b/create-image-angler_treble.sh
deleted file mode 100755
index 2e39ac6..0000000
--- a/create-image-angler_treble.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#
-# 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.
-
-source create-image.sh
-
-vts_multidevice_create_image angler ENABLE_TREBLE=true
diff --git a/create-image-bullhead.sh b/create-image-bullhead.sh
deleted file mode 100755
index a3afce4..0000000
--- a/create-image-bullhead.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#
-# 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.
-
-source create-image.sh
-
-vts_multidevice_create_image bullhead
diff --git a/create-image.sh b/create-image.sh
index 188a3f6..cc63ecc 100755
--- a/create-image.sh
+++ b/create-image.sh
@@ -18,6 +18,7 @@
DEVICE=$1
rm ${ANDROID_BUILD_TOP}/test/vts/testcases/hal/nfc/ -rf
+ rm ${ANDROID_BUILD_TOP}/test/vts/testcases/hal/sensors/ -rf
rm ${ANDROID_BUILD_TOP}/test/vts/testcases/hal/vehicle/ -rf
rm ${ANDROID_BUILD_TOP}/test/vts/testcases/hal/vibrator/ -rf
rm ${ANDROID_BUILD_TOP}/test/vts/testcases/hal/vr/ -rf
@@ -26,6 +27,7 @@
cd ${ANDROID_BUILD_TOP}; lunch ${DEVICE}-userdebug $2
cd ${ANDROID_BUILD_TOP}/test/vts; mma -j 32 && cd ${ANDROID_BUILD_TOP}; make vts adb -j 32
cp ${ANDROID_BUILD_TOP}/hardware/interfaces/nfc/1.0/vts/functional/vts/testcases/hal/nfc/ ${ANDROID_BUILD_TOP}/test/vts/testcases/hal/ -rf
+ cp ${ANDROID_BUILD_TOP}/hardware/interfaces/sensors/1.0/vts/functional/vts/testcases/hal/sensors/ ${ANDROID_BUILD_TOP}/test/vts/testcases/hal/ -rf
cp ${ANDROID_BUILD_TOP}/hardware/interfaces/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/ ${ANDROID_BUILD_TOP}/test/vts/testcases/hal/ -rf
cp ${ANDROID_BUILD_TOP}/hardware/interfaces/vibrator/1.0/vts/functional/vts/testcases/hal/vibrator/ ${ANDROID_BUILD_TOP}/test/vts/testcases/hal/ -rf
cp ${ANDROID_BUILD_TOP}/hardware/interfaces/vr/1.0/vts/functional/vts/testcases/hal/vr/ ${ANDROID_BUILD_TOP}/test/vts/testcases/hal/ -rf
diff --git a/doc/testcase_develop_manual/run_vts_directly.md b/doc/testcase_develop_manual/run_vts_directly.md
index faf2572..997da85 100644
--- a/doc/testcase_develop_manual/run_vts_directly.md
+++ b/doc/testcase_develop_manual/run_vts_directly.md
@@ -6,31 +6,11 @@
`$ cd test/vts`
-`$ ./create-image-<your build target>.sh`
-
-For angler_treble and bullhead, please run:
-
-`$ ./create-image-angler_treble.sh`
-
-and
-
-`$ ./create-image-bullhead.sh`
-
-respectively.
+`$ ./create-image.sh <your build target>`
## Copy Binaries
-`$ ./setup-<your build target>.sh`
-
-For angler_treble and bullhead, please run:
-
-`$ ./setup-angler_treble.sh`
-
-and
-
-`$ ./setup-bullhead.sh`
-
-respectively.
+`$ ./setup.sh <your build target>
## Run a test direclty
@@ -55,4 +35,4 @@
Optionally, the command used to add a new test can be also added to:
-`test/vts/run-angler.sh`
+`test/vts/run-local.sh`
diff --git a/run-angler.sh b/run-local.sh
similarity index 100%
rename from run-angler.sh
rename to run-local.sh
diff --git a/run-unittest.sh b/run-unittest.sh
old mode 100644
new mode 100755
diff --git a/runners/host/base_test_with_webdb.py b/runners/host/base_test_with_webdb.py
index e13bf59..22d6648 100644
--- a/runners/host/base_test_with_webdb.py
+++ b/runners/host/base_test_with_webdb.py
@@ -248,13 +248,16 @@
if self._current_test_report_msg:
self._current_test_report_msg.end_timestamp = test_end_time
if self._systrace_controller and self._systrace_controller.is_valid:
- if self.getUserParam(
- keys.ConfigKeys.IKEY_SYSTRACE_UPLAD_TO_DASHBOARD,
- default_value=False):
- try:
- systrace_msg = self._current_test_report_msg.systrace.add(
- )
- systrace_msg.process_name = self._systrace_controller.process_name
+ systrace_msg = None
+ try:
+ systrace_msg = self._current_test_report_msg.systrace.add(
+ )
+ systrace_msg.process_name = self._systrace_controller.process_name
+
+ if self.getUserParam(
+ keys.ConfigKeys.
+ IKEY_SYSTRACE_UPLAD_TO_DASHBOARD,
+ default_value=False):
html = self._systrace_controller.ReadLastOutput()
if html is None:
logging.error(
@@ -264,30 +267,47 @@
logging.info(
'Systrace html data added to report message. Length: %s',
len(html))
- suc = self._systrace_controller.ClearLastOutput()
- if not suc:
- logging.error(
- 'failed to clear last systrace output.')
- except Exception as e: # TODO(yuexima): more specific exceptions catch
- logging.error(
- 'Failed to add systrace to resport message %s',
- e)
+ except Exception as e: # TODO(yuexima): more specific exceptions catch
+ logging.exception(
+ 'Failed to add systrace to resport message %s', e)
report_path = self.getUserParam(
keys.ConfigKeys.IKEY_SYSTRACE_REPORT_PATH,
default_value=None)
if report_path:
- report_destination_file = os.path.join(
- report_path,
- '{module}_{test}_{process}_{time}.html'.format(
- module=self.test_module_name,
- test=test_name,
- process=self._systrace_controller.process_name,
- time=test_end_time))
+ report_destination_file_name = '{module}_{test}_{process}_{time}.html'.format(
+ module=self.test_module_name,
+ test=test_name,
+ process=self._systrace_controller.process_name,
+ time=test_end_time)
+ report_destination_file_path = os.path.join(
+ report_path, report_destination_file_name)
self._systrace_controller.SaveLastOutput(
- report_destination_file)
+ report_destination_file_path)
logging.info('Systrace output saved to %s',
- report_destination_file)
+ report_destination_file_path)
+
+ report_url_prefix = self.getUserParam(
+ keys.ConfigKeys.IKEY_SYSTRACE_REPORT_URL_PREFIX,
+ default_value=None)
+ if report_url_prefix and systrace_msg:
+ report_url_prefix = str(report_url_prefix)
+ report_destination_file_url = '%s%s' % (
+ report_url_prefix,
+ report_destination_file_name)
+
+ try:
+ systrace_msg.url.append(
+ report_destination_file_url)
+ logging.info(
+ 'systrace result url %s added to protobuf message.',
+ report_destination_file_url)
+ except Exception as e: # TODO(yuexima): more specific exceptions catch
+ logging.exception(
+ 'failed to append systrace result url "%s" to proto message: %s',
+ (report_destination_file_url, e))
+ if not self._systrace_controller.ClearLastOutput():
+ logging.error('failed to clear last systrace output.')
else:
logging.info(
"test result of '%s' is empty and will not be uploaded.",
@@ -478,10 +498,9 @@
regression_mode: specifies the direction of change which indicates
performance regression.
"""
- self.AddProfilingDataVector(name, labels, values,
- ReportMsg.VTS_PROFILING_TYPE_LABELED_VECTOR,
- options, x_axis_label, y_axis_label,
- regression_mode)
+ self.AddProfilingDataVector(
+ name, labels, values, ReportMsg.VTS_PROFILING_TYPE_LABELED_VECTOR,
+ options, x_axis_label, y_axis_label, regression_mode)
def AddProfilingDataUnlabeledVector(
self,
@@ -502,10 +521,9 @@
regression_mode: specifies the direction of change which indicates
performance regression.
"""
- self.AddProfilingDataVector(name, None, values,
- ReportMsg.VTS_PROFILING_TYPE_UNLABELED_VECTOR,
- options, x_axis_label, y_axis_label,
- regression_mode)
+ self.AddProfilingDataVector(
+ name, None, values, ReportMsg.VTS_PROFILING_TYPE_UNLABELED_VECTOR,
+ options, x_axis_label, y_axis_label, regression_mode)
def AddProfilingDataTimestamp(
self,
@@ -595,7 +613,8 @@
try:
build_client = artifact_fetcher.AndroidBuildClient(
service_json_path)
- except Exception:
+ except Exception as e:
+ logging.exception('Failed to instantiate build client: %s', e)
logging.error("Invalid service JSON file %s", service_json_path)
return False
@@ -603,7 +622,8 @@
try:
revision_dict = build_client.GetRepoDictionary(
self.BRANCH, build_flavor, device_build_id)
- except:
+ except Exception as e:
+ logging.exception('Failed to fetch repo dictionary: %s', e)
logging.error("Could not read build info for branch: %s, " +
"target: %s, id: %s", self.BRANCH, build_flavor,
device_build_id)
@@ -615,7 +635,8 @@
build_client.GetCoverage("master", build_flavor,
device_build_id, product))
cov_zip = zipfile.ZipFile(cov_zip)
- except:
+ except Exception as e:
+ logging.exception('Failed to fetch coverage zip: %s', e)
logging.error("Could not read coverage zip for branch: %s, " +
"target: %s, id: %s, product: %s", self.BRANCH,
build_flavor, device_build_id, product)
@@ -672,7 +693,7 @@
cov_zip = getattr(self, self.COVERAGE_ZIP)
revision_dict = getattr(self, self.REVISION_DICT)
except AttributeError as e:
- logging.error("attributes not found %s", str(e))
+ logging.exception("attributes not found %s", e)
return False
if not self.IsCoverageConfigSpecified():
diff --git a/runners/host/keys.py b/runners/host/keys.py
index 43af264..300b2b3 100644
--- a/runners/host/keys.py
+++ b/runners/host/keys.py
@@ -69,6 +69,7 @@
# Keys for systrace (for hal tests)
IKEY_SYSTRACE_PROCESS_NAME = "systrace_process_name"
IKEY_SYSTRACE_REPORT_PATH = "systrace_report_path"
+ IKEY_SYSTRACE_REPORT_URL_PREFIX = "systrace_report_url_prefix"
IKEY_SYSTRACE_UPLAD_TO_DASHBOARD = "systrace_upload_to_dashboard"
# Keys for coverage
diff --git a/setup-angler.sh b/setup-angler.sh
deleted file mode 100755
index e662263..0000000
--- a/setup-angler.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#
-# 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.
-
-source setup.sh
-
-vts_multidevice_target_setup angler
diff --git a/setup-angler_treble.sh b/setup-angler_treble.sh
deleted file mode 100755
index 98762d8..0000000
--- a/setup-angler_treble.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#
-# 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.
-
-source setup.sh
-
-vts_multidevice_target_setup angler_treble
diff --git a/setup-bullhead.sh b/setup-bullhead.sh
deleted file mode 100755
index c8512dd..0000000
--- a/setup-bullhead.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-#
-# 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.
-
-source setup.sh
-
-vts_multidevice_target_setup bullhead
-
diff --git a/setup.sh b/setup.sh
index 4be362f..959b119 100755
--- a/setup.sh
+++ b/setup.sh
@@ -48,8 +48,8 @@
adb push ${ANDROID_BUILD_TOP}/out/host/linux-x86/vts/android-vts/testcases/DATA/lib64/libprotobuf-cpp-full.so /data/local/tmp/64/
echo "install vts drivers for hidl"
- adb push ${ANDROID_BUILD_TOP}/out/target/product/${DEVICE}/system/lib/android.hardware.*.vts.driver@1.0.so /data/local/tmp/32/
- adb push ${ANDROID_BUILD_TOP}/out/target/product/${DEVICE}/system/lib64/android.hardware.*.vts.driver@1.0.so /data/local/tmp/64/
+ adb push ${ANDROID_BUILD_TOP}/out/target/product/${DEVICE}/system/lib/android.hardware.*.vts.driver@*.so /data/local/tmp/32/
+ adb push ${ANDROID_BUILD_TOP}/out/target/product/${DEVICE}/system/lib64/android.hardware.*.vts.driver@*.so /data/local/tmp/64/
echo "install hal packages"
adb shell mkdir -p /data/local/tmp/32/hw
@@ -80,12 +80,11 @@
adb push ${ANDROID_BUILD_TOP}/test/vts/specification/hal_conventional/WifiHalV1.vts /data/local/tmp/spec/WifiHalV1.vts
adb push ${ANDROID_BUILD_TOP}/test/vts/specification/hal_conventional/BluetoothHalV1.vts /data/local/tmp/spec/BluetoothHalV1.vts
adb push ${ANDROID_BUILD_TOP}/test/vts/specification/hal_conventional/BluetoothHalV1bt_interface_t.vts /data/local/tmp/spec/BluetoothHalV1bt_interface_t.vts
- adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/nfc/1.0/vts/*.vts /data/local/tmp/spec/
- adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/vr/1.0/vts/Vr.vts /data/local/tmp/spec/Vr.vts
- adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/vehicle/2.0/vts/*.vts /data/local/tmp/spec/
- # uncomment to test TV CEC HAL
+ # adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/nfc/1.0/vts/*.vts /data/local/tmp/spec/
+ # adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/vr/1.0/vts/Vr.vts /data/local/tmp/spec/Vr.vts
+ # adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/vehicle/2.0/vts/*.vts /data/local/tmp/spec/
+ # adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/sensors/1.0/vts/*.vts /data/local/tmp/spec/
# adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/tv/cec/1.0/vts/*.vts /data/local/tmp/spec/
- # uncomment to test vibrator HAL
# adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/vibrator/1.0/vts/Vibrator.vts /data/local/tmp/spec/
# adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/vibrator/1.0/vts/types.vts /data/local/tmp/spec/
adb push ${ANDROID_BUILD_TOP}/test/vts/specification/lib_bionic/libmV1.vts /data/local/tmp/spec/libmV1.vts
diff --git a/tools/build/tasks/list/vts_bin_package_list.mk b/tools/build/tasks/list/vts_bin_package_list.mk
index 06ed482..04ee73a 100644
--- a/tools/build/tasks/list/vts_bin_package_list.mk
+++ b/tools/build/tasks/list/vts_bin_package_list.mk
@@ -17,3 +17,4 @@
vts_hal_agent \
vtssysfuzzer \
vts_shell_driver \
+ vts_profiling_configure \
diff --git a/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl-profiling-tv.xml b/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl-profiling-tv.xml
new file mode 100644
index 0000000..4ff26e8
--- /dev/null
+++ b/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl-profiling-tv.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<configuration description="Run New VTS Tests for HIDL HALs in the Staging environment">
+ <include name="everything" />
+ <option name="plan" value="vts" />
+ <option name="compatibility:include-filter" value="TvCecHidlProfilingTest" />
+ <option name="compatibility:include-filter" value="TvInputHidlProfilingTest" />
+ <template-include name="reporters" default="basic-reporters" />
+</configuration>
diff --git a/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl-tv.xml b/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl-tv.xml
index 147792d..c341a9a 100644
--- a/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl-tv.xml
+++ b/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl-tv.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 Google Inc.
+<!-- Copyright (C) 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.
diff --git a/utils/python/mirror/mirror_object.py b/utils/python/mirror/mirror_object.py
index e766b6f..51d0b12 100644
--- a/utils/python/mirror/mirror_object.py
+++ b/utils/python/mirror/mirror_object.py
@@ -619,5 +619,17 @@
raise MirrorObjectError("unknown api name %s" % api_name)
def GetRawCodeCoverage(self):
- """Returns any measured raw code coverage data."""
- return self._last_raw_code_coverage_data
+ """Returns any measured raw code coverage data."""
+ return self._last_raw_code_coverage_data
+
+ def __str__(self):
+ """Prints all the attributes and methods."""
+ result = ""
+ if self._if_spec_msg:
+ if self._if_spec_msg.attribute:
+ for attribute in self._if_spec_msg.attribute:
+ result += "attribute %s\n" % attribute.name
+ if self._if_spec_msg.api:
+ for api in self._if_spec_msg.api:
+ result += "api %s\n" % api.name
+ return result
diff --git a/utils/python/mirror/mirror_object_for_types.py b/utils/python/mirror/mirror_object_for_types.py
index 6932c4e..a4f2b54 100644
--- a/utils/python/mirror/mirror_object_for_types.py
+++ b/utils/python/mirror/mirror_object_for_types.py
@@ -143,7 +143,6 @@
if enumerator == type_name:
return copy.copy(attribute)
return None
- return None
except AttributeError as e:
# TODO: check in advance whether self._if_spec_msg Interface
# SpecificationMessage.
@@ -261,3 +260,16 @@
return ConstGenerator()
raise MirrorObjectError("unknown api name %s" % api_name)
+
+ def __str__(self):
+ """Prints all the attributes and methods."""
+ result = ""
+ if self._if_spec_msg:
+ if self._if_spec_msg.attribute:
+ for attribute in self._if_spec_msg.attribute:
+ result += "global attribute %s\n" % attribute.name
+ if self._if_spec_msg.interface.attribute:
+ for attribute in self._if_spec_msg.interface.attribute:
+ result += "interface attribute %s\n" % attribute.name
+ return result
+
diff --git a/utils/python/mirror/py2pb.py b/utils/python/mirror/py2pb.py
index 4eb99da..6a2e72b 100644
--- a/utils/python/mirror/py2pb.py
+++ b/utils/python/mirror/py2pb.py
@@ -194,13 +194,13 @@
if pb_spec.type == CompSpecMsg.TYPE_STRUCT:
PyDict2PbStruct(message, pb_spec, py_value)
- elif attr.type == CompSpecMsg.TYPE_ENUM:
+ elif pb_spec.type == CompSpecMsg.TYPE_ENUM:
PyValue2PbEnum(message, pb_spec, py_value)
- elif attr.type == CompSpecMsg.TYPE_SCALAR:
+ elif pb_spec.type == CompSpecMsg.TYPE_SCALAR:
PyValue2PbScalar(message, pb_spec, py_value)
- elif attr.type == CompSpecMsg.TYPE_STRING:
+ elif pb_spec.type == CompSpecMsg.TYPE_STRING:
PyStringPbString(attr_msg, attr, curr_value)
- elif attr.type == CompSpecMsg.TYPE_VECTOR:
+ elif pb_spec.type == CompSpecMsg.TYPE_VECTOR:
PyList2PbVector(message, pb_spec, py_value)
else:
logging.error("py2pb.Convert: unsupported type %s",
diff --git a/utils/python/systrace/systrace_controller.py b/utils/python/systrace/systrace_controller.py
index 4f5d6dc..1c8a54e 100644
--- a/utils/python/systrace/systrace_controller.py
+++ b/utils/python/systrace/systrace_controller.py
@@ -197,7 +197,7 @@
if self._path_output:
try:
- shutil.rmtree(self._path_output)
+ shutil.rmtree(os.path.basename(self._path_output))
except Exception as e:
logging.error('failed to remove systrace output file. %s', e)
return False
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/BaseServlet.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/BaseServlet.java
index cfd2466..c62bd55 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/BaseServlet.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/BaseServlet.java
@@ -1,3 +1,19 @@
+/*
+ * 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;
@@ -8,6 +24,7 @@
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.util.List;
import java.util.logging.Logger;
public abstract class BaseServlet extends HttpServlet {
@@ -21,7 +38,41 @@
// Common constants
protected static final long ONE_DAY = 86400000000L; // units microseconds
+ protected static final long MILLI_TO_MICRO = 1000; // conversion factor from milli to micro units
protected static final String TABLE_PREFIX = "result_";
+ protected static final String CURRENT_PAGE = "#";
+
+ public enum Page {
+ HOME ("VTS Dashboard Home", "/"),
+ PREFERENCES ("Preferences", "/show_preferences"),
+ TABLE ("", "/show_table"),
+ GRAPH ("Profiling", "/show_graph"),
+ COVERAGE ("Coverage", "/show_coverage"),
+ PERFORMANCE ("Performance Digest", "/show_performance_digest");
+
+ private final String name;
+ private final String url;
+
+ Page(String name, String url) {
+ this.name = name;
+ this.url = url;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+ }
+
+ /**
+ * Get a list of URL/Display name pairs for the navbar heirarchy.
+ * @param request The HttpServletRequest object for the page request.
+ * @return a list of 2-entried String arrays in the order [page url, page name]
+ */
+ public abstract List<String[]> getNavbarLinks(HttpServletRequest request);
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
@@ -29,7 +80,9 @@
// 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 loginURI = userService.createLoginURL(request.getRequestURI());
+ 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);
@@ -37,7 +90,9 @@
}
request.setAttribute("logoutURL", logoutURI);
request.setAttribute("email", currentUser.getEmail());
- request.setAttribute("analytics_id", new Gson().toJson(ANALYTICS_ID));
+ request.setAttribute("analyticsID", new Gson().toJson(ANALYTICS_ID));
+ request.setAttribute("navbarLinksJson", new Gson().toJson(getNavbarLinks(request)));
+ request.setAttribute("navbarLinks", getNavbarLinks(request));
response.setContentType("text/html");
doGetHandler(request, response);
}
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/DashboardMainServlet.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/DashboardMainServlet.java
index 40ec300..4d7b82c 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/DashboardMainServlet.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/DashboardMainServlet.java
@@ -46,7 +46,7 @@
*/
public class DashboardMainServlet extends BaseServlet {
- private static final String DASHBOARD_MAIN_JSP = "/dashboard_main.jsp";
+ 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 byte[] EMAIL_FAMILY = Bytes.toBytes("email_to_test");
@@ -60,6 +60,14 @@
private static final String UP_ARROW = "keyboard_arrow_up";
private static final String DOWN_ARROW = "keyboard_arrow_down";
+ @Override
+ public List<String[]> getNavbarLinks(HttpServletRequest request) {
+ List<String[]> links = new ArrayList<>();
+ Page root = Page.HOME;
+ String[] rootEntry = new String[]{CURRENT_PAGE, root.getName()};
+ links.add(rootEntry);
+ return links;
+ }
@Override
public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowCoverageServlet.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowCoverageServlet.java
index 8c98422..c6097ec 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowCoverageServlet.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowCoverageServlet.java
@@ -45,11 +45,34 @@
*/
public class ShowCoverageServlet extends BaseServlet {
+ private static final String COVERAGE_JSP = "WEB-INF/jsp/show_coverage.jsp";
private static final byte[] FAMILY = Bytes.toBytes("test");
private static final byte[] QUALIFIER = Bytes.toBytes("data");
private static final String ALL_TESTCASES_LABEL = "All";
@Override
+ public List<String[]> getNavbarLinks(HttpServletRequest request) {
+ List<String[]> links = new ArrayList<>();
+ Page root = Page.HOME;
+ String[] rootEntry = new String[]{root.getUrl(), root.getName()};
+ links.add(rootEntry);
+
+ Page table = Page.TABLE;
+ String testName = request.getParameter("testName");
+ String name = table.getName() + testName;
+ String url = table.getUrl() + "?testName=" + testName;
+ String[] tableEntry = new String[]{url, name};
+ links.add(tableEntry);
+
+ Page coverage = Page.COVERAGE;
+ String startTime = request.getParameter("startTime");
+ url = coverage.getUrl() + "?testName=" + testName + "&startTime=" + startTime;
+ String[] coverageEntry = new String[]{url, coverage.getName()};
+ links.add(coverageEntry);
+ return links;
+ }
+
+ @Override
public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
throws IOException {
RequestDispatcher dispatcher = null;
@@ -57,15 +80,13 @@
TableName tableName = null;
tableName = TableName.valueOf(TABLE_PREFIX + request.getParameter("testName"));
- // key is a unique combination of build Id and timestamp that helps identify the
- // corresponding build id.
- String key = request.getParameter("key");
+ String timeString = request.getParameter("startTime");
Scan scan = new Scan();
long time = -1;
try {
- time = Long.parseLong(key);
- scan.setStartRow(key.getBytes());
- scan.setStopRow(Long.toString((time + 1)).getBytes());
+ time = Long.parseLong(timeString);
+ scan.setStartRow(Long.toString(time - 1).getBytes());
+ scan.setStopRow(Long.toString(time).getBytes());
} catch (NumberFormatException e) { } // Use unbounded scan
TestReportMessage testReportMessage = null;
@@ -80,7 +101,7 @@
// filter empty build IDs and add only numbers
if (buildId.length() > 0) {
- if (time == currentTestReportMessage.getStartTimestamp()) {
+ if (time == currentTestReportMessage.getStartTimestamp() * MILLI_TO_MICRO) {
testReportMessage = currentTestReportMessage;
break;
}
@@ -166,8 +187,7 @@
request.setAttribute("indicators", new Gson().toJson(indicators));
request.setAttribute("sectionMap", new Gson().toJson(sectionMap));
request.setAttribute("startTime", request.getParameter("startTime"));
- request.setAttribute("endTime", request.getParameter("endTime"));
- dispatcher = request.getRequestDispatcher("/show_coverage.jsp");
+ dispatcher = request.getRequestDispatcher(COVERAGE_JSP);
try {
dispatcher.forward(request, response);
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowGraphServlet.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowGraphServlet.java
index c26c753..0034189 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowGraphServlet.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowGraphServlet.java
@@ -54,6 +54,7 @@
*/
public class ShowGraphServlet extends BaseServlet {
+ private static final String GRAPH_JSP = "WEB-INF/jsp/show_graph.jsp";
private static final byte[] FAMILY = Bytes.toBytes("test");
private static final byte[] QUALIFIER = Bytes.toBytes("data");
@@ -63,8 +64,27 @@
new HashSet<String>(Arrays.asList(splitKeysArray));
private static final String PROFILING_DATA_ALERT = "No profiling data was found.";
+ @Override
+ public List<String[]> getNavbarLinks(HttpServletRequest request) {
+ List<String[]> links = new ArrayList<>();
+ Page root = Page.HOME;
+ String[] rootEntry = new String[]{root.getUrl(), root.getName()};
+ links.add(rootEntry);
- private static final long MILLI_TO_MICRO = 1000; // conversion factor from milli to micro units
+ Page table = Page.TABLE;
+ String testName = request.getParameter("testName");
+ String name = table.getName() + testName;
+ String url = table.getUrl() + "?testName=" + testName;
+ String[] tableEntry = new String[]{url, name};
+ links.add(tableEntry);
+
+ Page graph = Page.GRAPH;
+ String profilingPointName = request.getParameter("profilingPoint");
+ url = graph.getUrl() + "?testName=" + testName + "&profilingPoint=" + profilingPointName;
+ String[] graphEntry = new String[]{url, graph.getName()};
+ links.add(graphEntry);
+ return links;
+ }
/**
* Process a profiling report message and determine which line graph to insert the point into.
@@ -195,7 +215,7 @@
request.setAttribute("graphs", gson.toJson(graphList));
request.setAttribute("profilingPointName", profilingPointName);
- dispatcher = request.getRequestDispatcher("/show_graph.jsp");
+ dispatcher = request.getRequestDispatcher(GRAPH_JSP);
try {
dispatcher.forward(request, response);
} catch (ServletException e) {
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java
index cb184e4..6437e21 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java
@@ -40,8 +40,8 @@
*/
public class ShowPerformanceDigestServlet extends BaseServlet {
+ private static final String PERF_DIGEST_JSP = "WEB-INF/jsp/show_performance_digest.jsp";
private static final int N_DIGITS = 2;
- private static final long MILLI_TO_MICRO = 1000; // conversion factor from milli to micro units
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));
@@ -54,6 +54,27 @@
private static final String LOWER_IS_BETTER = "Note: Lower values are better. Minimum is the best-case performance.";
private static final String STD = "Std";
+ @Override
+ public List<String[]> getNavbarLinks(HttpServletRequest request) {
+ List<String[]> links = new ArrayList<>();
+ Page root = Page.HOME;
+ String[] rootEntry = new String[]{root.getUrl(), root.getName()};
+ links.add(rootEntry);
+
+ Page table = Page.TABLE;
+ String testName = request.getParameter("testName");
+ String name = table.getName() + testName;
+ String url = table.getUrl() + "?testName=" + testName;
+ String[] tableEntry = new String[]{url, name};
+ links.add(tableEntry);
+
+ Page perf = Page.PERFORMANCE;
+ url = perf.getUrl() + "?testName=" + testName;
+ String[] perfEntry = new String[]{url, perf.getName()};
+ links.add(perfEntry);
+ return links;
+ }
+
/**
* Generates an HTML summary of the performance changes for the profiling results in the
* specified table.
@@ -225,7 +246,7 @@
request.setAttribute("selectedDevice", selectedDevice);
request.setAttribute("devices", devices);
- dispatcher = request.getRequestDispatcher("/show_performance_digest.jsp");
+ dispatcher = request.getRequestDispatcher(PERF_DIGEST_JSP);
try {
dispatcher.forward(request, response);
} catch (ServletException e) {
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowPreferencesServlet.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowPreferencesServlet.java
index 31f3716..db3b3f6 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowPreferencesServlet.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowPreferencesServlet.java
@@ -48,12 +48,24 @@
*/
public class ShowPreferencesServlet extends BaseServlet {
- private static final String PREFERENCES_JSP = "/show_preferences.jsp";
+ private static final String PREFERENCES_JSP = "WEB-INF/jsp/show_preferences.jsp";
private static final String DASHBOARD_MAIN_LINK = "/";
private static final byte[] EMAIL_FAMILY = Bytes.toBytes("email_to_test");
private static final byte[] TEST_FAMILY = Bytes.toBytes("test_to_email");
private static final String STATUS_TABLE = "vts_status_table";
+ @Override
+ public List<String[]> getNavbarLinks(HttpServletRequest request) {
+ List<String[]> links = new ArrayList<>();
+ Page root = Page.HOME;
+ String[] rootEntry = new String[]{root.getUrl(), root.getName()};
+ links.add(rootEntry);
+
+ Page prefs = Page.PREFERENCES;
+ String[] prefsEntry = new String[]{CURRENT_PAGE, prefs.getName()};
+ links.add(prefsEntry);
+ return links;
+ }
@Override
public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowTableServlet.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowTableServlet.java
index 136778c..0aa5a2b 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowTableServlet.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowTableServlet.java
@@ -58,6 +58,7 @@
*/
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.";
@@ -78,6 +79,22 @@
private static final byte[] FAMILY = Bytes.toBytes("test");
private static final byte[] QUALIFIER = Bytes.toBytes("data");
+ @Override
+ public List<String[]> getNavbarLinks(HttpServletRequest request) {
+ List<String[]> links = new ArrayList<>();
+ Page root = Page.HOME;
+ String[] rootEntry = new String[]{root.getUrl(), root.getName()};
+ links.add(rootEntry);
+
+ Page table = Page.TABLE;
+ String testName = request.getParameter("testName");
+ String name = table.getName() + testName;
+ String url = table.getUrl() + "?testName=" + testName;
+ String[] tableEntry = new String[]{url, name};
+ links.add(tableEntry);
+ return links;
+ }
+
/**
* Parse the search string to populate the searchPairs map and the generalTerms set.
* General terms apply to any field, while pairs in searchPairs are for a particular field.
@@ -508,10 +525,8 @@
double coveragePct = Math.round((100 * coveredLineCount /
totalLineCount) * 100f) / 100f;
coveragePctInfo = Double.toString(coveragePct) + "%" +
- "<a href=\"/show_coverage?key=" + report.getStartTimestamp() +
- "&testName=" + request.getParameter("testName") +
- "&startTime=" + startTime +
- "&endTime=" + endTime +
+ "<a href=\"/show_coverage?testName=" + request.getParameter("testName") +
+ "&startTime=" + (report.getStartTimestamp() * MILLI_TO_MICRO) +
"\" class=\"waves-effect waves-light btn red right coverage-btn\">" +
"<i class=\"material-icons coverage-icon\">menu</i></a>";
coverageInfo = coveredLineCount + "/" + totalLineCount;
@@ -579,7 +594,7 @@
request.setAttribute("showPresubmit", showPresubmit);
request.setAttribute("showPostsubmit", showPostsubmit);
- dispatcher = request.getRequestDispatcher("/show_table.jsp");
+ dispatcher = request.getRequestDispatcher(TABLE_JSP);
try {
dispatcher.forward(request, response);
} catch (ServletException e) {
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java
index 5735df8..05edd67 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java
@@ -63,9 +63,13 @@
private static final byte[] DATA_QUALIFIER = Bytes.toBytes("data");
private static final byte[] TIME_QUALIFIER = Bytes.toBytes("upload_timestamp");
private static final String STATUS_TABLE = "vts_status_table";
- private static final long MILLI_TO_MICRO = 1000; // conversion factor from milli to micro units
private static final long THREE_MINUTES = 180000000L; // units microseconds
+ @Override
+ public List<String[]> getNavbarLinks(HttpServletRequest request) {
+ return null;
+ }
+
/**
* Checks whether any new failures have occurred beginning since (and including) startTime.
* @param tableName The name of the table that stores the results for a test, string.
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java
index 111f99a..26985e6 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java
@@ -45,7 +45,6 @@
private static final String STATUS_TABLE = "vts_status_table";
private static final int N_DIGITS = 2;
- private static final long MILLI_TO_MICRO = 1000; // conversion factor from milli to micro units
private static final String MEAN = "Mean";
private static final String MAX = "Max";
@@ -66,6 +65,11 @@
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;";
+ @Override
+ public List<String[]> getNavbarLinks(HttpServletRequest request) {
+ return null;
+ }
+
/**
* Generates an HTML summary of the performance changes for the profiling results in the
* specified table.
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/dashboard_main.jsp b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/dashboard_main.jsp
new file mode 100644
index 0000000..52eddbe
--- /dev/null
+++ b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/dashboard_main.jsp
@@ -0,0 +1,63 @@
+<%--
+ ~ 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" %>
+ <body>
+ <div class='container'>
+ <div class='row' id='options'>
+ <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>
+ <div class='col s12'>
+ <h4 id='section-header'>${headerLabel}</h4>
+ </div>
+ <c:forEach items='${testNames}' var='test'>
+ <a href='${pageContext.request.contextPath}/show_table?testName=${test}'>
+ <div class='col s12 card hoverable option valign-wrapper waves-effect'>
+ <span class='entry valign'>${test}</span>
+ </div>
+ </a>
+ </c:forEach>
+ </c:otherwise>
+ </c:choose>
+ </div>
+ <div class='row center-align'>
+ <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>
+ </div>
+ <c:if test='${not showAll}'>
+ <div id='edit-button-wrapper' class='fixed-action-btn'>
+ <a href='/show_preferences' id='edit-button' class='btn-floating btn-large red waves-effect'>
+ <i class='large material-icons'>mode_edit</i>
+ </a>
+ </div>
+ </c:if>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/footer.jsp b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/footer.jsp
new file mode 100644
index 0000000..ed2d950
--- /dev/null
+++ b/web/dashboard/appengine/servlet/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/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/header.jsp b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/header.jsp
new file mode 100644
index 0000000..1978511
--- /dev/null
+++ b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/header.jsp
@@ -0,0 +1,61 @@
+<%--
+ ~ 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='/css/navbar.css'>
+ <link rel='stylesheet' href='/css/common.css'>
+ <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'>
+ <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.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');
+ }
+ links = ${navbarLinksJson};
+ </script>
+ <title>VTS Dashboard</title>
+</head>
+<body>
+ <nav id='navbar'>
+ <div class='nav-wrapper'>
+ <span>
+ <c:forEach items='${navbarLinks}' var='link'>
+ <a href='${link[0]}' class='breadcrumb'>${link[1]}</a>
+ </c:forEach>
+ </span>
+ <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>
+ </div>
+ </div>
+ </nav>
+</body>
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/show_coverage.jsp b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_coverage.jsp
similarity index 76%
rename from web/dashboard/appengine/servlet/src/main/webapp/show_coverage.jsp
rename to web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_coverage.jsp
index ea878d0..e3388f1 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/show_coverage.jsp
+++ b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_coverage.jsp
@@ -13,26 +13,16 @@
~ 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"%>
-
+<%@ 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>
- <head>
- <title>Coverage Information</title>
- <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="https://www.gstatic.com/external_hosted/materialize/all_styles-bundle.css">
- <link rel="stylesheet" href="/css/navbar.css">
- <link rel="stylesheet" href="/css/show_coverage.css">
- <script src='/js/analytics.js' type='text/javascript'></script>
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
- <script src="https://www.gstatic.com/external_hosted/materialize/materialize.min.js"></script>
- <script src="https://apis.google.com/js/api.js" type="text/javascript"></script>
+ <%@ 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">
- if (${analytics_id}) analytics_init(${analytics_id});
var coverageVectors = ${coverageVectors};
$(document).ready(function() {
// Initialize AJAX for CORS
@@ -171,32 +161,8 @@
}).find('.collapsible-header').click(onClick);
}
</script>
- <nav id="navbar">
- <div class="nav-wrapper">
- <span>
- <a href="${pageContext.request.contextPath}/" class="breadcrumb">VTS Dashboard Home</a>
- <a href="${pageContext.request.contextPath}/show_table?testName=${testName}&startTime=${startTime}&endTime=${endTime}" class="breadcrumb">${testName}</a>
- <a href="#!" class="breadcrumb">Coverage</a>
- </span>
- <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>
- </div>
- </nav>
- </head>
- <body>
- <div id="coverage-container" class="container">
+ <div id='coverage-container' class='wide container'>
</div>
- <footer class="page-footer">
- <div class="footer-copyright">
- <div class="container">© 2016 - The Android Open Source Project
- </div>
- </div>
- </footer>
+ <%@ include file="footer.jsp" %>
</body>
</html>
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_graph.jsp b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_graph.jsp
new file mode 100644
index 0000000..8b8aef4
--- /dev/null
+++ b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_graph.jsp
@@ -0,0 +1,257 @@
+<%--
+ ~ 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;
+
+ $(function() {
+ $('select').material_select();
+ var date = $('#date').datepicker({
+ showAnim: 'slideDown',
+ maxDate: new Date()
+ });
+ date.datepicker('setDate', new Date(${startTime} / MICRO_PER_MILLI));
+ $('#load').click(load);
+ });
+
+ // Draw all graphs.
+ function drawAllGraphs() {
+ var graphs = ${graphs};
+ graphs.forEach(function(graph) {
+ if (graph.type == 'LINE_GRAPH') drawLineGraph(graph);
+ else if (graph.type == 'HISTOGRAM') drawHistogram(graph);
+ });
+ }
+
+ /**
+ * 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) {
+ var title = 'Performance';
+ if (lineGraph.name) title += ' (' + lineGraph.name + ')';
+ if (lineGraph.ticks.length < 1) {
+ return;
+ }
+ 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
+ */
+ function drawHistogram(hist) {
+ test = hist;
+ var title = 'Performance';
+ if (hist.name) title += ' (' + hist.name + ')';
+ var values = hist.values;
+ var histogramData = values.map(function(d, i) {
+ return [hist.ids[i], d];
+ });
+ var min = Math.min.apply(null, values),
+ max = Math.max.apply(null, values);
+
+ var histogramTicks = new Array(10);
+ var delta = (max - min) / 10;
+ for (var i = 0; i <= 10; i++) {
+ histogramTicks[i] = Math.round(min + delta * i);
+ }
+
+ var data = google.visualization.arrayToDataTable(histogramData, true);
+
+ 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: {
+ ticks: histogramTicks,
+ title: hist.x_label,
+ textStyle: {
+ fontSize: 12,
+ color: '#757575'
+ },
+ titleTextStyle: {
+ color: '#424242',
+ fontSize: 12,
+ italic: false
+ }
+ },
+ bar: { gap: 0 },
+ histogram: {
+ maxNumBuckets: 200,
+ minValue: min * 0.95,
+ maxValue: max * 1.05
+ },
+ chartArea: {
+ width: '100%',
+ top: 40,
+ left: 50,
+ height: '80%'
+ }
+ };
+ 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 startTime = $('#date').datepicker('getDate').getTime();
+ startTime = startTime + (ONE_DAY / MICRO_PER_MILLI) - 1;
+ var ctx = '${pageContext.request.contextPath}';
+ var link = ctx + '/show_graph?profilingPoint=${profilingPointName}' +
+ '&testName=${testName}' +
+ '&startTime=' + (startTime * MICRO_PER_MILLI);
+ 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'>
+ <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'>
+ <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 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/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_performance_digest.jsp b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_performance_digest.jsp
new file mode 100644
index 0000000..224d847
--- /dev/null
+++ b/web/dashboard/appengine/servlet/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/web/dashboard/appengine/servlet/src/main/webapp/show_preferences.jsp b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_preferences.jsp
similarity index 78%
rename from web/dashboard/appengine/servlet/src/main/webapp/show_preferences.jsp
rename to web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_preferences.jsp
index ced594e..b41ea06 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/show_preferences.jsp
+++ b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_preferences.jsp
@@ -1,4 +1,3 @@
-<%-- //[START all]--%>
<%--
~ Copyright (c) 2016 Google Inc. All Rights Reserved.
~
@@ -18,40 +17,12 @@
<%@ 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='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='https://www.gstatic.com/external_hosted/materialize/all_styles-bundle.css'>
- <link rel='stylesheet' href='/css/navbar.css'>
+ <%@ include file="header.jsp" %>
<link rel='stylesheet' href='/css/show_preferences.css'>
- <script src='/js/analytics.js' type='text/javascript'></script>
- <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
- <script src='https://www.gstatic.com/external_hosted/materialize/materialize.min.js'></script>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js'></script>
- <head>
- <title>VTS Dashboard</title>
-
- <nav id='navbar'>
- <div class='nav-wrapper'>
- <span>
- <a href='/' class='breadcrumb'>VTS Dashboard Home</a>
- <a href='#!' class='breadcrumb'>Preferences</a>
- </span>
- <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>
- </div>
- </div>
- </nav>
+ <body>
<script>
- if (${analytics_id}) analytics_init(${analytics_id});
var subscribedSet = new Set(${subscribedTestsJson});
var displayedSet = new Set(${subscribedTestsJson});
var allTests = ${allTestsJson};
@@ -141,9 +112,6 @@
$('#save-button-wrapper').hide();
});
</script>
- </head>
-
- <body>
<div class='container'>
<div class='row'>
<h3 class='col s12 header'>Favorites</h3>
@@ -181,13 +149,6 @@
<i class='large material-icons'>done</i>
</a>
</div>
- <footer class='page-footer'>
- <div class='footer-copyright'>
- <div class='container'>
- © 2016 - The Android Open Source Project
- </div>
- </div>
- </footer>
+ <%@ include file="footer.jsp" %>
</body>
</html>
-<%-- //[END all]--%>
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/show_table.jsp b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_table.jsp
similarity index 86%
rename from web/dashboard/appengine/servlet/src/main/webapp/show_table.jsp
rename to web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_table.jsp
index d888a9b..a527de0 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/show_table.jsp
+++ b/web/dashboard/appengine/servlet/src/main/webapp/WEB-INF/jsp/show_table.jsp
@@ -18,21 +18,11 @@
<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
<html>
- <head>
- <title>VTS Table</title>
- <link rel='icon' href='//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='https://www.gstatic.com/external_hosted/materialize/all_styles-bundle.css'>
- <link type='text/css' href='/css/navbar.css' rel='stylesheet'>
- <link type='text/css' href='/css/show_table.css' rel='stylesheet'>
- <script src='/js/analytics.js' type='text/javascript'></script>
- <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
- <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
- <script src='https://www.gstatic.com/external_hosted/materialize/materialize.min.js'></script>
- <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script>
- <script type='text/javascript'>
- if (${analytics_id}) analytics_init(${analytics_id});
+ <%@ include file="header.jsp" %>
+ <link type='text/css' href='/css/show_table.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 type='text/javascript'>
google.charts.load('current', {'packages':['table', 'corechart']});
google.charts.setOnLoadCallback(drawGridTable);
google.charts.setOnLoadCallback(drawProfilingTable);
@@ -244,28 +234,10 @@
};
table.draw(data, options);
}
- </script>
-
- <nav id='navbar'>
- <div class='nav-wrapper'>
- <span>
- <a href='${pageContext.request.contextPath}/' class='breadcrumb'>VTS Dashboard Home</a>
- <a href='#!' class='breadcrumb'>${testName}</a>
- </span>
- <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>
- </div>
- </nav>
- </head>
+ </script>
<body>
- <div class='container'>
+ <div class='wide container'>
<div class='row'>
<div class='col s12'>
<div class='card' id='filter-wrapper'>
@@ -369,11 +341,6 @@
<a href="#!" class="modal-action modal-close waves-effect btn-flat">Close</a>
</div>
</div>
- <footer class='page-footer'>
- <div class='footer-copyright'>
- <div class='container'>© 2016 - The Android Open Source Project
- </div>
- </div>
- </footer>
+ <%@ include file="footer.jsp" %>
</body>
</html>
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/css/common.css b/web/dashboard/appengine/servlet/src/main/webapp/css/common.css
new file mode 100644
index 0000000..974f129
--- /dev/null
+++ b/web/dashboard/appengine/servlet/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/web/dashboard/appengine/servlet/src/main/webapp/css/dashboard_main.css b/web/dashboard/appengine/servlet/src/main/webapp/css/dashboard_main.css
index 0e5fa02..aa18c5f 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/css/dashboard_main.css
+++ b/web/dashboard/appengine/servlet/src/main/webapp/css/dashboard_main.css
@@ -12,9 +12,6 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
-.container {
- min-height: 85%;
-}
#edit-button-wrapper {
bottom: 25px;
@@ -32,7 +29,7 @@
text-align: center;
}
-.card.option {
+.row .col.s12.card.option {
padding: 10px 30px;
margin: 8px;
}
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/css/show_coverage.css b/web/dashboard/appengine/servlet/src/main/webapp/css/show_coverage.css
index 6c530bf..c187fd3 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/css/show_coverage.css
+++ b/web/dashboard/appengine/servlet/src/main/webapp/css/show_coverage.css
@@ -13,17 +13,6 @@
limitations under the License.
*/
-@media only screen and (min-width: 993px) {
- .container {
- width: 80%;
- max-width: 1600px;
- }
-}
-
-.container {
- min-height: 80%;
-}
-
.collapsible.popout {
margin-bottom: 50px;
}
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/css/show_performance_digest.css b/web/dashboard/appengine/servlet/src/main/webapp/css/show_performance_digest.css
index 8884392..5d0c0e6 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/css/show_performance_digest.css
+++ b/web/dashboard/appengine/servlet/src/main/webapp/css/show_performance_digest.css
@@ -13,17 +13,6 @@
limitations under the License.
*/
-@media only screen and (min-width: 993px) {
- .container {
- width: 80%;
- max-width: 1600px;
- }
-}
-
-.container {
- min-height: 85%;
-}
-
#header-container {
padding: 25px;
}
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/css/show_preferences.css b/web/dashboard/appengine/servlet/src/main/webapp/css/show_preferences.css
index 55920df..9731037 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/css/show_preferences.css
+++ b/web/dashboard/appengine/servlet/src/main/webapp/css/show_preferences.css
@@ -12,9 +12,6 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
-.container {
- min-height: 85%;
-}
.card.option {
padding: 10px 30px;
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/css/show_table.css b/web/dashboard/appengine/servlet/src/main/webapp/css/show_table.css
index 5d8f749..7a82ae9 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/css/show_table.css
+++ b/web/dashboard/appengine/servlet/src/main/webapp/css/show_table.css
@@ -12,12 +12,6 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
-@media only screen and (min-width: 993px) {
- .container {
- width: 80%;
- max-width: 1600px;
- }
-}
table {
font-family: Roboto !important;
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/dashboard_main.jsp b/web/dashboard/appengine/servlet/src/main/webapp/dashboard_main.jsp
deleted file mode 100644
index 5b799d6..0000000
--- a/web/dashboard/appengine/servlet/src/main/webapp/dashboard_main.jsp
+++ /dev/null
@@ -1,103 +0,0 @@
-<%-- //[START all]--%>
-<%--
- ~ 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='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='https://www.gstatic.com/external_hosted/materialize/all_styles-bundle.css'>
- <link rel='stylesheet' href='/css/navbar.css'>
- <link rel='stylesheet' href='/css/dashboard_main.css'>
- <script src='/js/analytics.js' type='text/javascript'></script>
- <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
- <script src='https://www.gstatic.com/external_hosted/materialize/materialize.min.js'></script>
- <script>
- if (${analytics_id}) analytics_init(${analytics_id});
- </script>
- <head>
- <title>VTS Dashboard</title>
-
- <nav id='navbar'>
- <div class='nav-wrapper'>
- <span>
- <a href='#!' class='breadcrumb'>VTS Dashboard Home</a>
- </span>
- <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>
- </div>
- </div>
- </nav>
- </head>
-
- <body>
- <div class='container'>
- <div class='row' id='options'>
- <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>
- <div class='col s12'>
- <h4 id='section-header'>${headerLabel}</h4>
- </div>
- <c:forEach items='${testNames}' var='test'>
- <a href='${pageContext.request.contextPath}/show_table?testName=${test}'>
- <div class='col s12 card hoverable option valign-wrapper waves-effect'>
- <span class='entry valign'>${test}</span>
- </div>
- </a>
- </c:forEach>
- </c:otherwise>
- </c:choose>
- </div>
- <div class='row center-align'>
- <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>
- </div>
- <c:if test='${not showAll}'>
- <div id='edit-button-wrapper' class='fixed-action-btn'>
- <a href='/show_preferences' id='edit-button' class='btn-floating btn-large red waves-effect'>
- <i class='large material-icons'>mode_edit</i>
- </a>
- </div>
- </c:if>
- <footer class='page-footer'>
- <div class='footer-copyright'>
- <div class='container'>
- © 2016 - The Android Open Source Project
- </div>
- </div>
- </footer>
- </body>
-</html>
-<%-- //[END all]--%>
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/js/analytics.js b/web/dashboard/appengine/servlet/src/main/webapp/js/analytics.js
deleted file mode 100644
index 94a5350..0000000
--- a/web/dashboard/appengine/servlet/src/main/webapp/js/analytics.js
+++ /dev/null
@@ -1,10 +0,0 @@
-function analytics_init (id) {
- // 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', id, 'auto');
- ga('send', 'pageview');
-}
\ No newline at end of file
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/show_graph.jsp b/web/dashboard/appengine/servlet/src/main/webapp/show_graph.jsp
deleted file mode 100644
index e9b8301..0000000
--- a/web/dashboard/appengine/servlet/src/main/webapp/show_graph.jsp
+++ /dev/null
@@ -1,286 +0,0 @@
-<%--
- ~ 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="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
-<html>
- <head>
- <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='https://www.gstatic.com/external_hosted/materialize/all_styles-bundle.css'>
- <link type='text/css' href='/css/navbar.css' rel='stylesheet'>
- <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 src='/js/analytics.js' type='text/javascript'></script>
- <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
- <script src='https://www.gstatic.com/external_hosted/materialize/materialize.min.js'></script>
- <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>
- <script src='/js/analytics.js' type='text/javascript'></script>
- <title>Graph</title>
- <script type='text/javascript'>
- if (${analytics_id}) analytics_init(${analytics_id});
- google.charts.load('current', {packages:['corechart', 'table', 'line']});
- google.charts.setOnLoadCallback(drawAllGraphs);
-
- ONE_DAY = 86400000000;
- MICRO_PER_MILLI = 1000;
-
- $(function() {
- $('select').material_select();
- var date = $('#date').datepicker({
- showAnim: 'slideDown',
- maxDate: new Date()
- });
- date.datepicker('setDate', new Date(${startTime} / MICRO_PER_MILLI));
- $('#load').click(load);
- });
-
- // Draw all graphs.
- function drawAllGraphs() {
- var graphs = ${graphs};
- graphs.forEach(function(graph) {
- if (graph.type == 'LINE_GRAPH') drawLineGraph(graph);
- else if (graph.type == 'HISTOGRAM') drawHistogram(graph);
- });
- }
-
- /**
- * 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) {
- var title = 'Performance';
- if (lineGraph.name) title += ' (' + lineGraph.name + ')';
- if (lineGraph.ticks.length < 1) {
- return;
- }
- 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
- */
- function drawHistogram(hist) {
- test = hist;
- var title = 'Performance';
- if (hist.name) title += ' (' + hist.name + ')';
- var values = hist.values;
- var histogramData = values.map(function(d, i) {
- return [hist.ids[i], d];
- });
- var min = Math.min.apply(null, values),
- max = Math.max.apply(null, values);
-
- var histogramTicks = new Array(10);
- var delta = (max - min) / 10;
- for (var i = 0; i <= 10; i++) {
- histogramTicks[i] = Math.round(min + delta * i);
- }
-
- var data = google.visualization.arrayToDataTable(histogramData, true);
-
- 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: {
- ticks: histogramTicks,
- title: hist.x_label,
- textStyle: {
- fontSize: 12,
- color: '#757575'
- },
- titleTextStyle: {
- color: '#424242',
- fontSize: 12,
- italic: false
- }
- },
- bar: { gap: 0 },
- histogram: {
- maxNumBuckets: 200,
- minValue: min * 0.95,
- maxValue: max * 1.05
- },
- chartArea: {
- width: '100%',
- top: 40,
- left: 50,
- height: '80%'
- }
- };
- 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 startTime = $('#date').datepicker('getDate').getTime();
- startTime = startTime + (ONE_DAY / MICRO_PER_MILLI) - 1;
- var ctx = '${pageContext.request.contextPath}';
- var link = ctx + '/show_graph?profilingPoint=${profilingPointName}' +
- '&testName=${testName}' +
- '&startTime=' + (startTime * MICRO_PER_MILLI);
- if ($('#device-select').prop('selectedIndex') > 1) {
- link += '&device=' + $('#device-select').val();
- }
- window.open(link,'_self');
- }
-
- </script>
- <nav id='navbar'>
- <div class='nav-wrapper'>
- <span>
- <a href='${pageContext.request.contextPath}/' class='breadcrumb'>VTS Dashboard Home</a>
- <a href='${pageContext.request.contextPath}/show_table?testName=${testName}&startTime=${startTime}' class='breadcrumb'>${testName}</a>
- <a href='#!' class='breadcrumb'>Profiling</a>
- </span>
- <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>
- </div>
- </nav>
- </head>
-
- <body>
- <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'>
- <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'>
- <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 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>
- </body>
-</html>
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/show_performance_digest.jsp b/web/dashboard/appengine/servlet/src/main/webapp/show_performance_digest.jsp
deleted file mode 100644
index affe4c3..0000000
--- a/web/dashboard/appengine/servlet/src/main/webapp/show_performance_digest.jsp
+++ /dev/null
@@ -1,138 +0,0 @@
-<%--
- ~ 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>
- <head>
- <title>VTS Table</title>
- <link rel='icon' href='//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='https://www.gstatic.com/external_hosted/materialize/all_styles-bundle.css'>
- <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.css">
- <link type='text/css' href='/css/navbar.css' rel='stylesheet'>
- <link type="text/css" href="/css/datepicker.css" rel="stylesheet">
- <link type='text/css' href='/css/show_performance_digest.css' rel='stylesheet'>
- <script src='/js/analytics.js' type='text/javascript'></script>
- <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
- <script src='https://www.gstatic.com/external_hosted/materialize/materialize.min.js'></script>
- <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>
- <script type='text/javascript'>
- if (${analytics_id}) analytics_init(${analytics_id});
-
- 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>
-
- <nav id='navbar'>
- <div class='nav-wrapper'>
- <span>
- <a href='${pageContext.request.contextPath}/' class='breadcrumb'>VTS Dashboard Home</a>
- <a href='${pageContext.request.contextPath}/show_table?testName=${testName}' class='breadcrumb'>${testName}</a>
- <a href="#!" class="breadcrumb">Performance Digest</a>
- </span>
- <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>
- </div>
- </nav>
- </head>
-
- <body>
- <div class='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>
-
- <footer class='page-footer'>
- <div class='footer-copyright'>
- <div class='container'>© 2016 - The Android Open Source Project
- </div>
- </div>
- </footer>
- </body>
-</html>
diff --git a/web/dashboard/appengine/servlet/src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java b/web/dashboard/appengine/servlet/src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java
index e23d30f..24db08a 100644
--- a/web/dashboard/appengine/servlet/src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java
+++ b/web/dashboard/appengine/servlet/src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java
@@ -1,3 +1,19 @@
+/*
+ * 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.*;
diff --git a/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/MathUtilTest.java b/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/MathUtilTest.java
index e8532b9..766ba0b 100644
--- a/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/MathUtilTest.java
+++ b/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/MathUtilTest.java
@@ -1,3 +1,19 @@
+/*
+ * 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.*;
diff --git a/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java b/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java
index 2bdcd47..a83b2c5 100644
--- a/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java
+++ b/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java
@@ -1,3 +1,19 @@
+/*
+ * 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.*;
diff --git a/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/StatSummaryTest.java b/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/StatSummaryTest.java
index b262c0f..846c354 100644
--- a/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/StatSummaryTest.java
+++ b/web/dashboard/appengine/servlet/src/test/java/com/android/vts/util/StatSummaryTest.java
@@ -1,3 +1,19 @@
+/*
+ * 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.*;