Merge remote-tracking branch 'goog/ub-launcher3-master' into temp

Test: make builds

Change-Id: I4e845aa51c9247328159e5aa0d95d425bffa435c
diff --git a/Android.bp b/Android.bp
index e132854..4265a44 100644
--- a/Android.bp
+++ b/Android.bp
@@ -19,6 +19,7 @@
         "androidx.test.runner",
         "androidx.test.rules",
         "androidx.test.uiautomator_uiautomator",
+        "androidx.preference_preference",
         "SystemUISharedLib",
     ],
     srcs: [
diff --git a/CleanSpec.mk b/CleanSpec.mk
index f7bda94..489abd1 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -52,6 +52,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/Launcher2.apk)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Launcher2_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/Launcher2.apk)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/Launcher3QuickStep)
 
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/priv-app/Launcher3)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/priv-app/Launcher3Go)
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/go/res/values-v26/bools.xml b/go/res/values-v26/bools.xml
index cc4a7ba..1584734 100644
--- a/go/res/values-v26/bools.xml
+++ b/go/res/values-v26/bools.xml
@@ -17,5 +17,6 @@
 -->
 
 <resources>
-    <bool name="notification_badging_enabled">false</bool>
-</resources>
\ No newline at end of file
+    <bool name="notification_dots_enabled">false</bool>
+</resources>
+
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java b/iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java
deleted file mode 100644
index 7b8070a..0000000
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java
+++ /dev/null
@@ -1,317 +0,0 @@
-<<<<<<< HEAD   (cc6caf Merge "Let launcher to provide its own OverscrollPlugin" int)
-/*
- * Copyright (C) 2018 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.
- */
-package com.android.launcher3.icons.cache;
-
-import android.content.ComponentName;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseBooleanArray;
-
-import com.android.launcher3.icons.cache.BaseIconCache.IconDB;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.Stack;
-
-/**
- * Utility class to handle updating the Icon cache
- */
-public class IconCacheUpdateHandler {
-
-    private static final String TAG = "IconCacheUpdateHandler";
-
-    /**
-     * In this mode, all invalid icons are marked as to-be-deleted in {@link #mItemsToDelete}.
-     * This mode is used for the first run.
-     */
-    private static final boolean MODE_SET_INVALID_ITEMS = true;
-
-    /**
-     * In this mode, any valid icon is removed from {@link #mItemsToDelete}. This is used for all
-     * subsequent runs, which essentially acts as set-union of all valid items.
-     */
-    private static final boolean MODE_CLEAR_VALID_ITEMS = false;
-
-    private static final Object ICON_UPDATE_TOKEN = new Object();
-
-    private final HashMap<String, PackageInfo> mPkgInfoMap;
-    private final BaseIconCache mIconCache;
-
-    private final ArrayMap<UserHandle, Set<String>> mPackagesToIgnore = new ArrayMap<>();
-
-    private final SparseBooleanArray mItemsToDelete = new SparseBooleanArray();
-    private boolean mFilterMode = MODE_SET_INVALID_ITEMS;
-
-    IconCacheUpdateHandler(BaseIconCache cache) {
-        mIconCache = cache;
-
-        mPkgInfoMap = new HashMap<>();
-
-        // Remove all active icon update tasks.
-        mIconCache.mWorkerHandler.removeCallbacksAndMessages(ICON_UPDATE_TOKEN);
-
-        createPackageInfoMap();
-    }
-
-    /**
-     * Sets a package to ignore for processing
-     */
-    public void addPackagesToIgnore(UserHandle userHandle, String packageName) {
-        Set<String> packages = mPackagesToIgnore.get(userHandle);
-        if (packages == null) {
-            packages = new HashSet<>();
-            mPackagesToIgnore.put(userHandle, packages);
-        }
-        packages.add(packageName);
-    }
-
-    private void createPackageInfoMap() {
-        PackageManager pm = mIconCache.mPackageManager;
-        for (PackageInfo info :
-                pm.getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES)) {
-            mPkgInfoMap.put(info.packageName, info);
-        }
-    }
-
-    /**
-     * Updates the persistent DB, such that only entries corresponding to {@param apps} remain in
-     * the DB and are updated.
-     * @return The set of packages for which icons have updated.
-     */
-    public <T> void updateIcons(List<T> apps, CachingLogic<T> cachingLogic,
-            OnUpdateCallback onUpdateCallback) {
-        // Filter the list per user
-        HashMap<UserHandle, HashMap<ComponentName, T>> userComponentMap = new HashMap<>();
-        int count = apps.size();
-        for (int i = 0; i < count; i++) {
-            T app = apps.get(i);
-            UserHandle userHandle = cachingLogic.getUser(app);
-            HashMap<ComponentName, T> componentMap = userComponentMap.get(userHandle);
-            if (componentMap == null) {
-                componentMap = new HashMap<>();
-                userComponentMap.put(userHandle, componentMap);
-            }
-            componentMap.put(cachingLogic.getComponent(app), app);
-        }
-
-        for (Entry<UserHandle, HashMap<ComponentName, T>> entry : userComponentMap.entrySet()) {
-            updateIconsPerUser(entry.getKey(), entry.getValue(), cachingLogic, onUpdateCallback);
-        }
-
-        // From now on, clear every valid item from the global valid map.
-        mFilterMode = MODE_CLEAR_VALID_ITEMS;
-    }
-
-    /**
-     * Updates the persistent DB, such that only entries corresponding to {@param apps} remain in
-     * the DB and are updated.
-     * @return The set of packages for which icons have updated.
-     */
-    @SuppressWarnings("unchecked")
-    private <T> void updateIconsPerUser(UserHandle user, HashMap<ComponentName, T> componentMap,
-            CachingLogic<T> cachingLogic, OnUpdateCallback onUpdateCallback) {
-        Set<String> ignorePackages = mPackagesToIgnore.get(user);
-        if (ignorePackages == null) {
-            ignorePackages = Collections.emptySet();
-        }
-        long userSerial = mIconCache.getSerialNumberForUser(user);
-
-        Stack<T> appsToUpdate = new Stack<>();
-
-        try (Cursor c = mIconCache.mIconDb.query(
-                new String[]{IconDB.COLUMN_ROWID, IconDB.COLUMN_COMPONENT,
-                        IconDB.COLUMN_LAST_UPDATED, IconDB.COLUMN_VERSION,
-                        IconDB.COLUMN_SYSTEM_STATE},
-                IconDB.COLUMN_USER + " = ? ",
-                new String[]{Long.toString(userSerial)})) {
-
-            final int indexComponent = c.getColumnIndex(IconDB.COLUMN_COMPONENT);
-            final int indexLastUpdate = c.getColumnIndex(IconDB.COLUMN_LAST_UPDATED);
-            final int indexVersion = c.getColumnIndex(IconDB.COLUMN_VERSION);
-            final int rowIndex = c.getColumnIndex(IconDB.COLUMN_ROWID);
-            final int systemStateIndex = c.getColumnIndex(IconDB.COLUMN_SYSTEM_STATE);
-
-            while (c.moveToNext()) {
-                String cn = c.getString(indexComponent);
-                ComponentName component = ComponentName.unflattenFromString(cn);
-                PackageInfo info = mPkgInfoMap.get(component.getPackageName());
-
-                int rowId = c.getInt(rowIndex);
-                if (info == null) {
-                    if (!ignorePackages.contains(component.getPackageName())) {
-
-                        if (mFilterMode == MODE_SET_INVALID_ITEMS) {
-                            mIconCache.remove(component, user);
-                            mItemsToDelete.put(rowId, true);
-                        }
-                    }
-                    continue;
-                }
-                if ((info.applicationInfo.flags & ApplicationInfo.FLAG_IS_DATA_ONLY) != 0) {
-                    // Application is not present
-                    continue;
-                }
-
-                long updateTime = c.getLong(indexLastUpdate);
-                int version = c.getInt(indexVersion);
-                T app = componentMap.remove(component);
-                if (version == info.versionCode
-                        && updateTime == cachingLogic.getLastUpdatedTime(app, info)
-                        && TextUtils.equals(c.getString(systemStateIndex),
-                                mIconCache.getIconSystemState(info.packageName))) {
-
-                    if (mFilterMode == MODE_CLEAR_VALID_ITEMS) {
-                        mItemsToDelete.put(rowId, false);
-                    }
-                    continue;
-                }
-
-                if (app == null) {
-                    if (mFilterMode == MODE_SET_INVALID_ITEMS) {
-                        mIconCache.remove(component, user);
-                        mItemsToDelete.put(rowId, true);
-                    }
-                } else {
-                    appsToUpdate.add(app);
-                }
-            }
-        } catch (SQLiteException e) {
-            Log.d(TAG, "Error reading icon cache", e);
-            // Continue updating whatever we have read so far
-        }
-
-        // Insert remaining apps.
-        if (!componentMap.isEmpty() || !appsToUpdate.isEmpty()) {
-            Stack<T> appsToAdd = new Stack<>();
-            appsToAdd.addAll(componentMap.values());
-            new SerializedIconUpdateTask(userSerial, user, appsToAdd, appsToUpdate, cachingLogic,
-                    onUpdateCallback).scheduleNext();
-        }
-    }
-
-    /**
-     * Commits all updates as part of the update handler to disk. Not more calls should be made
-     * to this class after this.
-     */
-    public void finish() {
-        // Commit all deletes
-        int deleteCount = 0;
-        StringBuilder queryBuilder = new StringBuilder()
-                .append(IconDB.COLUMN_ROWID)
-                .append(" IN (");
-
-        int count = mItemsToDelete.size();
-        for (int i = 0;  i < count; i++) {
-            if (mItemsToDelete.valueAt(i)) {
-                if (deleteCount > 0) {
-                    queryBuilder.append(", ");
-                }
-                queryBuilder.append(mItemsToDelete.keyAt(i));
-                deleteCount++;
-            }
-        }
-        queryBuilder.append(')');
-
-        if (deleteCount > 0) {
-            mIconCache.mIconDb.delete(queryBuilder.toString(), null);
-        }
-    }
-
-    /**
-     * A runnable that updates invalid icons and adds missing icons in the DB for the provided
-     * LauncherActivityInfo list. Items are updated/added one at a time, so that the
-     * worker thread doesn't get blocked.
-     */
-    private class SerializedIconUpdateTask<T> implements Runnable {
-        private final long mUserSerial;
-        private final UserHandle mUserHandle;
-        private final Stack<T> mAppsToAdd;
-        private final Stack<T> mAppsToUpdate;
-        private final CachingLogic<T> mCachingLogic;
-        private final HashSet<String> mUpdatedPackages = new HashSet<>();
-        private final OnUpdateCallback mOnUpdateCallback;
-
-        SerializedIconUpdateTask(long userSerial, UserHandle userHandle,
-                Stack<T> appsToAdd, Stack<T> appsToUpdate, CachingLogic<T> cachingLogic,
-                OnUpdateCallback onUpdateCallback) {
-            mUserHandle = userHandle;
-            mUserSerial = userSerial;
-            mAppsToAdd = appsToAdd;
-            mAppsToUpdate = appsToUpdate;
-            mCachingLogic = cachingLogic;
-            mOnUpdateCallback = onUpdateCallback;
-        }
-
-        @Override
-        public void run() {
-            if (!mAppsToUpdate.isEmpty()) {
-                T app = mAppsToUpdate.pop();
-                String pkg = mCachingLogic.getComponent(app).getPackageName();
-                PackageInfo info = mPkgInfoMap.get(pkg);
-
-                mIconCache.addIconToDBAndMemCache(
-                        app, mCachingLogic, info, mUserSerial, true /*replace existing*/);
-                mUpdatedPackages.add(pkg);
-
-                if (mAppsToUpdate.isEmpty() && !mUpdatedPackages.isEmpty()) {
-                    // No more app to update. Notify callback.
-                    mOnUpdateCallback.onPackageIconsUpdated(mUpdatedPackages, mUserHandle);
-                }
-
-                // Let it run one more time.
-                scheduleNext();
-            } else if (!mAppsToAdd.isEmpty()) {
-                T app = mAppsToAdd.pop();
-                PackageInfo info = mPkgInfoMap.get(mCachingLogic.getComponent(app).getPackageName());
-                // We do not check the mPkgInfoMap when generating the mAppsToAdd. Although every
-                // app should have package info, this is not guaranteed by the api
-                if (info != null) {
-                    mIconCache.addIconToDBAndMemCache(app, mCachingLogic, info,
-                            mUserSerial, false /*replace existing*/);
-                }
-
-                if (!mAppsToAdd.isEmpty()) {
-                    scheduleNext();
-                }
-            }
-        }
-
-        public void scheduleNext() {
-            mIconCache.mWorkerHandler.postAtTime(this, ICON_UPDATE_TOKEN,
-                    SystemClock.uptimeMillis() + 1);
-        }
-    }
-
-    public interface OnUpdateCallback {
-
-        void onPackageIconsUpdated(HashSet<String> updatedPackages, UserHandle user);
-    }
-}
-=======
->>>>>>> CHANGE (805b52 Removes iconloaderlib from Launcher3.)
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
index 2b3f395..4b8e434 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
@@ -54,7 +54,6 @@
     private static final int DEFAULT_CLOSE_DURATION = 200;
     protected static final int FINAL_SCRIM_BG_COLOR = 0x88000000;
 
-
     // we use this value to keep track of migration logs as we experiment with different migrations
     private static final int MIGRATION_EXPERIMENT_IDENTIFIER = 1;
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 43dba85..cf86cd5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -205,7 +205,8 @@
         boolean willUserBeActive = (getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0;
         boolean visible = (state == NORMAL || state == OVERVIEW)
                 && (willUserBeActive || isUserActive())
-                && !profile.isVerticalBarLayout();
+                && !profile.isVerticalBarLayout()
+                && profile.isPhone && !profile.isLandscape;
         UiThreadHelper.runAsyncCommand(this, SET_SHELF_HEIGHT, visible ? 1 : 0,
                 profile.hotseatBarSizePx);
         if (state == NORMAL && !inTransition) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 1012ab2..9d16f0e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -518,6 +518,11 @@
                 } else {
                     mUncheckedConsumer = InputConsumer.NO_OP;
                 }
+            } else if (mDeviceState.canTriggerOneHandedAction(event)
+                    && !mDeviceState.isOneHandedModeActive()) {
+                // Consume gesture event for triggering one handed feature.
+                mUncheckedConsumer = new OneHandedModeInputConsumer(this, mDeviceState,
+                        InputConsumer.NO_OP, mInputMonitorCompat);
             } else {
                 mUncheckedConsumer = InputConsumer.NO_OP;
             }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index 32b1c58..9bfe84f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -108,4 +108,5 @@
             mActivity.dispatchKeyEvent(ev);
         }
     }
-}
\ No newline at end of file
+}
+
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SurfaceTransactionApplier.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SurfaceTransactionApplier.java
index 0a3e3ec..0436a1c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SurfaceTransactionApplier.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SurfaceTransactionApplier.java
@@ -16,7 +16,6 @@
 package com.android.quickstep.util;
 
 import static com.android.systemui.shared.system.TransactionCompat.deferTransactionUntil;
-import static com.android.systemui.shared.system.TransactionCompat.setEarlyWakeup;
 
 import android.annotation.TargetApi;
 import android.os.Build;
@@ -95,7 +94,6 @@
                     surfaceParams.applyTo(t);
                 }
             }
-            setEarlyWakeup(t);
             t.apply();
             Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
                     .sendToTarget();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java
index 45f49bb..756331d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java
@@ -213,7 +213,6 @@
             for (SurfaceParams param : params) {
                 SyncRtSurfaceTransactionApplierCompat.applyParams(t, param);
             }
-            t.setEarlyWakeup();
             t.apply();
         }
     }
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 769d298..86120e3 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -163,4 +163,4 @@
     <string name="action_screenshot">Screenshot</string>
     <!-- Message shown when an action is blocked by a policy enforced by the app or the organization managing the device. [CHAR_LIMIT=NONE] -->
     <string name="blocked_by_policy">This action isn\'t allowed by the app or your organization</string>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index 5ad0bca..02769c6 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -158,4 +158,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index bd97f65..2d096d1 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -608,8 +608,10 @@
                         }
 
                         matrix.setTranslate(tmpPos.x, tmpPos.y);
+                        final Rect crop = new Rect(target.screenSpaceBounds);
+                        crop.offsetTo(0, 0);
                         builder.withMatrix(matrix)
-                                .withWindowCrop(target.screenSpaceBounds)
+                                .withWindowCrop(crop)
                                 .withAlpha(1f);
                     }
                     params[i] = builder.build();
@@ -776,8 +778,10 @@
                         builder.withMatrix(matrix)
                                 .withAlpha(1f);
                     }
+                    final Rect crop = new Rect(target.screenSpaceBounds);
+                    crop.offsetTo(0, 0);
                     params[i] = builder
-                            .withWindowCrop(target.screenSpaceBounds)
+                            .withWindowCrop(crop)
                             .build();
                 }
                 surfaceApplier.scheduleApply(params);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/DejankBinderTracker.java b/quickstep/src/com/android/launcher3/uioverrides/DejankBinderTracker.java
new file mode 100644
index 0000000..d8aa235
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/DejankBinderTracker.java
@@ -0,0 +1,159 @@
+/**
+ * Copyright (C) 2019 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.
+ */
+
+package com.android.launcher3.uioverrides;
+
+import static android.os.IBinder.FLAG_ONEWAY;
+
+import android.os.Binder;
+import android.os.Build;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+
+import androidx.annotation.MainThread;
+
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.function.BiConsumer;
+import java.util.function.Supplier;
+
+/**
+ * A binder proxy transaction listener for tracking non-whitelisted binder calls.
+ */
+public class DejankBinderTracker implements Binder.ProxyTransactListener {
+    private static final String TAG = "DejankBinderTracker";
+
+    private static final Object sLock = new Object();
+    private static final HashSet<String> sWhitelistedFrameworkClasses = new HashSet<>();
+    static {
+        // Common IPCs that are ok to block the main thread.
+        sWhitelistedFrameworkClasses.add("android.view.IWindowSession");
+        sWhitelistedFrameworkClasses.add("android.os.IPowerManager");
+    }
+    private static boolean sTemporarilyIgnoreTracking = false;
+
+    // Used by the client to limit binder tracking to specific regions
+    private static boolean sTrackingAllowed = false;
+
+    private BiConsumer<String, Integer> mUnexpectedTransactionCallback;
+    private boolean mIsTracking = false;
+
+    /**
+     * Temporarily ignore blocking binder calls for the duration of this {@link Runnable}.
+     */
+    @MainThread
+    public static void whitelistIpcs(Runnable runnable) {
+        sTemporarilyIgnoreTracking = true;
+        runnable.run();
+        sTemporarilyIgnoreTracking = false;
+    }
+
+    /**
+     * Temporarily ignore blocking binder calls for the duration of this {@link Supplier}.
+     */
+    @MainThread
+    public static <T> T whitelistIpcs(Supplier<T> supplier) {
+        sTemporarilyIgnoreTracking = true;
+        T value = supplier.get();
+        sTemporarilyIgnoreTracking = false;
+        return value;
+    }
+
+    /**
+     * Enables binder tracking during a test.
+     */
+    @MainThread
+    public static void allowBinderTrackingInTests() {
+        sTrackingAllowed = true;
+    }
+
+    /**
+     * Disables binder tracking during a test.
+     */
+    @MainThread
+    public static void disallowBinderTrackingInTests() {
+        sTrackingAllowed = false;
+    }
+
+    public DejankBinderTracker(BiConsumer<String, Integer> unexpectedTransactionCallback) {
+        mUnexpectedTransactionCallback = unexpectedTransactionCallback;
+    }
+
+    @MainThread
+    public void startTracking() {
+        if (!Build.TYPE.toLowerCase(Locale.ROOT).contains("debug")
+                && !Build.TYPE.toLowerCase(Locale.ROOT).equals("eng")) {
+            Log.wtf(TAG, "Unexpected use of binder tracker in non-debug build", new Exception());
+            return;
+        }
+        if (mIsTracking) {
+            return;
+        }
+        mIsTracking = true;
+        Binder.setProxyTransactListener(this);
+    }
+
+    @MainThread
+    public void stopTracking() {
+        if (!mIsTracking) {
+            return;
+        }
+        mIsTracking = false;
+        Binder.setProxyTransactListener(null);
+    }
+
+    // Override the hidden Binder#onTransactStarted method
+    public synchronized Object onTransactStarted(IBinder binder, int transactionCode, int flags) {
+        if (!mIsTracking
+                || !sTrackingAllowed
+                || sTemporarilyIgnoreTracking
+                || (flags & FLAG_ONEWAY) == FLAG_ONEWAY
+                || !isMainThread()) {
+            return null;
+        }
+
+        String descriptor;
+        try {
+            descriptor = binder.getInterfaceDescriptor();
+            if (sWhitelistedFrameworkClasses.contains(descriptor)) {
+                return null;
+            }
+        } catch (RemoteException e) {
+            e.printStackTrace();
+            descriptor = binder.getClass().getSimpleName();
+        }
+
+        mUnexpectedTransactionCallback.accept(descriptor, transactionCode);
+        return null;
+    }
+
+    @Override
+    public Object onTransactStarted(IBinder binder, int transactionCode) {
+        // Do nothing
+        return null;
+    }
+
+    @Override
+    public void onTransactEnded(Object session) {
+        // Do nothing
+    }
+
+    public static boolean isMainThread() {
+        return Thread.currentThread() == Looper.getMainLooper().getThread();
+    }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 0c5b9ad..9732cdc 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -102,4 +102,4 @@
         }
         mLauncher.pressHome();
     }
-}
\ No newline at end of file
+}
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
deleted file mode 100644
index 0758148..0000000
--- a/res/values-rm/strings.xml
+++ /dev/null
@@ -1,203 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2008 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.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for application_name (5181331383435256801) -->
-    <skip />
-    <!-- no translation found for home (7658288663002113681) -->
-    <skip />
-    <!-- no translation found for uid_name (7820867637514617527) -->
-    <skip />
-    <string name="folder_name" msgid="7371454440695724752"></string>
-    <!-- no translation found for activity_not_found (8071924732094499514) -->
-    <skip />
-    <!-- no translation found for widgets_tab_label (2921133187116603919) -->
-    <skip />
-    <!-- no translation found for widget_adder (3201040140710381657) -->
-    <skip />
-    <!-- no translation found for toggle_weight_watcher (5645299835184636119) -->
-    <skip />
-    <!-- no translation found for long_press_widget_to_add (7699152356777458215) -->
-    <skip />
-    <!-- no translation found for market (2619650989819296998) -->
-    <skip />
-    <!-- no translation found for widget_dims_format (2370757736025621599) -->
-    <skip />
-    <!-- no translation found for external_drop_widget_error (3165821058322217155) -->
-    <skip />
-    <!-- no translation found for external_drop_widget_pick_title (3486317258037690630) -->
-    <skip />
-    <!-- no translation found for rename_folder_label (3727762225964550653) -->
-    <skip />
-    <!-- no translation found for rename_folder_title (3771389277707820891) -->
-    <skip />
-    <!-- no translation found for rename_action (5559600076028658757) -->
-    <skip />
-    <!-- no translation found for cancel_action (7009134900002915310) -->
-    <skip />
-    <!-- no translation found for menu_item_add_item (1264911265836810421) -->
-    <skip />
-    <!-- no translation found for group_applications (3797214114206693605) -->
-    <skip />
-    <!-- no translation found for group_shortcuts (6012256992764410535) -->
-    <skip />
-    <!-- no translation found for group_widgets (1569030723286851002) -->
-    <skip />
-    <!-- no translation found for completely_out_of_space (6106288382070760318) -->
-    <skip />
-    <!-- no translation found for out_of_space (4691004494942118364) -->
-    <skip />
-    <!-- no translation found for hotseat_out_of_space (7448809638125333693) -->
-    <skip />
-    <!-- no translation found for invalid_hotseat_item (5779907847267573691) -->
-    <skip />
-    <!-- no translation found for shortcut_installed (1701742129426969556) -->
-    <skip />
-    <!-- no translation found for shortcut_uninstalled (8176767991305701821) -->
-    <skip />
-    <!-- no translation found for shortcut_duplicate (9167217446062498127) -->
-    <skip />
-    <!-- no translation found for title_select_shortcut (6680642571148153868) -->
-    <skip />
-    <!-- no translation found for title_select_application (3280812711670683644) -->
-    <skip />
-    <!-- no translation found for all_apps_button_label (9110807029020582876) -->
-    <skip />
-    <!-- no translation found for all_apps_home_button_label (252062713717058851) -->
-    <skip />
-    <!-- no translation found for delete_zone_label_workspace (4009607676751398685) -->
-    <skip />
-    <!-- no translation found for delete_zone_label_all_apps (8083826390278958980) -->
-    <skip />
-    <!-- no translation found for delete_target_label (1822697352535677073) -->
-    <skip />
-    <!-- no translation found for delete_target_uninstall_label (5100785476250872595) -->
-    <skip />
-    <!-- no translation found for info_target_label (8053346143994679532) -->
-    <skip />
-    <!-- no translation found for accessibility_search_button (1628520399424565142) -->
-    <skip />
-    <!-- no translation found for accessibility_voice_search_button (4637324840434406584) -->
-    <skip />
-    <!-- no translation found for accessibility_all_apps_button (2603132375383800483) -->
-    <skip />
-    <!-- no translation found for accessibility_delete_button (6466114477993744621) -->
-    <skip />
-    <!-- no translation found for delete_zone_label_all_apps_system_app (449755632749610895) -->
-    <skip />
-    <!-- no translation found for cab_menu_delete_app (7435191475867183689) -->
-    <skip />
-    <!-- no translation found for cab_menu_app_info (8593722221450362342) -->
-    <skip />
-    <!-- no translation found for cab_app_selection_text (374688303047985416) -->
-    <skip />
-    <!-- no translation found for cab_widget_selection_text (1833458597831541241) -->
-    <skip />
-    <!-- no translation found for cab_folder_selection_text (7999992513806132118) -->
-    <skip />
-    <!-- no translation found for cab_shortcut_selection_text (2103811025667946450) -->
-    <skip />
-    <!-- no translation found for permlab_install_shortcut (5632423390354674437) -->
-    <skip />
-    <!-- no translation found for permdesc_install_shortcut (923466509822011139) -->
-    <skip />
-    <!-- no translation found for permlab_uninstall_shortcut (864595034498083837) -->
-    <skip />
-    <!-- no translation found for permdesc_uninstall_shortcut (5134129545001836849) -->
-    <skip />
-    <!-- no translation found for permlab_read_settings (1941457408239617576) -->
-    <skip />
-    <!-- no translation found for permdesc_read_settings (5833423719057558387) -->
-    <skip />
-    <!-- no translation found for permlab_write_settings (3574213698004620587) -->
-    <skip />
-    <!-- no translation found for permdesc_write_settings (5440712911516509985) -->
-    <skip />
-    <!-- no translation found for gadget_error_text (6081085226050792095) -->
-    <skip />
-    <!-- no translation found for uninstall_system_app_text (4172046090762920660) -->
-    <skip />
-    <!-- no translation found for dream_name (1530253749244328964) -->
-    <skip />
-    <!-- no translation found for folder_hint_text (6617836969016293992) -->
-    <skip />
-    <!-- no translation found for workspace_description_format (2950174241104043327) -->
-    <skip />
-    <!-- no translation found for default_scroll_format (7475544710230993317) -->
-    <skip />
-    <!-- no translation found for workspace_scroll_format (8458889198184077399) -->
-    <skip />
-    <!-- no translation found for apps_customize_apps_scroll_format (370005296147130238) -->
-    <skip />
-    <!-- no translation found for apps_customize_widgets_scroll_format (3106209519974971521) -->
-    <skip />
-    <!-- no translation found for first_run_cling_title (2459738000155917941) -->
-    <skip />
-    <!-- no translation found for first_run_cling_description (6447072552696253358) -->
-    <skip />
-    <!-- no translation found for first_run_cling_create_screens_hint (6950729526680114157) -->
-    <skip />
-    <!-- no translation found for migration_cling_title (9181776667882933767) -->
-    <skip />
-    <!-- no translation found for migration_cling_description (2752413805582227644) -->
-    <skip />
-    <!-- no translation found for migration_cling_copy_apps (946331230090919440) -->
-    <skip />
-    <!-- no translation found for migration_cling_use_default (2626475813981258626) -->
-    <skip />
-    <!-- no translation found for workspace_cling_title (5626202359865825661) -->
-    <skip />
-    <!-- no translation found for workspace_cling_move_item (528201129978005352) -->
-    <skip />
-    <!-- no translation found for folder_cling_title (3894908818693254164) -->
-    <skip />
-    <!-- no translation found for folder_cling_create_folder (6158215559475836131) -->
-    <skip />
-    <!-- no translation found for cling_dismiss (8962359497601507581) -->
-    <skip />
-    <!-- no translation found for folder_opened (94695026776264709) -->
-    <skip />
-    <!-- no translation found for folder_tap_to_close (1884479294466410023) -->
-    <skip />
-    <!-- no translation found for folder_tap_to_rename (9191075570492871147) -->
-    <skip />
-    <!-- no translation found for folder_closed (4100806530910930934) -->
-    <skip />
-    <!-- no translation found for folder_renamed (1794088362165669656) -->
-    <skip />
-    <!-- no translation found for folder_name_format (6629239338071103179) -->
-    <skip />
-    <!-- no translation found for widget_button_text (2880537293434387943) -->
-    <skip />
-    <!-- no translation found for wallpaper_button_text (8404103075899945851) -->
-    <skip />
-    <!-- no translation found for settings_button_text (8119458837558863227) -->
-    <skip />
-    <!-- no translation found for package_state_enqueued (6227252464303085641) -->
-    <skip />
-    <!-- no translation found for package_state_downloading (4088770468458724721) -->
-    <skip />
-    <!-- no translation found for package_state_installing (7588193972189849870) -->
-    <skip />
-    <!-- no translation found for package_state_unknown (7592128424511031410) -->
-    <skip />
-    <!-- no translation found for package_state_error (7672093962724223588) -->
-    <skip />
-</resources>
diff --git a/tests/Android.mk b/tests/Android.mk
index 4d1bfa6..3d9077d 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -23,6 +23,7 @@
 	androidx.annotation_annotation \
 	androidx.test.runner \
 	androidx.test.rules \
+	androidx.preference_preference \
 	androidx.test.uiautomator_uiautomator
 
 ifneq (,$(wildcard frameworks/base))
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 34e425d..a39f215 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -41,6 +41,7 @@
 import com.android.launcher3.widget.WidgetsRecyclerView;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -101,7 +102,7 @@
         mLauncher.pressHome();
     }
 
-    @Test
+    @Ignore
     public void testOpenHomeSettingsFromWorkspace() {
         mDevice.pressMenu();
         mDevice.waitForIdle();