mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-27 15:26:58 +00:00
Fix android 14 crashes (#5620)
This commit is contained in:
committed by
GitHub
parent
40575a66a9
commit
cb8b206a50
@@ -144,7 +144,8 @@ public class RemoteTargetGluer {
|
|||||||
// a) mSplitBounds was already set (from the clicked GroupedTaskView)
|
// a) mSplitBounds was already set (from the clicked GroupedTaskView)
|
||||||
// b) A SplitBounds was passed up from shell (via AbsSwipeUpHandler)
|
// b) A SplitBounds was passed up from shell (via AbsSwipeUpHandler)
|
||||||
// If both of these are null, we are in a 1-app or 1-app-plus-assistant case.
|
// If both of these are null, we are in a 1-app or 1-app-plus-assistant case.
|
||||||
if (mSplitBounds == null) {
|
if (mSplitBounds == null && targets.extras != null
|
||||||
|
&& targets.extras.containsKey(KEY_EXTRA_SPLIT_BOUNDS)) {
|
||||||
SplitBounds shellSplitBounds = targets.extras.getParcelable(KEY_EXTRA_SPLIT_BOUNDS,
|
SplitBounds shellSplitBounds = targets.extras.getParcelable(KEY_EXTRA_SPLIT_BOUNDS,
|
||||||
SplitBounds.class);
|
SplitBounds.class);
|
||||||
mSplitBounds = convertShellSplitBoundsToLauncher(shellSplitBounds);
|
mSplitBounds = convertShellSplitBoundsToLauncher(shellSplitBounds);
|
||||||
|
|||||||
@@ -1570,6 +1570,16 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable {
|
|||||||
wallpapers, homeContentInsets, minimizedHomeBounds, extras);
|
wallpapers, homeContentInsets, minimizedHomeBounds, extras);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Support for Android 13 and below
|
||||||
|
public void onAnimationStart(IRecentsAnimationController controller,
|
||||||
|
RemoteAnimationTarget[] apps, RemoteAnimationTarget[] nonAppTargets,
|
||||||
|
Rect homeContentInsets, Rect minimizedHomeBounds) {
|
||||||
|
// Chain the call to the newer 6-argument version, passing null for the 'extras' bundle.
|
||||||
|
onAnimationStart(controller, apps, nonAppTargets, homeContentInsets,
|
||||||
|
minimizedHomeBounds, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationCanceled(int[] taskIds, TaskSnapshot[] taskSnapshots) {
|
public void onAnimationCanceled(int[] taskIds, TaskSnapshot[] taskSnapshots) {
|
||||||
listener.onAnimationCanceled(
|
listener.onAnimationCanceled(
|
||||||
|
|||||||
@@ -2883,7 +2883,12 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasDesktopTask(Task[] runningTasks) {
|
private boolean hasDesktopTask(Task[] runningTasks) {
|
||||||
if (!DesktopModeStatus.canEnterDesktopMode(getContext())) {
|
try {
|
||||||
|
if (!DesktopModeStatus.canEnterDesktopMode(getContext())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (NoClassDefFoundError e) {
|
||||||
|
// Desktop mode is not supported on this device
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (Task task : runningTasks) {
|
for (Task task : runningTasks) {
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ class WorkspaceItemProcessor(
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
Utilities.ATLEAST_U && (c.restoreFlag != 0 ||
|
Utilities.ATLEAST_V && (c.restoreFlag != 0 ||
|
||||||
Flags.enableSupportForArchiving() &&
|
Flags.enableSupportForArchiving() &&
|
||||||
activityInfo != null &&
|
activityInfo != null &&
|
||||||
activityInfo.applicationInfo.isArchived) && !TextUtils.isEmpty(targetPkg)
|
activityInfo.applicationInfo.isArchived) && !TextUtils.isEmpty(targetPkg)
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import android.content.Intent;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -53,6 +54,7 @@ import com.android.internal.app.IVoiceInteractionManagerService;
|
|||||||
import com.android.systemui.shared.recents.model.Task;
|
import com.android.systemui.shared.recents.model.Task;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -155,9 +157,24 @@ public class ActivityManagerWrapper {
|
|||||||
public @NonNull ThumbnailData getTaskThumbnail(int taskId, boolean isLowResolution) {
|
public @NonNull ThumbnailData getTaskThumbnail(int taskId, boolean isLowResolution) {
|
||||||
TaskSnapshot snapshot = null;
|
TaskSnapshot snapshot = null;
|
||||||
try {
|
try {
|
||||||
snapshot = getService().getTaskSnapshot(taskId, isLowResolution);
|
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||||
|
Method getTaskSnapshotMethod = getService().getClass().getMethod(
|
||||||
|
"getTaskSnapshot",
|
||||||
|
int.class, // taskId
|
||||||
|
boolean.class, // isLowResolution
|
||||||
|
boolean.class // isTranslucent (added in Android 14)
|
||||||
|
);
|
||||||
|
|
||||||
|
snapshot = (TaskSnapshot) getTaskSnapshotMethod.invoke(
|
||||||
|
getService(), taskId, isLowResolution, false);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
snapshot = getService().getTaskSnapshot(taskId, isLowResolution);
|
||||||
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "Failed to retrieve task snapshot", e);
|
Log.w(TAG, "Failed to retrieve task snapshot", e);
|
||||||
|
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
Log.e(TAG, "Failed to invoke getTaskSnapshot", e);
|
||||||
}
|
}
|
||||||
if (snapshot != null) {
|
if (snapshot != null) {
|
||||||
return ThumbnailData.fromSnapshot(snapshot);
|
return ThumbnailData.fromSnapshot(snapshot);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
|
|||||||
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
|
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
|
||||||
|
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
@@ -32,6 +33,8 @@ import android.view.InputEvent;
|
|||||||
import android.view.WindowManagerGlobal;
|
import android.view.WindowManagerGlobal;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the input consumer that allows the SystemUI to directly receive input.
|
* Manages the input consumer that allows the SystemUI to directly receive input.
|
||||||
@@ -139,7 +142,14 @@ public class InputConsumerController {
|
|||||||
if (mInputEventReceiver == null) {
|
if (mInputEventReceiver == null) {
|
||||||
final InputChannel inputChannel = new InputChannel();
|
final InputChannel inputChannel = new InputChannel();
|
||||||
try {
|
try {
|
||||||
mWindowManager.destroyInputConsumer(mToken, DEFAULT_DISPLAY);
|
// Hook for Android P (9) to VANILLA_ICE_CREAM (15), where the method signature changed
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
|
||||||
|
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||||
|
hookDestroyInputConsumer(mWindowManager);
|
||||||
|
} else {
|
||||||
|
mWindowManager.destroyInputConsumer(mToken, DEFAULT_DISPLAY);
|
||||||
|
}
|
||||||
|
|
||||||
mWindowManager.createInputConsumer(mToken, mName, DEFAULT_DISPLAY, inputChannel);
|
mWindowManager.createInputConsumer(mToken, mName, DEFAULT_DISPLAY, inputChannel);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Failed to create input consumer", e);
|
Log.e(TAG, "Failed to create input consumer", e);
|
||||||
@@ -152,13 +162,36 @@ public class InputConsumerController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IWindowManager @destroyInputConsumer reflection
|
||||||
|
*/
|
||||||
|
private void hookDestroyInputConsumer(IWindowManager mWindowManager) throws RemoteException {
|
||||||
|
try {
|
||||||
|
Class<?> iWindowManagerClass = Class.forName("android.view.IWindowManager");
|
||||||
|
Method destroyInputConsumerMethod = iWindowManagerClass.getMethod("destroyInputConsumer", String.class, int.class);
|
||||||
|
destroyInputConsumerMethod.invoke(mWindowManager, mName, DEFAULT_DISPLAY);
|
||||||
|
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException |
|
||||||
|
InvocationTargetException e) {
|
||||||
|
Log.e(TAG, "Failed to invoke destroyInputConsumer", e);
|
||||||
|
mWindowManager.destroyInputConsumer(mToken, DEFAULT_DISPLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregisters the input consumer.
|
* Unregisters the input consumer.
|
||||||
*/
|
*/
|
||||||
public void unregisterInputConsumer() {
|
public void unregisterInputConsumer() {
|
||||||
if (mInputEventReceiver != null) {
|
if (mInputEventReceiver != null) {
|
||||||
try {
|
try {
|
||||||
mWindowManager.destroyInputConsumer(mToken, DEFAULT_DISPLAY);
|
// Hook for Android P (9) to VANILLA_ICE_CREAM (15), where the method signature changed
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
|
||||||
|
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||||
|
hookDestroyInputConsumer(mWindowManager);
|
||||||
|
} else {
|
||||||
|
mWindowManager.destroyInputConsumer(mToken, DEFAULT_DISPLAY);
|
||||||
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Failed to destroy input consumer", e);
|
Log.e(TAG, "Failed to destroy input consumer", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.systemui.shared.system;
|
package com.android.systemui.shared.system;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.IRecentsAnimationController;
|
import android.view.IRecentsAnimationController;
|
||||||
@@ -26,6 +27,8 @@ import android.window.TaskSnapshot;
|
|||||||
import com.android.internal.os.IResultReceiver;
|
import com.android.internal.os.IResultReceiver;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
public class RecentsAnimationControllerCompat {
|
public class RecentsAnimationControllerCompat {
|
||||||
|
|
||||||
private static final String TAG = RecentsAnimationControllerCompat.class.getSimpleName();
|
private static final String TAG = RecentsAnimationControllerCompat.class.getSimpleName();
|
||||||
@@ -92,7 +95,24 @@ public class RecentsAnimationControllerCompat {
|
|||||||
*/
|
*/
|
||||||
public void finish(boolean toHome, boolean sendUserLeaveHint, IResultReceiver finishCb) {
|
public void finish(boolean toHome, boolean sendUserLeaveHint, IResultReceiver finishCb) {
|
||||||
try {
|
try {
|
||||||
mAnimationController.finish(toHome, sendUserLeaveHint, finishCb);
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||||
|
mAnimationController.finish(toHome, sendUserLeaveHint, finishCb);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Method finishMethod = mAnimationController.getClass().getMethod(
|
||||||
|
"finish", boolean.class, boolean.class);
|
||||||
|
finishMethod.invoke(mAnimationController, toHome, sendUserLeaveHint);
|
||||||
|
|
||||||
|
if (finishCb != null) {
|
||||||
|
finishCb.send(0, null);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Failed to finish recents animation via reflection", e);
|
||||||
|
if (finishCb != null) {
|
||||||
|
finishCb.send(0, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Failed to finish recents animation", e);
|
Log.e(TAG, "Failed to finish recents animation", e);
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.wm.shell.shared;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
@@ -150,7 +151,8 @@ public class DesktopModeStatus {
|
|||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public static boolean isDesktopModeSupported(@NonNull Context context) {
|
public static boolean isDesktopModeSupported(@NonNull Context context) {
|
||||||
return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported);
|
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
|
||||||
|
&& context.getResources().getBoolean(R.bool.config_isDesktopModeSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user