Loading quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +11 −6 Original line number Diff line number Diff line Loading @@ -65,6 +65,10 @@ import android.view.InputEvent; import android.view.MotionEvent; import android.view.Surface; import androidx.annotation.BinderThread; import androidx.annotation.UiThread; import androidx.annotation.WorkerThread; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; import com.android.launcher3.ResourceUtils; Loading @@ -75,6 +79,7 @@ import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.DejankBinderTracker; import com.android.launcher3.util.DefaultDisplay; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener; Loading Loading @@ -106,10 +111,6 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; import androidx.annotation.BinderThread; import androidx.annotation.UiThread; import androidx.annotation.WorkerThread; /** * Wrapper around a list for processing arguments. */ Loading Loading @@ -536,6 +537,7 @@ public class TouchInteractionService extends Service implements } private void onInputEvent(InputEvent ev) { DejankBinderTracker.allowBinderTrackingInTests(); if (TestProtocol.sDebugTracing) { Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onInputEvent " + ev); } Loading Loading @@ -571,6 +573,7 @@ public class TouchInteractionService extends Service implements TOUCH_INTERACTION_LOG.addLog("onMotionEvent", event.getActionMasked()); mUncheckedConsumer.onMotionEvent(event); DejankBinderTracker.disallowBinderTrackingInTests(); } private boolean validSystemUiFlags() { Loading Loading @@ -634,7 +637,8 @@ public class TouchInteractionService extends Service implements } private InputConsumer newBaseConsumer(boolean useSharedState, MotionEvent event) { RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0); RunningTaskInfo runningTaskInfo = DejankBinderTracker.whitelistIpcs( () -> mAM.getRunningTask(0)); if (!useSharedState) { sSwipeSharedState.clearAllState(false /* finishAnimation */); } Loading @@ -650,7 +654,8 @@ public class TouchInteractionService extends Service implements if (isExcludedAssistant(runningTaskInfo)) { // In the case where we are in the excluded assistant state, ignore it and treat the // running activity as the task behind the assistant runningTaskInfo = mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT); runningTaskInfo = DejankBinderTracker.whitelistIpcs( () -> mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT)); if (!ActivityManagerWrapper.isHomeTask(runningTaskInfo)) { final ComponentName homeComponent = mOverviewComponentObserver.getHomeIntent().getComponent(); Loading quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +8 −3 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.uioverrides.DejankBinderTracker; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; Loading Loading @@ -423,9 +424,13 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> private void initializeLauncherAnimationController() { buildAnimationController(); DejankBinderTracker.whitelistIpcs(() -> { // Only used in debug builds if (LatencyTrackerCompat.isEnabled(mContext)) { LatencyTrackerCompat.logToggleRecents((int) (mLauncherFrameDrawnTime - mTouchTimeMs)); LatencyTrackerCompat.logToggleRecents( (int) (mLauncherFrameDrawnTime - mTouchTimeMs)); } }); // This method is only called when STATE_GESTURE_STARTED is set, so we can enable the // high-res thumbnail loader here once we are sure that we will end up in an overview state Loading quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java +2 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.launcher3.R; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.appprediction.PredictionUiStateManager; import com.android.launcher3.appprediction.PredictionUiStateManager.Client; import com.android.launcher3.uioverrides.DejankBinderTracker; import com.android.launcher3.views.ScrimView; import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.util.ClipAnimationHelper; Loading Loading @@ -172,7 +173,7 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements StateL @Override public boolean shouldUseMultiWindowTaskSizeStrategy() { return mActivity.isInMultiWindowMode(); return DejankBinderTracker.whitelistIpcs(() -> mActivity.isInMultiWindowMode()); } @Override Loading quickstep/src/com/android/launcher3/uioverrides/DejankBinderTracker.java 0 → 100644 +159 −0 Original line number Diff line number Diff line /** * 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(); } } src/com/android/launcher3/BaseDraggingActivity.java +3 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.uioverrides.DejankBinderTracker; import com.android.launcher3.uioverrides.DisplayRotationListener; import com.android.launcher3.uioverrides.WallpaperColorInfo; import com.android.launcher3.util.PackageManagerHelper; Loading Loading @@ -65,7 +66,8 @@ public abstract class BaseDraggingActivity extends BaseActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mIsSafeModeEnabled = getPackageManager().isSafeMode(); mIsSafeModeEnabled = DejankBinderTracker.whitelistIpcs(() -> getPackageManager().isSafeMode()); mRotationListener = new DisplayRotationListener(this, this::onDeviceRotationChanged); // Update theme Loading Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +11 −6 Original line number Diff line number Diff line Loading @@ -65,6 +65,10 @@ import android.view.InputEvent; import android.view.MotionEvent; import android.view.Surface; import androidx.annotation.BinderThread; import androidx.annotation.UiThread; import androidx.annotation.WorkerThread; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; import com.android.launcher3.ResourceUtils; Loading @@ -75,6 +79,7 @@ import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.DejankBinderTracker; import com.android.launcher3.util.DefaultDisplay; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener; Loading Loading @@ -106,10 +111,6 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; import androidx.annotation.BinderThread; import androidx.annotation.UiThread; import androidx.annotation.WorkerThread; /** * Wrapper around a list for processing arguments. */ Loading Loading @@ -536,6 +537,7 @@ public class TouchInteractionService extends Service implements } private void onInputEvent(InputEvent ev) { DejankBinderTracker.allowBinderTrackingInTests(); if (TestProtocol.sDebugTracing) { Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onInputEvent " + ev); } Loading Loading @@ -571,6 +573,7 @@ public class TouchInteractionService extends Service implements TOUCH_INTERACTION_LOG.addLog("onMotionEvent", event.getActionMasked()); mUncheckedConsumer.onMotionEvent(event); DejankBinderTracker.disallowBinderTrackingInTests(); } private boolean validSystemUiFlags() { Loading Loading @@ -634,7 +637,8 @@ public class TouchInteractionService extends Service implements } private InputConsumer newBaseConsumer(boolean useSharedState, MotionEvent event) { RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0); RunningTaskInfo runningTaskInfo = DejankBinderTracker.whitelistIpcs( () -> mAM.getRunningTask(0)); if (!useSharedState) { sSwipeSharedState.clearAllState(false /* finishAnimation */); } Loading @@ -650,7 +654,8 @@ public class TouchInteractionService extends Service implements if (isExcludedAssistant(runningTaskInfo)) { // In the case where we are in the excluded assistant state, ignore it and treat the // running activity as the task behind the assistant runningTaskInfo = mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT); runningTaskInfo = DejankBinderTracker.whitelistIpcs( () -> mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT)); if (!ActivityManagerWrapper.isHomeTask(runningTaskInfo)) { final ComponentName homeComponent = mOverviewComponentObserver.getHomeIntent().getComponent(); Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +8 −3 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.uioverrides.DejankBinderTracker; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; Loading Loading @@ -423,9 +424,13 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> private void initializeLauncherAnimationController() { buildAnimationController(); DejankBinderTracker.whitelistIpcs(() -> { // Only used in debug builds if (LatencyTrackerCompat.isEnabled(mContext)) { LatencyTrackerCompat.logToggleRecents((int) (mLauncherFrameDrawnTime - mTouchTimeMs)); LatencyTrackerCompat.logToggleRecents( (int) (mLauncherFrameDrawnTime - mTouchTimeMs)); } }); // This method is only called when STATE_GESTURE_STARTED is set, so we can enable the // high-res thumbnail loader here once we are sure that we will end up in an overview state Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java +2 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.launcher3.R; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.appprediction.PredictionUiStateManager; import com.android.launcher3.appprediction.PredictionUiStateManager.Client; import com.android.launcher3.uioverrides.DejankBinderTracker; import com.android.launcher3.views.ScrimView; import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.util.ClipAnimationHelper; Loading Loading @@ -172,7 +173,7 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements StateL @Override public boolean shouldUseMultiWindowTaskSizeStrategy() { return mActivity.isInMultiWindowMode(); return DejankBinderTracker.whitelistIpcs(() -> mActivity.isInMultiWindowMode()); } @Override Loading
quickstep/src/com/android/launcher3/uioverrides/DejankBinderTracker.java 0 → 100644 +159 −0 Original line number Diff line number Diff line /** * 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(); } }
src/com/android/launcher3/BaseDraggingActivity.java +3 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.uioverrides.DejankBinderTracker; import com.android.launcher3.uioverrides.DisplayRotationListener; import com.android.launcher3.uioverrides.WallpaperColorInfo; import com.android.launcher3.util.PackageManagerHelper; Loading Loading @@ -65,7 +66,8 @@ public abstract class BaseDraggingActivity extends BaseActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mIsSafeModeEnabled = getPackageManager().isSafeMode(); mIsSafeModeEnabled = DejankBinderTracker.whitelistIpcs(() -> getPackageManager().isSafeMode()); mRotationListener = new DisplayRotationListener(this, this::onDeviceRotationChanged); // Update theme Loading