Merge "Don't preload overview if current home isn't gestural overview" into ub-launcher3-qt-r1-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index bb6892a..1705c97 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -16,6 +16,8 @@
 package com.android.quickstep.util;
 
 import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.view.View;
 import android.view.ViewGroup;
@@ -29,6 +31,7 @@
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutAndWidgetContainer;
+import com.android.launcher3.Workspace;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.anim.PropertySetter;
 import com.android.launcher3.anim.SpringObjectAnimator;
@@ -79,9 +82,19 @@
                 .getDimensionPixelSize(R.dimen.swipe_up_max_workspace_trans_y);
 
         DeviceProfile grid = launcher.getDeviceProfile();
-        ShortcutAndWidgetContainer currentPage = ((CellLayout) launcher.getWorkspace()
-                .getChildAt(launcher.getWorkspace().getCurrentPage()))
-                .getShortcutsAndWidgets();
+        Workspace workspace = launcher.getWorkspace();
+        CellLayout cellLayout = (CellLayout) workspace.getChildAt(workspace.getCurrentPage());
+        ShortcutAndWidgetContainer currentPage = cellLayout.getShortcutsAndWidgets();
+
+        boolean workspaceClipChildren = workspace.getClipChildren();
+        boolean workspaceClipToPadding = workspace.getClipToPadding();
+        boolean cellLayoutClipChildren = cellLayout.getClipChildren();
+        boolean cellLayoutClipToPadding = cellLayout.getClipToPadding();
+
+        workspace.setClipChildren(false);
+        workspace.setClipToPadding(false);
+        cellLayout.setClipChildren(false);
+        cellLayout.setClipToPadding(false);
 
         // Hotseat and QSB takes up two additional rows.
         int totalRows = grid.inv.numRows + (grid.isVerticalBarLayout() ? 0 : 2);
@@ -111,6 +124,27 @@
 
         addWorkspaceScrimAnimationForState(launcher, BACKGROUND_APP, 0);
         addWorkspaceScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
+
+        AnimatorListener resetClipListener = new AnimatorListenerAdapter() {
+            int numAnimations = mAnimators.size();
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                numAnimations--;
+                if (numAnimations > 0) {
+                    return;
+                }
+
+                workspace.setClipChildren(workspaceClipChildren);
+                workspace.setClipToPadding(workspaceClipToPadding);
+                cellLayout.setClipChildren(cellLayoutClipChildren);
+                cellLayout.setClipToPadding(cellLayoutClipToPadding);
+            }
+        };
+
+        for (Animator a : mAnimators) {
+            a.addListener(resetClipListener);
+        }
     }
 
     /**
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 5394f49..01dcff2 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -33,5 +33,5 @@
     <string name="time_left_for_app" msgid="3111996412933644358">"Encore <xliff:g id="TIME">%1$s</xliff:g> aujourd\'hui"</string>
     <string name="title_app_suggestions" msgid="4185902664111965088">"Suggestions d\'applications"</string>
     <string name="all_apps_label" msgid="8542784161730910663">"Toutes les applications"</string>
-    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Vos applications prévues"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Applications prévues pour vous"</string>
 </resources>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 0467af4..387d509 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -27,7 +27,7 @@
     <string name="accessibility_close_task" msgid="5354563209433803643">"बंद करें"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ऐप्लिकेशन इस्तेमाल की सेटिंग"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"सभी ऐप्लिकेशन बंद करें"</string>
-    <string name="accessibility_recent_apps" msgid="4058661986695117371">"हाल ही में इस्तेमाल किए गए एेप्लिकेशन"</string>
+    <string name="accessibility_recent_apps" msgid="4058661986695117371">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन"</string>
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 मिनट"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"आज <xliff:g id="TIME">%1$s</xliff:g> और चलेगा"</string>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index 1ca558a..cccece7 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -27,7 +27,7 @@
     <string name="accessibility_close_task" msgid="5354563209433803643">"बंद"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"अ‍ॅप वापर सेटिंग्ज"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"सर्व साफ करा"</string>
-    <string name="accessibility_recent_apps" msgid="4058661986695117371">"अलीकडील अॅप्स"</string>
+    <string name="accessibility_recent_apps" msgid="4058661986695117371">"अलीकडील अ‍ॅप्स"</string>
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"१मिहून कमी"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"आज <xliff:g id="TIME">%1$s</xliff:g>शिल्लक आहे"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index c0859d3..50f92da 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -88,7 +88,7 @@
     <string name="notification_dots_title" msgid="9062440428204120317">"Punts de notificació"</string>
     <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activats"</string>
     <string name="notification_dots_desc_off" msgid="1760796511504341095">"Desactivats"</string>
-    <string name="title_missing_notification_access" msgid="7503287056163941064">"Cal que tingui accés a les notificacions"</string>
+    <string name="title_missing_notification_access" msgid="7503287056163941064">"Cal accés a les notificacions"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Per veure els punts de notificació, activa les notificacions de l\'aplicació <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Canvia la configuració"</string>
     <string name="notification_dots_service_title" msgid="4284221181793592871">"Mostra els punts de notificació"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 3054214..211f735 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -30,10 +30,10 @@
     <string name="home_screen" msgid="806512411299847073">"Layar utama"</string>
     <string name="custom_actions" msgid="3747508247759093328">"Tindakan khusus"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Sentuh lama untuk memilih widget."</string>
-    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tap dua kalip &amp; tahan untuk mengambil widget atau menggunakan tindakan khusus."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ketuk dua kali &amp; tahan untuk mengambil widget atau menggunakan tindakan khusus."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"lebar %1$d x tinggi %2$d"</string>
-    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tap lama untuk menempatkan secara manual"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sentuh lama untuk menempatkan secara manual"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Tambahkan otomatis"</string>
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Telusuri aplikasi"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Memuat aplikasi…"</string>
@@ -41,8 +41,8 @@
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Telusuri aplikasi lainnya"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikasi"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifikasi"</string>
-    <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Tap lama untuk memilih pintasan."</string>
-    <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Tap dua kali &amp; tahan untuk memilih pintasan atau menggunakan tindakan khusus."</string>
+    <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Sentuh lama untuk memilih pintasan."</string>
+    <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Ketuk dua kali &amp; tahan untuk memilih pintasan atau menggunakan tindakan khusus."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Tidak ada ruang lagi pada layar Utama ini."</string>
     <string name="hotseat_out_of_space" msgid="7448809638125333693">"Tidak ada ruang tersisa di baki Favorit"</string>
     <string name="all_apps_button_label" msgid="8130441508702294465">"Daftar aplikasi"</string>
@@ -73,8 +73,8 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Layar utama %1$d dari %2$d"</string>
     <string name="workspace_new_page" msgid="257366611030256142">"Halaman layar utama baru"</string>
     <string name="folder_opened" msgid="94695026776264709">"Folder dibuka, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
-    <string name="folder_tap_to_close" msgid="4625795376335528256">"Tap untuk menutup folder"</string>
-    <string name="folder_tap_to_rename" msgid="4017685068016979677">"Tap untuk menyimpan ganti nama"</string>
+    <string name="folder_tap_to_close" msgid="4625795376335528256">"Ketuk untuk menutup folder"</string>
+    <string name="folder_tap_to_rename" msgid="4017685068016979677">"Ketuk untuk menyimpan ganti nama"</string>
     <string name="folder_closed" msgid="4100806530910930934">"Folder ditutup"</string>
     <string name="folder_renamed" msgid="1794088362165669656">"Folder diganti namanya menjadi <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 19c0697..49e3898 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -35,18 +35,18 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d रूंद बाय %2$d उंच"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा"</string>
     <string name="place_automatically" msgid="8064208734425456485">"आपोआप जोडा"</string>
-    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"अॅप्स शोधा"</string>
-    <string name="all_apps_loading_message" msgid="5813968043155271636">"अॅप्स लोड करत आहे…"</string>
-    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"अधिक अॅप्स शोधा"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"अ‍ॅप्स शोधा"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"अ‍ॅप्स लोड करत आहे…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" शी जुळणारे कोणतेही अ‍ॅप्स आढळले नाहीत"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"अधिक अ‍ॅप्स शोधा"</string>
     <string name="label_application" msgid="8531721983832654978">"ॲप"</string>
     <string name="notifications_header" msgid="1404149926117359025">"सूचना"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string>
     <string name="out_of_space" msgid="4691004494942118364">"या मुख्य स्क्रीनवर आणखी जागा नाही."</string>
     <string name="hotseat_out_of_space" msgid="7448809638125333693">"आवडीच्या ट्रे मध्ये आणखी जागा नाही"</string>
-    <string name="all_apps_button_label" msgid="8130441508702294465">"अॅप्स सूची"</string>
-    <string name="all_apps_button_personal_label" msgid="1315764287305224468">"वैयक्तिक अॅप्स सूची"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"अ‍ॅप्स सूची"</string>
+    <string name="all_apps_button_personal_label" msgid="1315764287305224468">"वैयक्तिक अ‍ॅप्स सूची"</string>
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"कामाच्या ठिकाणी वापरली जाणाऱ्या अॅप्सची सूची"</string>
     <string name="all_apps_home_button_label" msgid="252062713717058851">"होम"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"काढा"</string>
@@ -136,7 +136,7 @@
     <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"कामाची अ‍ॅप्स येथे मिळवा"</string>
     <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"प्रत्येक कार्य अ‍ॅपला एक बॅज असतो आणि तो तुमच्या संस्थेकडून सुरक्षित ठेवला जातो. अधिक सहज अ‍ॅक्सेससाठी अ‍ॅप्स तुमच्या होम स्क्रीनवर हलवा."</string>
     <string name="work_mode_on_label" msgid="4781128097185272916">"तुमच्या संस्थेकडून व्यवस्थापित"</string>
-    <string name="work_mode_off_label" msgid="3194894777601421047">"सूचना आणि अॅप्स बंद आहेत"</string>
+    <string name="work_mode_off_label" msgid="3194894777601421047">"सूचना आणि अ‍ॅप्स बंद आहेत"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"बंद करा"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"बंद केले"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"हे करता आले नाही: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 34e267d..23b00d0 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -90,7 +90,7 @@
     <string name="notification_dots_title" msgid="9062440428204120317">"Значки уведомлений"</string>
     <string name="notification_dots_desc_on" msgid="1679848116452218908">"Включены"</string>
     <string name="notification_dots_desc_off" msgid="1760796511504341095">"Отключены"</string>
-    <string name="title_missing_notification_access" msgid="7503287056163941064">"Нет доступа к уведомлениям"</string>
+    <string name="title_missing_notification_access" msgid="7503287056163941064">"Нужен доступ к уведомлениям"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Чтобы показывать значки уведомлений, включите уведомления в приложении \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Изменить настройки"</string>
     <string name="notification_dots_service_title" msgid="4284221181793592871">"Показывать значки уведомлений"</string>
diff --git a/src/com/android/launcher3/anim/SpringObjectAnimator.java b/src/com/android/launcher3/anim/SpringObjectAnimator.java
index 395fed2..91a3106 100644
--- a/src/com/android/launcher3/anim/SpringObjectAnimator.java
+++ b/src/com/android/launcher3/anim/SpringObjectAnimator.java
@@ -96,7 +96,10 @@
             }
         });
 
-        mSpring.addUpdateListener((animation, value, velocity) -> mSpringEnded = false);
+        mSpring.addUpdateListener((animation, value, velocity) -> {
+            mSpringEnded = false;
+            mEnded = false;
+        });
         mSpring.addEndListener((animation, canceled, value, velocity) -> {
             mSpringEnded = true;
             tryEnding();
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index 54efcb7..45639e0 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -105,7 +105,7 @@
             "ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview");
 
     public static final TogglableFlag ENABLE_HINTS_IN_OVERVIEW = new TogglableFlag(
-            "ENABLE_HINTS_IN_OVERVIEW", true,
+            "ENABLE_HINTS_IN_OVERVIEW", false,
             "Show chip hints and gleams on the overview screen");
 
     public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag(
diff --git a/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java b/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java
index fa23b8d..6a6916e 100644
--- a/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java
+++ b/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java
@@ -32,13 +32,14 @@
 import android.os.ParcelFileDescriptor;
 import android.util.Base64;
 
+import androidx.test.InstrumentationRegistry;
+
+import com.android.launcher3.tapl.TestHelpers;
+
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 
-import androidx.test.InstrumentationRegistry;
-
 /**
  * Content provider to receive commands from tests
  */
@@ -47,6 +48,7 @@
     public static final String ENABLE_TEST_LAUNCHER = "enable-test-launcher";
     public static final String DISABLE_TEST_LAUNCHER = "disable-test-launcher";
     public static final String KILL_PROCESS = "kill-process";
+    public static final String GET_SYSTEM_HEALTH_MESSAGE = "get-system-health-message";
 
     @Override
     public boolean onCreate() {
@@ -99,6 +101,12 @@
                         killBackgroundProcesses(arg);
                 return null;
             }
+
+            case GET_SYSTEM_HEALTH_MESSAGE: {
+                final Bundle response = new Bundle();
+                response.putString("result", TestHelpers.getSystemHealthMessage(getContext()));
+                return response;
+            }
         }
         return super.call(method, arg, extras);
     }
@@ -122,7 +130,8 @@
             // Create an empty file so that we can pass its descriptor
             try {
                 file.createNewFile();
-            } catch (IOException e) { }
+            } catch (IOException e) {
+            }
         }
 
         return ParcelFileDescriptor.open(file, MODE_READ_WRITE);
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index e39fc76..361f2fb 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -51,6 +51,7 @@
 import com.android.launcher3.model.AppLaunchTracker;
 import com.android.launcher3.tapl.LauncherInstrumentation;
 import com.android.launcher3.tapl.TestHelpers;
+import com.android.launcher3.testcomponent.TestCommandReceiver;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.Wait;
 import com.android.launcher3.util.rule.FailureWatcher;
@@ -98,7 +99,11 @@
         } catch (RemoteException e) {
             throw new RuntimeException(e);
         }
-        if (TestHelpers.isInLauncherProcess()) Utilities.enableRunningInTestHarnessForTests();
+        if (TestHelpers.isInLauncherProcess()) {
+            Utilities.enableRunningInTestHarnessForTests();
+            mLauncher.setSystemHealthSupplier(() -> TestCommandReceiver.callCommand(
+                    TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE).getString("result"));
+        }
     }
 
     protected final LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java
index 79c2d07..d9edc35 100644
--- a/tests/src/com/android/launcher3/ui/WorkTabTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java
@@ -54,7 +54,7 @@
     @Test
     public void workTabExists() {
         mDevice.pressHome();
-
+        waitForLauncherCondition("Launcher didn't start", launcher -> launcher != null);
         executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
 
         /*
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 5a6c898..0fed337 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -39,7 +39,6 @@
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.DropBoxManager;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.text.TextUtils;
@@ -73,6 +72,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.TimeoutException;
+import java.util.function.Supplier;
 
 /**
  * The main tapl object. The only object that can be explicitly constructed by the using code. It
@@ -133,6 +133,7 @@
     private int mExpectedRotation = Surface.ROTATION_0;
     private final Uri mTestProviderUri;
     private final Deque<String> mDiagnosticContext = new LinkedList<>();
+    private Supplier<String> mSystemHealthSupplier;
 
     /**
      * Constructs the root of TAPL hierarchy. You get all other objects from it.
@@ -285,79 +286,24 @@
         return "Background";
     }
 
-    private static String truncateCrash(String text, int maxLines) {
-        String[] lines = text.split("\\r?\\n");
-        StringBuilder ret = new StringBuilder();
-        for (int i = 0; i < maxLines && i < lines.length; i++) {
-            ret.append(lines[i]);
-            ret.append('\n');
-        }
-        if (lines.length > maxLines) {
-            ret.append("... ");
-            ret.append(lines.length - maxLines);
-            ret.append(" more lines truncated ...\n");
-        }
-        return ret.toString();
-    }
-
-    private String checkCrash(String label) {
-        DropBoxManager dropbox = (DropBoxManager) getContext().getSystemService(
-                Context.DROPBOX_SERVICE);
-        Assert.assertNotNull("Unable access the DropBoxManager service", dropbox);
-
-        long timestamp = 0;
-        DropBoxManager.Entry entry;
-        int crashCount = 0;
-        StringBuilder errorDetails = new StringBuilder();
-        while (null != (entry = dropbox.getNextEntry(label, timestamp))) {
-            String dropboxSnippet;
-            try {
-                dropboxSnippet = entry.getText(4096);
-            } finally {
-                entry.close();
-            }
-
-            crashCount++;
-            errorDetails.append(label);
-            errorDetails.append(": ");
-            errorDetails.append(truncateCrash(dropboxSnippet, 40));
-            errorDetails.append("    ...\n");
-
-            timestamp = entry.getTimeMillis();
-        }
-        Assert.assertEquals(errorDetails.toString(), 0, crashCount);
-        return crashCount > 0 ? errorDetails.toString() : null;
+    public void setSystemHealthSupplier(Supplier<String> supplier) {
+        this.mSystemHealthSupplier = supplier;
     }
 
     private String getSystemHealthMessage() {
+        final String testPackage = getContext().getPackageName();
         try {
-            StringBuilder errors = new StringBuilder();
-
-            final String testPackage = getContext().getPackageName();
-            try {
-                mDevice.executeShellCommand("pm grant " + testPackage +
-                        " android.permission.READ_LOGS");
-                mDevice.executeShellCommand("pm grant " + testPackage +
-                        " android.permission.PACKAGE_USAGE_STATS");
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-
-            final String[] labels = {
-                    "system_server_crash",
-                    "system_server_native_crash",
-                    "system_server_anr",
-            };
-
-            for (String label : labels) {
-                final String crash = checkCrash(label);
-                if (crash != null) errors.append(crash);
-            }
-
-            return errors.length() != 0 ? errors.toString() : null;
-        } catch (Exception e) {
-            return null;
+            mDevice.executeShellCommand("pm grant " + testPackage +
+                    " android.permission.READ_LOGS");
+            mDevice.executeShellCommand("pm grant " + testPackage +
+                    " android.permission.PACKAGE_USAGE_STATS");
+        } catch (IOException e) {
+            e.printStackTrace();
         }
+
+        return mSystemHealthSupplier != null
+                ? mSystemHealthSupplier.get()
+                : TestHelpers.getSystemHealthMessage(getContext());
     }
 
     private void fail(String message) {
diff --git a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java
index 93554d2..e19f91a 100644
--- a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java
+++ b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java
@@ -26,6 +26,9 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
+import android.os.DropBoxManager;
+
+import org.junit.Assert;
 
 import java.util.List;
 
@@ -81,4 +84,69 @@
         }
         return "com.android.systemui";
     }
+
+    private static String truncateCrash(String text, int maxLines) {
+        String[] lines = text.split("\\r?\\n");
+        StringBuilder ret = new StringBuilder();
+        for (int i = 0; i < maxLines && i < lines.length; i++) {
+            ret.append(lines[i]);
+            ret.append('\n');
+        }
+        if (lines.length > maxLines) {
+            ret.append("... ");
+            ret.append(lines.length - maxLines);
+            ret.append(" more lines truncated ...\n");
+        }
+        return ret.toString();
+    }
+
+    private static String checkCrash(Context context, String label) {
+        DropBoxManager dropbox = (DropBoxManager) context.getSystemService(Context.DROPBOX_SERVICE);
+        Assert.assertNotNull("Unable access the DropBoxManager service", dropbox);
+
+        long timestamp = 0;
+        DropBoxManager.Entry entry;
+        int crashCount = 0;
+        StringBuilder errorDetails = new StringBuilder();
+        while (null != (entry = dropbox.getNextEntry(label, timestamp))) {
+            String dropboxSnippet;
+            try {
+                dropboxSnippet = entry.getText(4096);
+            } finally {
+                entry.close();
+            }
+
+            crashCount++;
+            errorDetails.append(label);
+            errorDetails.append(": ");
+            errorDetails.append(truncateCrash(dropboxSnippet, 40));
+            errorDetails.append("    ...\n");
+
+            timestamp = entry.getTimeMillis();
+        }
+        Assert.assertEquals(errorDetails.toString(), 0, crashCount);
+        return crashCount > 0 ? errorDetails.toString() : null;
+    }
+
+    public static String getSystemHealthMessage(Context context) {
+        try {
+            StringBuilder errors = new StringBuilder();
+
+            final String[] labels = {
+                    "system_server_crash",
+                    "system_server_native_crash",
+                    "system_server_anr",
+            };
+
+            for (String label : labels) {
+                final String crash = checkCrash(context, label);
+                if (crash != null) errors.append(crash);
+            }
+
+            return errors.length() != 0 ? errors.toString() : null;
+        } catch (Exception e) {
+            return "Failed to get system health diags, maybe build your test via .bp instead of "
+                    + ".mk? " + android.util.Log.getStackTraceString(e);
+        }
+    }
 }