fix(QuickSwitch): Transition behaviour compat for 16.0 (#7282)
This commit is contained in:
1 parent
12c2ee2219
commit
d2d1775131
18 files changed
+294
-36
No files matched your search
@@ -11,6 +11,10 @@ val isOnePlusStock = checkOnePlusStock()
|
||||
|
||||
val isGestureNavContractCompatible = checkGestureNavContract()
|
||||
|
||||
val isNothingOs = checkNothingStock()
|
||||
|
||||
val isAndroidBaklavaInitial = checkGenericBaklavaInitial()
|
||||
|
||||
private fun checkOnePlusStock(): Boolean = when {
|
||||
getSystemProperty("ro.rom.version", "")
|
||||
.contains(Regex("Oxygen OS|Hydrogen OS|O2_BETA|H2_BETA")) -> true
|
||||
@@ -52,6 +56,18 @@ private fun checkMeizuStock(): Boolean = when {
|
||||
else -> false
|
||||
}
|
||||
|
||||
private fun checkNothingStock(): Boolean = when {
|
||||
getSystemProperty("ro.nothing.version.id", "").isNotEmpty() -> true
|
||||
getSystemProperty("ro.build.nothing.version", "").isNotEmpty() -> true
|
||||
getSystemProperty("ro.build.nothing.feature.base", "").isNotEmpty() -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
private fun checkGenericBaklavaInitial(): Boolean = when {
|
||||
arrayOf("BP2A.", "BD1A.").any { prefix -> Build.FINGERPRINT.contains(prefix) } -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
private fun checkGestureNavContract(): Boolean = when {
|
||||
!Utilities.ATLEAST_Q -> false
|
||||
checkOnePlusStock() -> false
|
||||
|
||||
@@ -1258,7 +1258,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
homeCheck.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
|
||||
|
||||
homeCheck.mRequirements[2].mNot = true;
|
||||
homeCheck.mRequirements[2].mCustomAnimation = true;
|
||||
if (Utilities.ATLEAST_BAKLAVA) { // LC-Note: QuickSwitch compatibility!
|
||||
homeCheck.mRequirements[2].mCustomAnimation = true;
|
||||
}
|
||||
homeCheck.mRequirements[2].mMustBeTask = true;
|
||||
homeCheck.mRequirements[2].mMustBeIndependent = true;
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.window.RemoteTransition
|
||||
import android.window.TransitionFilter
|
||||
import android.window.TransitionFilter.CONTAINER_ORDER_TOP
|
||||
import com.android.internal.jank.Cuj
|
||||
import com.android.launcher3.Utilities
|
||||
import com.android.launcher3.desktop.DesktopAppLaunchTransition.AppLaunchType
|
||||
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
|
||||
import com.android.quickstep.SystemUiProxy
|
||||
@@ -74,7 +75,8 @@ class DesktopAppLaunchTransitionManager(
|
||||
}
|
||||
|
||||
private fun shouldRegisterTransitions(): Boolean =
|
||||
DesktopModeStatus.canEnterDesktopMode(context) &&
|
||||
Utilities.ATLEAST_BAKLAVA && // LC-Note: This is only available for Baklava
|
||||
DesktopModeStatus.canEnterDesktopMode(context) &&
|
||||
DesktopModeFlags.ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX.isTrue
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.launcher3.taskbar
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Insets
|
||||
@@ -22,6 +23,7 @@ import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.graphics.Region
|
||||
import android.os.Binder
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
import android.view.DisplayInfo
|
||||
import android.view.Gravity
|
||||
@@ -50,6 +52,7 @@ import androidx.core.graphics.toRegion
|
||||
import com.android.internal.policy.GestureNavigationSettingsObserver
|
||||
import com.android.launcher3.DeviceProfile
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.Utilities
|
||||
import com.android.launcher3.anim.AlphaUpdateListener
|
||||
import com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UNIFICATION
|
||||
import com.android.launcher3.config.FeatureFlags.enableTaskbarNoRecreate
|
||||
@@ -89,12 +92,29 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
|
||||
onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
|
||||
}
|
||||
private val gestureNavSettingsObserver =
|
||||
GestureNavigationSettingsObserver(
|
||||
context.mainThreadHandler,
|
||||
Executors.UI_HELPER_EXECUTOR.handler,
|
||||
context,
|
||||
this::onTaskbarOrBubblebarWindowHeightOrInsetsChanged,
|
||||
)
|
||||
if (Utilities.ATLEAST_V) { // LC-Note: This is only available for V
|
||||
GestureNavigationSettingsObserver(
|
||||
context.mainThreadHandler,
|
||||
Executors.UI_HELPER_EXECUTOR.handler,
|
||||
context,
|
||||
this::onTaskbarOrBubblebarWindowHeightOrInsetsChanged,
|
||||
)
|
||||
} else {
|
||||
try {
|
||||
GestureNavigationSettingsObserver::class.java
|
||||
.getConstructor(Handler::class.java, Context::class.java, Runnable::class.java)
|
||||
.newInstance(
|
||||
context.mainThreadHandler,
|
||||
context,
|
||||
Runnable { onTaskbarOrBubblebarWindowHeightOrInsetsChanged() },
|
||||
)
|
||||
} catch (e: ReflectiveOperationException) {
|
||||
throw IllegalStateException(
|
||||
"LC: Unable to create legacy GestureNavigationSettingsObserver! QuickSwitch is tested for Android 14 above!",
|
||||
e,
|
||||
)
|
||||
}
|
||||
}
|
||||
@VisibleForTesting val debugTouchableRegion = DebugTouchableRegion()
|
||||
|
||||
// Initialized in init.
|
||||
|
||||
@@ -81,6 +81,7 @@ import android.graphics.Matrix;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
@@ -1687,8 +1688,19 @@ public abstract class AbsSwipeUpHandler<
|
||||
boolean hasValidLeash = runningTaskTarget != null
|
||||
&& runningTaskTarget.leash != null
|
||||
&& runningTaskTarget.leash.isValid();
|
||||
|
||||
boolean enableDesktopWindowingPipCompat = false;
|
||||
// Literal int because https://github.com/LawnchairLauncher/lawnchair/issues/6817
|
||||
if (Build.VERSION.SDK_INT >= 36 && Build.VERSION.SDK_INT_FULL >= 3600001) {
|
||||
try {
|
||||
enableDesktopWindowingPipCompat = DesktopExperienceFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue();
|
||||
} catch (Exception e) {
|
||||
Log.d("LC-AbsSwipeUpHandler", "Failed to get ENABLE_DESKTOP_WINDOWING_PIP flag, defaulting to false", e);
|
||||
}
|
||||
}
|
||||
|
||||
final boolean swipeUpInDesktopWindowing =
|
||||
DesktopExperienceFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()
|
||||
enableDesktopWindowingPipCompat
|
||||
&& runningTaskTarget != null
|
||||
&& runningTaskTarget.taskInfo.getWindowingMode()
|
||||
== WINDOWING_MODE_FREEFORM;
|
||||
|
||||
@@ -42,7 +42,7 @@ private val USER_SETUP_COMPLETE_URI = Settings.Secure.getUriFor(USER_SETUP_COMPL
|
||||
class AllAppsActionManager(
|
||||
private val context: Context,
|
||||
private val bgExecutor: Executor,
|
||||
private val quickstepKeyGestureEventsManager: QuickstepKeyGestureEventsManager,
|
||||
private val quickstepKeyGestureEventsManager: QuickstepKeyGestureEventsManager?, // LC-Note: Nullable because this isn't available for U and lower
|
||||
private val createAllAppsPendingIntent: () -> PendingIntent,
|
||||
) {
|
||||
|
||||
@@ -104,12 +104,12 @@ class AllAppsActionManager(
|
||||
),
|
||||
GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS,
|
||||
)
|
||||
quickstepKeyGestureEventsManager.registerAllAppsKeyGestureEvent(
|
||||
quickstepKeyGestureEventsManager?.registerAllAppsKeyGestureEvent( // LC-Note: QuickSwitch compatibility!
|
||||
allAppsPendingIntent
|
||||
)
|
||||
} else {
|
||||
accessibilityManager.unregisterSystemAction(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS)
|
||||
quickstepKeyGestureEventsManager.unregisterAllAppsKeyGestureEvent()
|
||||
quickstepKeyGestureEventsManager?.unregisterAllAppsKeyGestureEvent() // LC-Note: QuickSwitch compatibility!
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ class AllAppsActionManager(
|
||||
context
|
||||
.getSystemService(AccessibilityManager::class.java)
|
||||
?.unregisterSystemAction(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS)
|
||||
quickstepKeyGestureEventsManager.unregisterAllAppsKeyGestureEvent()
|
||||
quickstepKeyGestureEventsManager?.unregisterAllAppsKeyGestureEvent() // LC-Note: QuickSwitch compatibility!
|
||||
SettingsCache.INSTANCE[context].unregister(
|
||||
USER_SETUP_COMPLETE_URI,
|
||||
onSettingsChangeListener,
|
||||
|
||||
@@ -26,10 +26,12 @@ import android.content.Intent
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.graphics.Point
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
import android.os.Message
|
||||
import android.os.Parcel
|
||||
import android.os.RemoteException
|
||||
import android.os.Trace
|
||||
import android.os.Trace.traceBegin
|
||||
@@ -52,12 +54,14 @@ import android.window.WindowContainerTransaction
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.WorkerThread
|
||||
import app.lawnchair.util.isAndroidBaklavaInitial
|
||||
import app.lawnchair.util.isNothingOs
|
||||
//import app.lawnchair.gestures.type.GestureType
|
||||
import com.android.internal.logging.InstanceId
|
||||
import com.android.internal.util.ScreenshotRequest
|
||||
import com.android.internal.view.AppearanceRegion
|
||||
import com.android.launcher3.Flags
|
||||
import com.android.launcher3.Utilities.ATLEAST_BAKLAVA
|
||||
import com.android.launcher3.Utilities
|
||||
import com.android.launcher3.dagger.ApplicationContext
|
||||
import com.android.launcher3.dagger.LauncherAppComponent
|
||||
import com.android.launcher3.dagger.LauncherAppSingleton
|
||||
@@ -214,6 +218,36 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context:
|
||||
}
|
||||
}
|
||||
|
||||
private fun startInitialAndroid16RecentsTransition(
|
||||
recentTasks: IRecentTasks,
|
||||
pendingIntent: PendingIntent,
|
||||
intent: Intent?,
|
||||
options: Bundle,
|
||||
listener: IRecentsAnimationRunner,
|
||||
): Boolean {
|
||||
val data = Parcel.obtain(recentTasks.asBinder())
|
||||
return try {
|
||||
data.writeInterfaceToken(IRecentTasks.DESCRIPTOR)
|
||||
data.writeTypedObject(pendingIntent, 0)
|
||||
data.writeTypedObject(intent, 0)
|
||||
data.writeTypedObject(options, 0)
|
||||
data.writeStrongInterface(context.iApplicationThread)
|
||||
data.writeStrongInterface(listener)
|
||||
recentTasks.asBinder().transact(
|
||||
if (usesNothingOs4BaklavaInitialRecentsTransitionAidl()) {
|
||||
LC_TRANSACTION_startRecentsTransition_NothingOS_4_BaklavaInitial
|
||||
} else {
|
||||
LC_TRANSACTION_startRecentsTransition_AOSP_BaklavaInitial
|
||||
},
|
||||
data,
|
||||
null,
|
||||
IBinder.FLAG_ONEWAY,
|
||||
)
|
||||
} finally {
|
||||
data.recycle()
|
||||
}
|
||||
}
|
||||
|
||||
fun onBackEvent(backEvent: KeyEvent?) =
|
||||
executeWithErrorLog({ "Failed call onBackPressed" }) {
|
||||
systemUiProxy?.onBackEvent(backEvent)
|
||||
@@ -1108,7 +1142,7 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context:
|
||||
|
||||
private fun shouldEnableRunningTasksForDesktopMode(): Boolean =
|
||||
DesktopModeStatus.canEnterDesktopMode(context) &&
|
||||
if (ATLEAST_BAKLAVA) {
|
||||
if (Utilities.ATLEAST_BAKLAVA) {
|
||||
ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS.isTrue
|
||||
} else {
|
||||
false
|
||||
@@ -1271,6 +1305,24 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context:
|
||||
displayId: Int,
|
||||
): Boolean {
|
||||
executeWithErrorLog({ "Error starting recents via shell" }) {
|
||||
if (usesAOSPBaklavaInitialRecentsTransitionAidl()) {
|
||||
if (wct != null) {
|
||||
Log.w("LC-SystemUiProxy", "Android 16 initial does not support WCT-backed recents transitions")
|
||||
return false
|
||||
}
|
||||
val recentTasks = recentTasks ?: return false
|
||||
return startInitialAndroid16RecentsTransition(
|
||||
recentTasks,
|
||||
getRecentsPendingIntent(displayId),
|
||||
intent,
|
||||
options.toBundle().apply {
|
||||
if (useSyntheticRecentsTransition) {
|
||||
putBoolean("is_synthetic_recents_transition", true)
|
||||
}
|
||||
},
|
||||
RecentsAnimationListenerStub(listener),
|
||||
)
|
||||
}
|
||||
recentTasks?.startRecentsTransition(
|
||||
getRecentsPendingIntent(displayId),
|
||||
intent,
|
||||
@@ -1284,8 +1336,7 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context:
|
||||
RecentsAnimationListenerStub(listener),
|
||||
)
|
||||
?: run {
|
||||
// LC-Ignored
|
||||
//ActiveGestureProtoLogProxy.logRecentTasksMissing()
|
||||
if (Utilities.ATLEAST_S) ActiveGestureProtoLogProxy.logRecentTasksMissing()
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -1295,6 +1346,45 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context:
|
||||
|
||||
private class RecentsAnimationListenerStub(val listener: RecentsAnimationListener) :
|
||||
IRecentsAnimationRunner.Stub() {
|
||||
override fun onTransact(
|
||||
code: Int,
|
||||
data: Parcel,
|
||||
reply: Parcel?,
|
||||
flags: Int,
|
||||
): Boolean {
|
||||
if (usesNothingOs4BaklavaInitialRecentsTransitionAidl()
|
||||
&& code == LC_TRANSACTION_onAnimationStartWithSurfaceTransaction) {
|
||||
// LC-Note: What even the fuck this is (this handles a Nothing OS 4 binder transaction)
|
||||
data.enforceInterface(IRecentsAnimationRunner.DESCRIPTOR) // This can be mistaken for IRecentsAnimationController, keep it this way
|
||||
val controller = IRecentsAnimationController.Stub.asInterface(
|
||||
data.readStrongBinder())
|
||||
val transitionInfo = data.readTypedObject(TransitionInfo.CREATOR)
|
||||
val transaction = data.readTypedObject(Transaction.CREATOR)
|
||||
val apps = data.createTypedArray(RemoteAnimationTarget.CREATOR)
|
||||
val wallpapers = data.createTypedArray(RemoteAnimationTarget.CREATOR)
|
||||
val homeContentInsets = data.readTypedObject(Rect.CREATOR)
|
||||
val minimizedHomeBounds = data.readTypedObject(Rect.CREATOR)
|
||||
val extras = data.readTypedObject(Bundle.CREATOR)
|
||||
data.enforceNoDataAvail()
|
||||
try {
|
||||
transaction?.apply()
|
||||
} finally {
|
||||
transaction?.close()
|
||||
}
|
||||
onAnimationStart(
|
||||
controller,
|
||||
apps,
|
||||
wallpapers,
|
||||
homeContentInsets,
|
||||
minimizedHomeBounds,
|
||||
extras,
|
||||
transitionInfo,
|
||||
)
|
||||
return true
|
||||
}
|
||||
return super.onTransact(code, data, reply, flags)
|
||||
}
|
||||
|
||||
override fun onAnimationStart(
|
||||
controller: IRecentsAnimationController,
|
||||
apps: Array<RemoteAnimationTarget>?,
|
||||
@@ -1397,6 +1487,31 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context:
|
||||
companion object {
|
||||
private const val TAG = "SystemUiProxy"
|
||||
|
||||
/** LC-Note: Android 16.0 start recents transition binder code */
|
||||
private const val LC_TRANSACTION_startRecentsTransition_AOSP_BaklavaInitial =
|
||||
IBinder.FIRST_CALL_TRANSACTION + 4
|
||||
|
||||
/** LC-Note: Android 16.0, Nothing OS 4.0 start recents transition binder code whose value
|
||||
* is higher than AOSP 16.0 or [LC_TRANSACTION_startRecentsTransition_AOSP_BaklavaInitial] */
|
||||
private const val LC_TRANSACTION_startRecentsTransition_NothingOS_4_BaklavaInitial =
|
||||
IBinder.FIRST_CALL_TRANSACTION + 5
|
||||
|
||||
/** LC-Note: onAnimationStartWithSurfaceTransac binder code */
|
||||
private const val LC_TRANSACTION_onAnimationStartWithSurfaceTransaction =
|
||||
IBinder.FIRST_CALL_TRANSACTION + 4
|
||||
|
||||
/** LC-Note: Should use AOSP 16.0 recents transition AIDL? */
|
||||
private fun usesAOSPBaklavaInitialRecentsTransitionAidl(): Boolean {
|
||||
return Build.VERSION.SDK_INT == Build.VERSION_CODES.BAKLAVA
|
||||
&& isAndroidBaklavaInitial
|
||||
}
|
||||
|
||||
/** LC-Note: Should use Nothing OS 16.0 recents transition AIDL? */
|
||||
private fun usesNothingOs4BaklavaInitialRecentsTransitionAidl(): Boolean {
|
||||
return usesAOSPBaklavaInitialRecentsTransitionAidl()
|
||||
&& isNothingOs
|
||||
}
|
||||
|
||||
@JvmField val INSTANCE = DaggerSingletonObject(LauncherAppComponent::getSystemUiProxy)
|
||||
|
||||
private const val MSG_SET_SHELF_HEIGHT = 1
|
||||
|
||||
@@ -337,7 +337,9 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
|
||||
final ActivityOptions options = ActivityOptions.makeBasic();
|
||||
options.setPendingIntentBackgroundActivityStartMode(
|
||||
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS);
|
||||
Utilities.ATLEAST_BAKLAVA // LC-Note: QuickSwitch compatibility!
|
||||
? ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS
|
||||
: ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
|
||||
options.setTransientLaunch();
|
||||
options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
|
||||
options.setLaunchDisplayId(mDisplayId);
|
||||
|
||||
@@ -47,6 +47,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.dagger.ApplicationContext;
|
||||
import com.android.launcher3.dagger.LauncherAppSingleton;
|
||||
import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
@@ -161,7 +162,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta
|
||||
// task is brought to front, then mark other tasks behind as not-visible
|
||||
if (taskInfo.getActivityType() == ACTIVITY_TYPE_HOME
|
||||
|| (taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
|
||||
&& !taskInfo.isActivityStackTransparent)) {
|
||||
&& (!Utilities.ATLEAST_BAKLAVA || !taskInfo.isActivityStackTransparent))) { // LC-Note: QuickSwitch compatibility!
|
||||
// We've moved the task to the front of the list above, so only iterate the tasks after
|
||||
for (int i = 1; i < mOrderedTaskList.size(); i++) {
|
||||
final TaskInfo info = mOrderedTaskList.get(i);
|
||||
|
||||
@@ -731,6 +731,7 @@ public class TouchInteractionService extends Service {
|
||||
|
||||
private DisplayRepository mDisplayRepository;
|
||||
|
||||
@Nullable // LC-Note: QuickSwitch compatibility!
|
||||
private QuickstepKeyGestureEventsManager mQuickstepKeyGestureEventsHandler;
|
||||
private DisplaysWithDecorationsRepositoryCompat mDisplaysWithDecorationsRepositoryCompat;
|
||||
private CoroutineDispatcher mCoroutineDispatcher;
|
||||
@@ -749,7 +750,9 @@ public class TouchInteractionService extends Service {
|
||||
mRotationTouchHelperRepository = RotationTouchHelper.REPOSITORY_INSTANCE.get(this);
|
||||
mRecentsWindowManagerRepository = RecentsWindowManager.REPOSITORY_INSTANCE.get(this);
|
||||
mSystemDecorationChangeObserver = SystemDecorationChangeObserver.getINSTANCE().get(this);
|
||||
mQuickstepKeyGestureEventsHandler = new QuickstepKeyGestureEventsManager(this);
|
||||
if (Utilities.ATLEAST_V) { // LC-Note: QuickSwitch compatibility!
|
||||
mQuickstepKeyGestureEventsHandler = new QuickstepKeyGestureEventsManager(this);
|
||||
}
|
||||
mCoroutineDispatcher = ProductionDispatchers.INSTANCE.getMain();
|
||||
mDisplaysWithDecorationsRepositoryCompat =
|
||||
LauncherDisplaysWithDecorationsRepositoryCompat.getINSTANCE().get(this);
|
||||
@@ -884,8 +887,10 @@ public class TouchInteractionService extends Service {
|
||||
onOverviewTargetChanged(mOverviewComponentObserver.isHomeAndOverviewSame());
|
||||
|
||||
mTaskbarManager.onUserUnlocked();
|
||||
mQuickstepKeyGestureEventsHandler.registerOverviewKeyGestureEvent(
|
||||
createOverviewGestureHandler());
|
||||
if (mQuickstepKeyGestureEventsHandler != null) { // LC-Note: QuickSwitch compatibility!
|
||||
mQuickstepKeyGestureEventsHandler.registerOverviewKeyGestureEvent(
|
||||
createOverviewGestureHandler());
|
||||
}
|
||||
}
|
||||
|
||||
public OverviewCommandHelper getOverviewCommandHelper() {
|
||||
@@ -971,7 +976,9 @@ public class TouchInteractionService extends Service {
|
||||
+ " instance=" + System.identityHashCode(this));
|
||||
if (LockedUserState.get(this).isUserUnlocked()) {
|
||||
mInputConsumer.unregisterInputConsumer();
|
||||
mQuickstepKeyGestureEventsHandler.onDestroy();
|
||||
if (mQuickstepKeyGestureEventsHandler != null) { // LC-Note: QuickSwitch compatibility!
|
||||
mQuickstepKeyGestureEventsHandler.onDestroy();
|
||||
}
|
||||
mOverviewComponentObserver.setHomeDisabled(false);
|
||||
mOverviewComponentObserver.removeOverviewChangeListener(mOverviewChangeListener);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Trace
|
||||
import android.view.Display.DEFAULT_DISPLAY
|
||||
import com.android.launcher3.Utilities
|
||||
import com.android.launcher3.provider.RestoreDbTask
|
||||
import com.android.launcher3.util.Executors
|
||||
import com.android.launcher3.util.LockedUserState
|
||||
@@ -41,6 +42,8 @@ object ActivityPreloadUtil {
|
||||
}
|
||||
|
||||
private fun preloadOverview(ctx: Context, fromInit: Boolean, forSUWAllSet: Boolean) {
|
||||
if (!Utilities.ATLEAST_BAKLAVA) return // LC-Note: QuickSwitch compatibility!
|
||||
|
||||
Trace.beginSection("preloadOverview(fromInit=$fromInit, forSUWAllSet=$forSUWAllSet)")
|
||||
|
||||
try {
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.util.Log
|
||||
import android.view.Display.DEFAULT_DISPLAY
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.android.internal.app.AssistUtils
|
||||
import com.android.launcher3.Utilities
|
||||
import com.android.launcher3.dagger.ApplicationContext
|
||||
import com.android.launcher3.logging.StatsLogManager
|
||||
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LAUNCH_ASSISTANT_FAILED_SERVICE_ERROR
|
||||
@@ -62,7 +63,11 @@ internal constructor(
|
||||
SystemUiProxy.INSTANCE[context],
|
||||
StatsLogManager.newInstance(context),
|
||||
ContextualSearchHapticManager.INSTANCE[context],
|
||||
context.getSystemService(ContextualSearchManager::class.java),
|
||||
if (Utilities.ATLEAST_V) {
|
||||
context.getSystemService(ContextualSearchManager::class.java)
|
||||
} else { // LC-Note: QuickSwitch compatibility!
|
||||
null
|
||||
},
|
||||
)
|
||||
|
||||
@Inject
|
||||
@@ -80,13 +85,20 @@ internal constructor(
|
||||
systemUiProxy,
|
||||
logManagerFactory.create(context),
|
||||
hapticManager,
|
||||
context.getSystemService(ContextualSearchManager::class.java),
|
||||
if (Utilities.ATLEAST_V) { // LC-Note: QuickSwitch compatibility!
|
||||
context.getSystemService(ContextualSearchManager::class.java)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
|
||||
/** @return Array of AssistUtils.INVOCATION_TYPE_* that we want to handle instead of SysUI. */
|
||||
fun getSysUiAssistOverrideInvocationTypes(): IntArray {
|
||||
val overrideInvocationTypes = com.android.launcher3.util.IntArray()
|
||||
if (context.packageManager.hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)) {
|
||||
// LC-Note: QuickSwitch compatibility!
|
||||
if (Utilities.ATLEAST_V &&
|
||||
context.packageManager.hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)
|
||||
) {
|
||||
overrideInvocationTypes.add(AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS)
|
||||
}
|
||||
return overrideInvocationTypes.toArray()
|
||||
@@ -98,7 +110,11 @@ internal constructor(
|
||||
*/
|
||||
fun tryStartAssistOverride(invocationType: Int): Boolean {
|
||||
if (invocationType == AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS) {
|
||||
if (!context.packageManager.hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)) {
|
||||
// LC-Note: QuickSwitch compatibility!
|
||||
if (
|
||||
!Utilities.ATLEAST_V ||
|
||||
!context.packageManager.hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)
|
||||
) {
|
||||
// When Contextual Search is disabled, fall back to Assistant.
|
||||
return false
|
||||
}
|
||||
@@ -142,7 +158,8 @@ internal constructor(
|
||||
*/
|
||||
fun runContextualSearchInvocationChecksAndLogFailures(): Boolean {
|
||||
if (
|
||||
contextualSearchManager == null ||
|
||||
!Utilities.ATLEAST_V || // LC-Note: QuickSwitch compatibility!
|
||||
contextualSearchManager == null ||
|
||||
!context.packageManager.hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)
|
||||
) {
|
||||
Log.i(TAG, "Contextual Search invocation failed: no ContextualSearchManager")
|
||||
|
||||
@@ -99,12 +99,23 @@ public class ContextualSearchStateManager {
|
||||
mContextualSearchPackageReceiver =
|
||||
new SimpleBroadcastReceiver(context, UI_HELPER_EXECUTOR,
|
||||
(unused) -> requestUpdateProperties());
|
||||
mContextualSearchPackage = mContext.getResources().getString(
|
||||
com.android.internal.R.string.config_defaultContextualSearchPackageName);
|
||||
|
||||
// LC-Note: QuickSwitch compatibility!
|
||||
String resolvedCSPkgName;
|
||||
try {
|
||||
resolvedCSPkgName = mContext.getResources().getString(
|
||||
com.android.internal.R.string.config_defaultContextualSearchPackageName);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to get config_defaultContextualSearchPackageName", e);
|
||||
resolvedCSPkgName = "";
|
||||
}
|
||||
mContextualSearchPackage = resolvedCSPkgName;
|
||||
|
||||
mSystemUiProxy = systemUiProxy;
|
||||
mTopTaskTracker = topTaskTracker;
|
||||
|
||||
if (areAllContextualSearchFlagsDisabled()
|
||||
if (!Utilities.ATLEAST_V // LC-Note: QuickSwitch compatibility!
|
||||
|| areAllContextualSearchFlagsDisabled()
|
||||
|| !context.getPackageManager().hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)) {
|
||||
// If we had previously registered a SystemAction which is no longer valid, we need to
|
||||
// unregister it here.
|
||||
|
||||
@@ -90,7 +90,8 @@ public final class FeatureFlags {
|
||||
DISABLED, "Sends a notification whenever launcher encounters an uncaught exception.");
|
||||
|
||||
public static final boolean ENABLE_TASKBAR_NAVBAR_UNIFICATION =
|
||||
enableTaskbarNavbarUnification() && (!isPhone() || enableTaskbarOnPhones());
|
||||
Utilities.ATLEAST_V && enableTaskbarNavbarUnification()
|
||||
&& (!isPhone() || enableTaskbarOnPhones()); // LC-Note: QuickSwitch, Note, when this is enabled, it can crash with type 2019 on Android 14 and under
|
||||
|
||||
private static boolean isPhone() {
|
||||
final boolean isPhone;
|
||||
|
||||
@@ -39,6 +39,8 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
|
||||
import app.lawnchair.compat.LawnchairQuickstepCompat;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -111,8 +113,10 @@ public class Task {
|
||||
this.displayId = t.displayId;
|
||||
this.baseActivity = t.baseActivity;
|
||||
this.numActivities = t.numActivities;
|
||||
this.isTopActivityNoDisplay = t.isTopActivityNoDisplay;
|
||||
this.isActivityStackTransparent = t.isActivityStackTransparent;
|
||||
if (LawnchairQuickstepCompat.ATLEAST_BAKLAVA) { // LC-Note: QuickSwitch compatibility!
|
||||
this.isTopActivityNoDisplay = t.isTopActivityNoDisplay;
|
||||
this.isActivityStackTransparent = t.isActivityStackTransparent;
|
||||
}
|
||||
updateHashCode();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ dependencies {
|
||||
compileOnly projects.msdllib
|
||||
compileOnly projects.flags
|
||||
compileOnly projects.utils
|
||||
compileOnly libs.chickenhook.restrictionbypass
|
||||
}
|
||||
|
||||
ksp {
|
||||
|
||||
@@ -44,6 +44,7 @@ import android.annotation.SuppressLint;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
@@ -51,6 +52,8 @@ import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import org.chickenhook.restrictionbypass.RestrictionBypass;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/** Various utility functions for transitions. */
|
||||
@@ -408,7 +411,7 @@ public class TransitionUtil {
|
||||
null,
|
||||
new Rect(change.getStartAbsBounds()),
|
||||
taskInfo,
|
||||
change.isAllowEnterPip(),
|
||||
getAllowEnterPip(change), // LC-Note: QuickSwitch compatibility!
|
||||
INVALID_WINDOW_TYPE
|
||||
);
|
||||
target.setWillShowImeOnTarget(
|
||||
@@ -418,6 +421,28 @@ public class TransitionUtil {
|
||||
return target;
|
||||
}
|
||||
|
||||
/** Can you enter picture-in-picture mode?
|
||||
* <p>
|
||||
* SDK 35 or above: isAllowEnterPip()
|
||||
* <p>
|
||||
* SDK 34 or below: getAllowEnterPip()
|
||||
* <p>
|
||||
* LC-Note: QuickSwitch compatibility!
|
||||
*
|
||||
* @return true if the change allows entering picture-in-picture mode, false otherwise
|
||||
* */
|
||||
private static boolean getAllowEnterPip(TransitionInfo.Change change) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||
return change.isAllowEnterPip();
|
||||
}
|
||||
try {
|
||||
return (Boolean) RestrictionBypass.getMethod(
|
||||
TransitionInfo.Change.class, "getAllowEnterPip").invoke(change);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new IllegalStateException("Unable to read allowEnterPip from transition change", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new RemoteAnimationTarget from the provided change and leash
|
||||
*/
|
||||
|
||||
@@ -18,11 +18,30 @@ package com.android.wm.shell.shared.pip
|
||||
|
||||
import android.app.AppGlobals
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.window.DesktopExperienceFlags.ENABLE_DESKTOP_WINDOWING_PIP
|
||||
import com.android.wm.shell.Flags
|
||||
|
||||
class PipFlags {
|
||||
companion object {
|
||||
|
||||
/** LC-Note: Can you enable desktop windowing picture-in-picture?
|
||||
*
|
||||
* SDK 36.1 or above: ENABLE_DESKTOP_WINDOWING_PIP.isTrue
|
||||
*
|
||||
* SDK Anything else: false
|
||||
*
|
||||
* Note when an exception occurred it will default to false
|
||||
*/
|
||||
private val enableDesktopWindowingPipCompat = Build.VERSION.SDK_INT >= 36 && Build.VERSION.SDK_INT_FULL >= 3600001 && try { // Literal int because https://github.com/LawnchairLauncher/lawnchair/issues/6817
|
||||
ENABLE_DESKTOP_WINDOWING_PIP.isTrue
|
||||
} catch (e: Exception) {
|
||||
Log.d("LC-PipFlags", "Failed to get ENABLE_DESKTOP_WINDOWING_PIP flag, defaulting to false", e)
|
||||
false
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if PiP2 implementation should be used. Special note: if PiP on Desktop
|
||||
* Windowing is enabled, override the PiP2 gantry flag to be ON.
|
||||
@@ -31,7 +50,7 @@ class PipFlags {
|
||||
val isPip2ExperimentEnabled: Boolean by lazy {
|
||||
val isTv = AppGlobals.getPackageManager().hasSystemFeature(
|
||||
PackageManager.FEATURE_LEANBACK, 0)
|
||||
(Flags.enablePip2() || ENABLE_DESKTOP_WINDOWING_PIP.isTrue) && !isTv
|
||||
(Flags.enablePip2() || enableDesktopWindowingPipCompat) && !isTv
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
Reference in new issue
Block a user