Add a new jank cause of getting a bitmap of a java view.

We suspect that the toolbar is requesting bitmaps during scrolls that
cause jank. This should get us a rough estimate of the frequency and
examples.

Bug: 170621224
Change-Id: I239b4c6bd54915021b35d8a21956968570ad559f
diff --git a/Android.bp b/Android.bp
index 9084200..9b79fcb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -7030,6 +7030,7 @@
     "src/trace_processor/metrics/chrome/scroll_jank_cause.sql",
     "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql",
     "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql",
+    "src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql",
     "src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql",
     "src/trace_processor/metrics/chrome/test_chrome_metric.sql",
     "src/trace_processor/metrics/trace_metadata.sql",
diff --git a/BUILD b/BUILD
index 6a44395..f3ac09f 100644
--- a/BUILD
+++ b/BUILD
@@ -825,6 +825,7 @@
         "src/trace_processor/metrics/chrome/scroll_jank_cause.sql",
         "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql",
         "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql",
+        "src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql",
         "src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql",
         "src/trace_processor/metrics/chrome/test_chrome_metric.sql",
         "src/trace_processor/metrics/trace_metadata.sql",
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index 710a205..6f574cd 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -65,6 +65,7 @@
   "chrome/scroll_jank_cause.sql",
   "chrome/scroll_jank_cause_blocking_task.sql",
   "chrome/scroll_jank_cause_blocking_touch_move.sql",
+  "chrome/scroll_jank_cause_get_bitmap.sql",
   "chrome/scroll_jank_cause_queuing_delay.sql",
   "chrome/scroll_flow_event.sql",
   "chrome/scroll_flow_event_queuing_delay.sql",
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause.sql b/src/trace_processor/metrics/chrome/scroll_jank_cause.sql
index b56c257..e955bdf 100644
--- a/src/trace_processor/metrics/chrome/scroll_jank_cause.sql
+++ b/src/trace_processor/metrics/chrome/scroll_jank_cause.sql
@@ -31,6 +31,7 @@
 -- 5) modify the scroll_jank_cause_explained_jank to include your cause.
 SELECT RUN_METRIC('chrome/scroll_jank_cause_blocking_touch_move.sql');
 SELECT RUN_METRIC('chrome/scroll_jank_cause_blocking_task.sql');
+SELECT RUN_METRIC('chrome/scroll_jank_cause_get_bitmap.sql');
 
 DROP VIEW IF EXISTS scroll_jank_cause_joined;
 
@@ -40,13 +41,19 @@
     COALESCE(task.blocked_by_language_detection, 0)
         AS blocked_by_language_detection,
     COALESCE(task.blocked_by_copy_request, 0) AS blocked_by_copy_request,
+    COALESCE(bitmap.blocked_by_bitmap, 0) AS blocked_by_bitmap,
+    COALESCE(bitmap.blocked_by_toolbar, 0) AS blocked_by_toolbar,
+    COALESCE(bitmap.blocked_by_bitmap_no_toolbar, 0)
+        AS blocked_by_bitmap_no_toolbar,
     jank.*
   FROM
     scroll_jank jank LEFT JOIN
     scroll_jank_cause_blocking_touch_move move
         ON jank.id = move.scroll_id LEFT JOIN
     scroll_jank_cause_blocking_task task
-        ON jank.id = task.scroll_id;
+        ON jank.id = task.scroll_id LEFT JOIN
+    scroll_jank_cause_get_bitmap bitmap
+        ON jank.id = bitmap.scroll_id;
 
 DROP VIEW IF EXISTS scroll_jank_cause_explained_jank;
 
@@ -60,7 +67,8 @@
       CASE WHEN
         blocking_touch_move OR
         blocked_by_language_detection OR
-        blocked_by_copy_request
+        blocked_by_copy_request OR
+        blocked_by_bitmap
       THEN
         TRUE
       ELSE
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql b/src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql
new file mode 100644
index 0000000..af4cff5
--- /dev/null
+++ b/src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql
@@ -0,0 +1,195 @@
+--
+-- Copyright 2020 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
+--
+--     https://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.
+
+-- Needed for the scroll_jank table to tell which updates were janky.
+SELECT RUN_METRIC('chrome/scroll_jank.sql');
+
+--------------------------------------------------------------------------------
+-- Get all the track ids relevant to the critical path.
+--------------------------------------------------------------------------------
+
+-- Grab the track of the browser. sendTouchEvent is a Java category event which
+-- only occurs on the browser. This saves us the trouble of dealing with all the
+-- different possible names of the browser (when including system tracing).
+DROP VIEW IF EXISTS browser_main_track_id;
+
+CREATE VIEW browser_main_track_id AS
+SELECT
+  track_id AS id
+FROM slice
+WHERE
+  name = "sendTouchEvent"
+LIMIT 1;
+
+--------------------------------------------------------------------------------
+-- Grab the last LatencyInfo.Flow for each trace_id on the browser main.
+--------------------------------------------------------------------------------
+DROP VIEW IF EXISTS browser_flows;
+
+CREATE VIEW browser_flows AS
+SELECT
+  EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id,
+  EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") AS flow_step,
+  track_id,
+  max(ts) AS ts
+FROM slice
+WHERE
+  track_id = (
+    SELECT id FROM browser_main_track_id
+  ) AND
+  name = "LatencyInfo.Flow"
+  GROUP BY trace_id;
+
+--------------------------------------------------------------------------------
+-- Join the relevant tracks/flows to the individual scrolls.
+--------------------------------------------------------------------------------
+
+-- Keeping only the GestureScrollUpdates join the maximum flows on the browser
+-- thread. 
+DROP VIEW IF EXISTS scroll_with_browser_flows;
+
+CREATE VIEW scroll_with_browser_flows AS
+SELECT
+  scroll.trace_id,
+  scroll.scroll_id,
+  scroll.ts,
+  scroll.dur,
+  scroll.track_id,
+  browser_flows.ts AS browser_flow_ts,
+  browser_flows.flow_step AS browser_flow_step,
+  browser_flows.track_id AS browser_track_id
+FROM (
+  SELECT
+    trace_id,
+    id AS scroll_id,
+    ts,
+    dur,
+    track_id
+  FROM scroll_jank
+) scroll JOIN browser_flows ON
+    scroll.trace_id = browser_flows.trace_id;
+
+--------------------------------------------------------------------------------
+-- Below we determine if there was any bitmaps taken on the browser main.
+--------------------------------------------------------------------------------
+DROP VIEW IF EXISTS get_bitmap_calls;
+
+CREATE VIEW get_bitmap_calls AS
+  SELECT
+    id,
+    ts,
+    dur,
+    track_id
+  FROM slice
+  WHERE
+    slice.name = "ViewResourceAdapter:getBitmap" AND
+    track_id = (SELECT id FROM browser_main_track_id);
+
+DROP VIEW IF EXISTS toolbar_bitmaps;
+
+CREATE VIEW toolbar_bitmaps AS
+  SELECT
+    slice.id,
+    slice.ts,
+    slice.dur,
+    slice.track_id,
+    ancestor.id AS ancestor_id
+  FROM
+    slice JOIN
+    ancestor_slice(slice.id) AS ancestor ON
+      ancestor.depth = slice.depth - 1
+  WHERE
+    slice.name = "ToolbarLayout.draw" AND
+    ancestor.name = "ViewResourceAdapter:getBitmap" AND
+    slice.track_id = (SELECT id FROM browser_main_track_id);
+
+DROP VIEW IF EXISTS get_bitmaps_and_toolbar;
+
+CREATE VIEW get_bitmaps_and_toolbar AS
+  SELECT
+    bitmap.id AS id,
+    bitmap.ts AS ts,
+    bitmap.dur AS dur,
+    bitmap.track_id AS track_id,
+    toolbar.id AS toolbar_id,
+    toolbar.ts AS toolbar_ts,
+    toolbar.dur AS toolbar_dur,
+    toolbar.track_id AS toolbar_track_id
+  FROM
+    get_bitmap_calls bitmap LEFT JOIN
+    toolbar_bitmaps toolbar ON
+      toolbar.ancestor_id = bitmap.id;
+
+--------------------------------------------------------------------------------
+-- Take bitmaps and determine if it could have been blocked by a scroll. I.E. if
+-- the bitmap occurred after the start of the GestureScrollUpdate but before the
+-- last flow on the browser thread (the GestureScrollUpdate can't be blocked
+-- by a browser thread slice once its done on the browser thread).
+--------------------------------------------------------------------------------
+DROP VIEW IF EXISTS blocking_bitmap_tasks;
+
+CREATE VIEW blocking_bitmap_tasks AS
+SELECT
+  scroll.scroll_id,
+  scroll.trace_id,
+  bitmap.id,
+  bitmap.ts,
+  bitmap.dur,
+  bitmap.track_id,
+  CASE WHEN
+      bitmap.track_id = scroll.browser_track_id AND
+      bitmap.ts < scroll.browser_flow_ts THEN
+    TRUE
+  ELSE
+    FALSE
+  END AS blocked_by_bitmap,
+  CASE WHEN
+      bitmap.track_id = scroll.browser_track_id AND
+      bitmap.toolbar_id IS NOT NULL AND
+      bitmap.ts < scroll.browser_flow_ts THEN
+    TRUE
+  ELSE
+    FALSE
+  END AS blocked_by_toolbar,
+  CASE WHEN
+      bitmap.track_id = scroll.browser_track_id AND
+      bitmap.toolbar_id IS NULL AND
+      bitmap.ts < scroll.browser_flow_ts THEN
+    TRUE
+  ELSE
+    FALSE
+  END AS blocked_by_bitmap_no_toolbar
+FROM
+  scroll_with_browser_flows scroll JOIN
+  get_bitmaps_and_toolbar bitmap ON
+  scroll.ts + scroll.dur >= bitmap.ts AND
+  bitmap.ts + bitmap.dur >= scroll.ts;
+
+
+--------------------------------------------------------------------------------
+-- Remove duplicate tasks blocking so that there is only a boolean per
+-- scroll_id.
+--------------------------------------------------------------------------------
+DROP VIEW IF EXISTS scroll_jank_cause_get_bitmap;
+
+CREATE VIEW scroll_jank_cause_get_bitmap AS
+SELECT
+  scroll_id,
+  trace_id,
+  SUM(blocked_by_bitmap) > 0 AS blocked_by_bitmap,
+  SUM(blocked_by_toolbar) > 0 AS blocked_by_toolbar,
+  SUM(blocked_by_bitmap_no_toolbar) > 0 AS blocked_by_bitmap_no_toolbar
+FROM blocking_bitmap_tasks
+GROUP BY 1, 2;