mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-27 15:26:58 +00:00
Adding binder tracking support in tests
- Whitelist specific binder calls when handling touch during swipe up gestures - Only track binding for touch handling and certain launcher lifecycle changes for now Bug: 140246642 Change-Id: I6ba30280dd17da358662870f8719ae851536ad8b
This commit is contained in:
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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() {
|
||||
@@ -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 */);
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
@@ -423,9 +424,13 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
private void initializeLauncherAnimationController() {
|
||||
buildAnimationController();
|
||||
|
||||
if (LatencyTrackerCompat.isEnabled(mContext)) {
|
||||
LatencyTrackerCompat.logToggleRecents((int) (mLauncherFrameDrawnTime - mTouchTimeMs));
|
||||
}
|
||||
DejankBinderTracker.whitelistIpcs(() -> {
|
||||
// Only used in debug builds
|
||||
if (LatencyTrackerCompat.isEnabled(mContext)) {
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -116,6 +116,7 @@ import com.android.launcher3.qsb.QsbContainerView;
|
||||
import com.android.launcher3.states.InternalStateHandler;
|
||||
import com.android.launcher3.states.RotationHelper;
|
||||
import com.android.launcher3.touch.ItemClickHandler;
|
||||
import com.android.launcher3.uioverrides.DejankBinderTracker;
|
||||
import com.android.launcher3.uioverrides.UiFactory;
|
||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
@@ -309,6 +310,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
DejankBinderTracker.allowBinderTrackingInTests();
|
||||
RaceConditionTracker.onEvent(ON_CREATE_EVT, ENTER);
|
||||
if (DEBUG_STRICT_MODE) {
|
||||
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
|
||||
@@ -430,6 +432,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
}
|
||||
}
|
||||
});
|
||||
DejankBinderTracker.disallowBinderTrackingInTests();
|
||||
}
|
||||
|
||||
protected LauncherOverlayManager getDefaultOverlay() {
|
||||
@@ -941,6 +944,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
DejankBinderTracker.allowBinderTrackingInTests();
|
||||
RaceConditionTracker.onEvent(ON_START_EVT, ENTER);
|
||||
super.onStart();
|
||||
if (!mDeferOverlayCallbacks) {
|
||||
@@ -949,6 +953,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
|
||||
mAppWidgetHost.setListenIfResumed(true);
|
||||
RaceConditionTracker.onEvent(ON_START_EVT, EXIT);
|
||||
DejankBinderTracker.disallowBinderTrackingInTests();
|
||||
}
|
||||
|
||||
private void handleDeferredResume() {
|
||||
@@ -1043,6 +1048,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
DejankBinderTracker.allowBinderTrackingInTests();
|
||||
RaceConditionTracker.onEvent(ON_RESUME_EVT, ENTER);
|
||||
TraceHelper.beginSection("ON_RESUME");
|
||||
super.onResume();
|
||||
@@ -1068,6 +1074,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
|
||||
TraceHelper.endSection("ON_RESUME");
|
||||
RaceConditionTracker.onEvent(ON_RESUME_EVT, EXIT);
|
||||
DejankBinderTracker.disallowBinderTrackingInTests();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.os.Looper;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.launcher3.uioverrides.DejankBinderTracker;
|
||||
import com.android.launcher3.util.ResourceBasedOverride.Overrides;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -41,7 +42,8 @@ public class MainThreadInitializedObject<T> {
|
||||
public T get(Context context) {
|
||||
if (mValue == null) {
|
||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||
mValue = mProvider.get(context.getApplicationContext());
|
||||
mValue = DejankBinderTracker.whitelistIpcs(() ->
|
||||
mProvider.get(context.getApplicationContext()));
|
||||
} else {
|
||||
try {
|
||||
return MAIN_EXECUTOR.submit(() -> get(context)).get();
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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 android.os.IBinder;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A binder proxy transaction listener for tracking non-whitelisted binder calls.
|
||||
*/
|
||||
public class DejankBinderTracker {
|
||||
public static void whitelistIpcs(Runnable runnable) {}
|
||||
|
||||
public static <T> T whitelistIpcs(Supplier<T> supplier) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void allowBinderTrackingInTests() {}
|
||||
|
||||
public static void disallowBinderTrackingInTests() {}
|
||||
|
||||
public DejankBinderTracker(BiConsumer<String, Integer> unexpectedTransactionCallback) { }
|
||||
|
||||
public void startTracking() {}
|
||||
|
||||
public void stopTracking() {}
|
||||
|
||||
public Object onTransactStarted(IBinder binder, int transactionCode, int flags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object onTransactStarted(IBinder binder, int transactionCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onTransactEnded(Object session) {}
|
||||
|
||||
public static boolean isMainThread() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -30,13 +30,14 @@ else
|
||||
LOCAL_STATIC_JAVA_LIBRARIES += SystemUISharedLib
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, tapl) \
|
||||
../quickstep/src/com/android/launcher3/uioverrides/DejankBinderTracker.java \
|
||||
../src/com/android/launcher3/ResourceUtils.java \
|
||||
../src/com/android/launcher3/util/SecureSettingsObserver.java \
|
||||
../src/com/android/launcher3/testing/TestProtocol.java
|
||||
endif
|
||||
|
||||
LOCAL_MODULE := ub-launcher-aosp-tapl
|
||||
LOCAL_SDK_VERSION := current
|
||||
LOCAL_SDK_VERSION := system_current
|
||||
|
||||
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user