Merge "Ability to register controller without starting vts services. Enable HwBinderBinerizePerformanceAdbTest."
diff --git a/tools/build/tasks/list/vts_test_lib_hidl_package_list.mk b/tools/build/tasks/list/vts_test_lib_hidl_package_list.mk
index 26cc79c..e62a88a 100644
--- a/tools/build/tasks/list/vts_test_lib_hidl_package_list.mk
+++ b/tools/build/tasks/list/vts_test_lib_hidl_package_list.mk
@@ -48,6 +48,7 @@
 
 vts_test_lib_hidl_packages += \
   audio_effect_hidl_hal_test \
+  bluetooth_hidl_hal_test \
   boot_hidl_hal_test \
   graphics_allocator_hidl_hal_test \
   graphics_mapper_hidl_hal_test \
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 c195fd1..2dfafaf 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
@@ -23,7 +23,6 @@
 import com.android.vts.util.PerformanceUtil.TimeInterval;
 import com.android.vts.util.ProfilingPointSummary;
 import com.android.vts.util.StatSummary;
-import com.google.gson.Gson;
 import com.google.protobuf.ByteString;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -214,6 +213,7 @@
         RequestDispatcher dispatcher = null;
         String testName = request.getParameter("testName");
         String tableName = TABLE_PREFIX + testName;
+        String selectedDevice = request.getParameter("device");
         Long startTime = null;
         if (request.getParameter("startTime") != null) {
             String time = request.getParameter("startTime");
@@ -250,7 +250,7 @@
         String sectionLabels = "";
         int i = 0;
         for (TimeInterval interval : timeIntervals) {
-            PerformanceSummary perfSummary = new PerformanceSummary();
+            PerformanceSummary perfSummary = new PerformanceSummary(selectedDevice);
             PerformanceUtil.updatePerformanceSummary(tableName, interval.start, interval.end, perfSummary);
             if (perfSummary.size() == 0) continue;
             perfSummaries.add(perfSummary);
@@ -289,6 +289,7 @@
             }
         }
 
+        if (!deviceSet.contains(selectedDevice)) selectedDevice = null;
         String[] devices = deviceSet.toArray(new String[deviceSet.size()]);
         Arrays.sort(devices);
 
@@ -297,7 +298,8 @@
         request.setAttribute("tableTitles", tableTitles);
         request.setAttribute("tableSubtitles", tableSubtitles);
         request.setAttribute("startTime", Long.toString(startTime * 1000L));
-        request.setAttribute("devices", new Gson().toJson(devices));
+        request.setAttribute("selectedDevice", selectedDevice);
+        request.setAttribute("devices", devices);
 
         dispatcher = request.getRequestDispatcher("/show_performance_digest.jsp");
         try {
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/util/PerformanceSummary.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/util/PerformanceSummary.java
index b817e54..f35765d 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/util/PerformanceSummary.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/util/PerformanceSummary.java
@@ -36,15 +36,23 @@
     private Set<String> devices;
     private String deviceFilter;
 
+    /**
+     * Creates a performance summary object.
+     */
     public PerformanceSummary() {
         this.summaryMap = new HashMap<>();
         this.devices = new HashSet<>();
         this.deviceFilter = null;
     }
 
+    /**
+     * Creates a performance summary object with the specified device name filter.
+     * If the specified name is null, then use no filter.
+     * @param deviceFilter The name of the device to include in the performance summary.
+     */
     public PerformanceSummary(String deviceFilter) {
         this();
-        this.deviceFilter = deviceFilter.trim().toLowerCase();
+        if (deviceFilter != null) this.deviceFilter = deviceFilter.trim().toLowerCase();
     }
 
     /**
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 6a0a95e..fb52c65 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
@@ -30,6 +30,11 @@
 
 #load {
     margin-top: 15px;
+    margin-right: 30px;
+}
+
+#device-select-wrapper {
+    margin-top: 9px;
 }
 
 #date {
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
index 7304c7f..affe4c3 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/show_performance_digest.jsp
+++ b/web/dashboard/appengine/servlet/src/main/webapp/show_performance_digest.jsp
@@ -46,6 +46,9 @@
           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');
       }
 
@@ -61,6 +64,7 @@
               var label = $(this);
               label.html(moment(parseInt(label.html())).format('M/D/YY'));
           });
+          $('select').material_select();
       });
 
     </script>
@@ -88,10 +92,19 @@
     <div class='container'>
       <div class='row card'>
         <div id='header-container' class='col s12'>
-          <div class='col s9'>
+          <div class='col s12'>
             <h4>Daily Performance Digest</h4>
           </div>
-          <input type='text' id='date' name='date' class='col s2'>
+          <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>