diff --git a/compatLib/src/main/java/android/view/InsetsSource.java b/compatLib/src/main/java/android/view/InsetsSource.java new file mode 100644 index 0000000000..71f0516408 --- /dev/null +++ b/compatLib/src/main/java/android/view/InsetsSource.java @@ -0,0 +1,692 @@ +/* + * 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 android.view; + +import static android.view.InsetsSourceProto.FRAME; +import static android.view.InsetsSourceProto.TYPE; +import static android.view.InsetsSourceProto.TYPE_NUMBER; +import static android.view.InsetsSourceProto.VISIBLE; +import static android.view.InsetsSourceProto.VISIBLE_FRAME; +import static android.view.WindowInsets.Type.captionBar; +import static android.view.WindowInsets.Type.ime; + +import android.annotation.IntDef; +import android.annotation.IntRange; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.graphics.Insets; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.proto.ProtoOutputStream; +import android.view.WindowInsets.Type.InsetsType; +import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Objects; +import java.util.StringJoiner; + +/** + * Represents the state of a single entity generating insets for clients. + * + * @hide + */ +public class InsetsSource implements Parcelable { + + @Retention(RetentionPolicy.SOURCE) + @IntDef( + prefix = "SIDE_", + value = {SIDE_NONE, SIDE_LEFT, SIDE_TOP, SIDE_RIGHT, SIDE_BOTTOM, SIDE_UNKNOWN}) + public @interface InternalInsetsSide {} + + static final int SIDE_NONE = 0; + static final int SIDE_LEFT = 1; + static final int SIDE_TOP = 2; + static final int SIDE_RIGHT = 3; + static final int SIDE_BOTTOM = 4; + static final int SIDE_UNKNOWN = 5; + + /** The insets source ID of IME */ + public static final int ID_IME = createId(null, 0, ime()); + + /** The insets source ID of the IME caption bar ("fake" IME navigation bar). */ + public static final int ID_IME_CAPTION_BAR = + InsetsSource.createId(null /* owner */, 1 /* index */, captionBar()); + + /** + * Controls whether this source suppresses the scrim. If the scrim is ignored, the system won't + * draw a semi-transparent scrim behind the system bar area even when the bar contrast is + * enforced. + * + * @see android.R.styleable#Window_enforceStatusBarContrast + * @see android.R.styleable#Window_enforceNavigationBarContrast + */ + public static final int FLAG_SUPPRESS_SCRIM = 1; + + /** + * Controls whether the insets frame will be used to move {@link RoundedCorner} inward with the + * insets frame size when calculating the rounded corner insets to other windows. + * + *
For example, task bar will draw fake rounded corners above itself, so we need to move the
+ * rounded corner up by the task bar insets size to make other windows see a rounded corner
+ * above the task bar.
+ */
+ public static final int FLAG_INSETS_ROUNDED_CORNER = 1 << 1;
+
+ /** Controls whether the insets provided by this source should be forcibly consumed. */
+ public static final int FLAG_FORCE_CONSUMING = 1 << 2;
+
+ /** Controls whether the insets source will play an animation when resizing. */
+ public static final int FLAG_ANIMATE_RESIZING = 1 << 3;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ flag = true,
+ prefix = "FLAG_",
+ value = {
+ FLAG_SUPPRESS_SCRIM,
+ FLAG_INSETS_ROUNDED_CORNER,
+ FLAG_FORCE_CONSUMING,
+ FLAG_ANIMATE_RESIZING,
+ })
+ public @interface Flags {}
+
+ /**
+ * Used when there are no bounding rects to describe an inset, which is only possible when the
+ * insets itself is {@link Insets#NONE}.
+ */
+ private static final Rect[] NO_BOUNDING_RECTS = new Rect[0];
+
+ private @Flags int mFlags;
+
+ /** An unique integer to identify this source across processes. */
+ private final int mId;
+
+ private final @InsetsType int mType;
+
+ /** Frame of the source in screen coordinate space */
+ private final Rect mFrame;
+
+ private @Nullable Rect mVisibleFrame;
+ private @Nullable Rect[] mBoundingRects;
+
+ private boolean mVisible;
+
+ /**
+ * Used to decide which side of the relative frame should receive insets when the frame fully
+ * covers the relative frame.
+ */
+ private @InternalInsetsSide int mSideHint = SIDE_NONE;
+
+ private final Rect mTmpFrame = new Rect();
+ private final Rect mTmpBoundingRect = new Rect();
+
+ public InsetsSource(int id, @InsetsType int type) {
+ mId = id;
+ mType = type;
+ mFrame = new Rect();
+ mVisible = (WindowInsets.Type.defaultVisible() & type) != 0;
+ }
+
+ public InsetsSource(InsetsSource other) {
+ mId = other.mId;
+ mType = other.mType;
+ mFrame = new Rect(other.mFrame);
+ mVisible = other.mVisible;
+ mVisibleFrame = other.mVisibleFrame != null ? new Rect(other.mVisibleFrame) : null;
+ mFlags = other.mFlags;
+ mSideHint = other.mSideHint;
+ mBoundingRects = other.mBoundingRects != null ? other.mBoundingRects.clone() : null;
+ }
+
+ public void set(InsetsSource other) {
+ mFrame.set(other.mFrame);
+ mVisible = other.mVisible;
+ mVisibleFrame = other.mVisibleFrame != null ? new Rect(other.mVisibleFrame) : null;
+ mFlags = other.mFlags;
+ mSideHint = other.mSideHint;
+ mBoundingRects = other.mBoundingRects != null ? other.mBoundingRects.clone() : null;
+ }
+
+ public InsetsSource setFrame(int left, int top, int right, int bottom) {
+ mFrame.set(left, top, right, bottom);
+ return this;
+ }
+
+ public InsetsSource setFrame(Rect frame) {
+ mFrame.set(frame);
+ return this;
+ }
+
+ public InsetsSource setVisibleFrame(@Nullable Rect visibleFrame) {
+ mVisibleFrame = visibleFrame != null ? new Rect(visibleFrame) : null;
+ return this;
+ }
+
+ public InsetsSource setVisible(boolean visible) {
+ mVisible = visible;
+ return this;
+ }
+
+ public InsetsSource setFlags(@Flags int flags) {
+ mFlags = flags;
+ return this;
+ }
+
+ public InsetsSource setFlags(@Flags int flags, @Flags int mask) {
+ mFlags = (mFlags & ~mask) | (flags & mask);
+ return this;
+ }
+
+ /**
+ * Updates the side hint which is used to decide which side of the relative frame should receive
+ * insets when the frame fully covers the relative frame.
+ *
+ * @param bounds A rectangle which contains the frame. It will be used to calculate the hint.
+ */
+ public InsetsSource updateSideHint(Rect bounds) {
+ mSideHint = getInsetSide(calculateInsets(bounds, mFrame, true /* ignoreVisibility */));
+ return this;
+ }
+
+ /**
+ * Set the bounding rectangles of this source. They are expected to be relative to the source
+ * frame.
+ */
+ public InsetsSource setBoundingRects(@Nullable Rect[] rects) {
+ mBoundingRects = rects != null ? rects.clone() : null;
+ return this;
+ }
+
+ public int getId() {
+ return mId;
+ }
+
+ public @InsetsType int getType() {
+ return mType;
+ }
+
+ public Rect getFrame() {
+ return mFrame;
+ }
+
+ public @Nullable Rect getVisibleFrame() {
+ return mVisibleFrame;
+ }
+
+ public boolean isVisible() {
+ return mVisible;
+ }
+
+ public @Flags int getFlags() {
+ return mFlags;
+ }
+
+ public boolean hasFlags(int flags) {
+ return (mFlags & flags) == flags;
+ }
+
+ /** Returns the bounding rectangles of this source. */
+ public @Nullable Rect[] getBoundingRects() {
+ return mBoundingRects;
+ }
+
+ /**
+ * Calculates the insets this source will cause to a client window.
+ *
+ * @param relativeFrame The frame to calculate the insets relative to.
+ * @param ignoreVisibility If true, always reports back insets even if source isn't visible.
+ * @return The resulting insets. The contract is that only one side will be occupied by a
+ * source.
+ */
+ public Insets calculateInsets(Rect relativeFrame, boolean ignoreVisibility) {
+ return calculateInsets(relativeFrame, mFrame, ignoreVisibility);
+ }
+
+ /** Like {@link #calculateInsets(Rect, boolean)}, but will return visible insets. */
+ public Insets calculateVisibleInsets(Rect relativeFrame) {
+ return calculateInsets(
+ relativeFrame,
+ mVisibleFrame != null ? mVisibleFrame : mFrame,
+ false /* ignoreVisibility */);
+ }
+
+ private Insets calculateInsets(Rect relativeFrame, Rect frame, boolean ignoreVisibility) {
+ if (!ignoreVisibility && !mVisible) {
+ return Insets.NONE;
+ }
+ // During drag-move and drag-resizing, the caption insets position may not get updated
+ // before the app frame get updated. To layout the app content correctly during drag events,
+ // we always return the insets with the corresponding height covering the top.
+ // However, with the "fake" IME navigation bar treated as a caption bar, we return the
+ // insets with the corresponding height the bottom.
+ if (getType() == WindowInsets.Type.captionBar()) {
+ return getId() == ID_IME_CAPTION_BAR
+ ? Insets.of(0, 0, 0, frame.height())
+ : Insets.of(0, frame.height(), 0, 0);
+ }
+ // Checks for whether there is shared edge with insets for 0-width/height window.
+ final boolean hasIntersection =
+ relativeFrame.isEmpty()
+ ? getIntersection(frame, relativeFrame, mTmpFrame)
+ : mTmpFrame.setIntersect(frame, relativeFrame);
+ if (!hasIntersection) {
+ return Insets.NONE;
+ }
+
+ // TODO: Currently, non-floating IME always intersects at bottom due to issues with cutout.
+ // However, we should let the policy decide from the server.
+ if (getType() == WindowInsets.Type.ime()) {
+ return Insets.of(0, 0, 0, mTmpFrame.height());
+ }
+
+ if (mTmpFrame.equals(relativeFrame)) {
+ // Covering all sides
+ switch (mSideHint) {
+ default:
+ case SIDE_LEFT:
+ return Insets.of(mTmpFrame.width(), 0, 0, 0);
+ case SIDE_TOP:
+ return Insets.of(0, mTmpFrame.height(), 0, 0);
+ case SIDE_RIGHT:
+ return Insets.of(0, 0, mTmpFrame.width(), 0);
+ case SIDE_BOTTOM:
+ return Insets.of(0, 0, 0, mTmpFrame.height());
+ }
+ } else if (mTmpFrame.width() == relativeFrame.width()) {
+ // Intersecting at top/bottom
+ if (mTmpFrame.top == relativeFrame.top) {
+ return Insets.of(0, mTmpFrame.height(), 0, 0);
+ } else if (mTmpFrame.bottom == relativeFrame.bottom) {
+ return Insets.of(0, 0, 0, mTmpFrame.height());
+ }
+ // TODO: remove when insets are shell-customizable.
+ // This is a hack that says "if this is a top-inset (eg statusbar), always apply it
+ // to the top". It is used when adjusting primary split for IME.
+ if (mTmpFrame.top == 0) {
+ return Insets.of(0, mTmpFrame.height(), 0, 0);
+ }
+ } else if (mTmpFrame.height() == relativeFrame.height()) {
+ // Intersecting at left/right
+ if (mTmpFrame.left == relativeFrame.left) {
+ return Insets.of(mTmpFrame.width(), 0, 0, 0);
+ } else if (mTmpFrame.right == relativeFrame.right) {
+ return Insets.of(0, 0, mTmpFrame.width(), 0);
+ }
+ }
+ return Insets.NONE;
+ }
+
+ /** Calculates the bounding rects the source will cause to a client window. */
+ public @NonNull Rect[] calculateBoundingRects(Rect relativeFrame, boolean ignoreVisibility) {
+ if (!ignoreVisibility && !mVisible) {
+ return NO_BOUNDING_RECTS;
+ }
+
+ final Rect frame = getFrame();
+ if (mBoundingRects == null) {
+ // No bounding rects set, make a single bounding rect that covers the intersection of
+ // the |frame| and the |relativeFrame|. Also make it relative to the window origin.
+ return mTmpBoundingRect.setIntersect(frame, relativeFrame)
+ ? new Rect[] {
+ new Rect(
+ mTmpBoundingRect.left - relativeFrame.left,
+ mTmpBoundingRect.top - relativeFrame.top,
+ mTmpBoundingRect.right - relativeFrame.left,
+ mTmpBoundingRect.bottom - relativeFrame.top)
+ }
+ : NO_BOUNDING_RECTS;
+ }
+
+ // Special treatment for captionBar inset type. During drag-resizing, the |frame| and
+ // |boundingRects| may not get updated as quickly as |relativeFrame|, so just assume the
+ // |frame| will always be either at the top or bottom of |relativeFrame|. This means some
+ // calculations to make |boundingRects| relative to |relativeFrame| can be skipped or
+ // simplified.
+ // TODO(b/254128050): remove special treatment.
+ if (getType() == WindowInsets.Type.captionBar()) {
+ final ArrayList This allows the client to customize various back behaviors by overriding the corresponding
+ * callback methods.
+ *
+ * Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, which is
+ * held at window level and accessible through {@link Activity#getOnBackInvokedDispatcher()}, {@link
+ * Dialog#getOnBackInvokedDispatcher()}, {@link Window#getOnBackInvokedDispatcher()} and {@link
+ * View#findOnBackInvokedDispatcher()}.
+ *
+ * When back is triggered, callbacks on the in-focus window are invoked in reverse order in which
+ * they are added within the same priority. Between different priorities, callbacks with higher
+ * priority are invoked first.
+ *
+ *
+ *
+ * @see OnBackInvokedCallback
+ */
+public interface OnBackAnimationCallback extends OnBackInvokedCallback {
+ /**
+ * Called when a back gesture has been started, or back button has been pressed down.
+ *
+ * @param backEvent The {@link BackEvent} containing information about the touch or button
+ * press.
+ * @see BackEvent
+ */
+ default void onBackStarted(@NonNull BackEvent backEvent) {}
+
+ /**
+ * Called when a back gesture progresses.
+ *
+ * @param backEvent An {@link BackEvent} object describing the progress event.
+ * @see BackEvent
+ */
+ default void onBackProgressed(@NonNull BackEvent backEvent) {}
+
+ /** Called when a back gesture or back button press has been cancelled. */
+ default void onBackCancelled() {}
+}
diff --git a/compatLib/src/main/java/android/window/OnBackInvokedCallback.java b/compatLib/src/main/java/android/window/OnBackInvokedCallback.java
new file mode 100644
index 0000000000..ab6b08971e
--- /dev/null
+++ b/compatLib/src/main/java/android/window/OnBackInvokedCallback.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 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 android.window;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.view.View;
+import android.view.Window;
+
+/**
+ * Callback allowing applications to handle back events in place of the system.
+ *
+ * Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, which is
+ * held at window level and accessible through {@link Activity#getOnBackInvokedDispatcher()}, {@link
+ * Dialog#getOnBackInvokedDispatcher()}, {@link Window#getOnBackInvokedDispatcher()} and {@link
+ * View#findOnBackInvokedDispatcher()}.
+ *
+ * When back is triggered, callbacks on the in-focus window are invoked in reverse order in which
+ * they are added within the same priority. Between different priorities, callbacks with higher
+ * priority are invoked first.
+ *
+ * This replaces {@link Activity#onBackPressed()}, {@link Dialog#onBackPressed()} and {@link
+ * android.view.KeyEvent#KEYCODE_BACK}
+ *
+ * If you want to customize back animation behaviors, in addition to handling back invocations,
+ * register its subclass instances {@link OnBackAnimationCallback} instead.
+ *
+ *
+ *
+ * @see OnBackInvokedDispatcher#registerOnBackInvokedCallback(int, OnBackInvokedCallback)
+ * registerOnBackInvokedCallback(priority, OnBackInvokedCallback) to specify callback priority.
+ */
+@SuppressWarnings("deprecation")
+public interface OnBackInvokedCallback {
+ /**
+ * Called when a back gesture has been completed and committed, or back button pressed has been
+ * released and committed.
+ */
+ void onBackInvoked();
+}
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index cf21b3d619..2da9c3e89f 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -32,14 +32,19 @@ import android.view.ViewTreeObserver;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.quickstep.util.BaseDepthController;
+import com.patrykmichalik.opto.core.PreferenceExtensionsKt;
import java.io.PrintWriter;
import java.util.function.Consumer;
+import app.lawnchair.compat.LawnchairQuickstepCompat;
+import app.lawnchair.preferences2.PreferenceManager2;
+
/**
* Controls blur and wallpaper zoom, for the Launcher surface only.
*/
@@ -57,14 +62,24 @@ public class DepthController extends BaseDepthController implements StateHandler
private View.OnAttachStateChangeListener mOnAttachListener;
+ private final boolean mEnableDepth;
+
public DepthController(Launcher l) {
super(l);
+ var pref = PreferenceManager2.getInstance(l).getWallpaperDepthEffect();
+ mEnableDepth = PreferenceExtensionsKt.firstBlocking(pref);
}
private void onLauncherDraw() {
View view = mLauncher.getDragLayer();
ViewRootImpl viewRootImpl = view.getViewRootImpl();
- setSurface(viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
+ try {
+ if (Utilities.ATLEAST_Q) {
+ setSurface(viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
+ }
+ } catch (Throwable t) {
+ // Ignore any exceptions
+ }
view.post(() -> view.getViewTreeObserver().removeOnDrawListener(mOnDrawListener));
}
@@ -74,8 +89,12 @@ public class DepthController extends BaseDepthController implements StateHandler
mOnAttachListener = new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View view) {
- CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
- mCrossWindowBlurListener);
+ try {
+ CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
+ mCrossWindowBlurListener);
+ } catch (Throwable t) {
+ // Ignore
+ }
mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener);
// To handle the case where window token is invalid during last setDepth call.
@@ -108,7 +127,11 @@ public class DepthController extends BaseDepthController implements StateHandler
private void removeSecondaryListeners() {
if (mCrossWindowBlurListener != null) {
- CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener);
+ try {
+ CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener);
+ } catch (Throwable t) {
+ // Ignore
+ }
}
if (mOpaquenessListener != null) {
mLauncher.getScrimView().removeOpaquenessListener(mOpaquenessListener);
@@ -154,8 +177,14 @@ public class DepthController extends BaseDepthController implements StateHandler
@Override
protected void applyDepthAndBlur() {
- ensureDependencies();
- super.applyDepthAndBlur();
+ try {
+ if (LawnchairQuickstepCompat.ATLEAST_R && mEnableDepth) {
+ ensureDependencies();
+ super.applyDepthAndBlur();
+ }
+ } catch (Throwable t) {
+ // Ignore
+ }
}
@Override
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 53a311a303..3d8426fb34 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -185,30 +185,34 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable {
* different process). It is bare-bones, so it's expected that the component and options will
* be provided via fill-in intent.
*/
- private final PendingIntent mRecentsPendingIntent;
+ private PendingIntent mRecentsPendingIntent;
@Nullable
- private final ProxyUnfoldTransitionProvider mUnfoldTransitionProvider;
+ private ProxyUnfoldTransitionProvider mUnfoldTransitionProvider;
private SystemUiProxy(Context context) {
mContext = context;
mAsyncHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::handleMessageAsync);
final Intent baseIntent = new Intent().setPackage(mContext.getPackageName());
- final ActivityOptions options = ActivityOptions.makeBasic();
- if (Utilities.ATLEAST_U) {
- options.setPendingIntentCreatorBackgroundActivityStartMode(
- ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ if (Utilities.ATLEAST_Q) {
+
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ if (Utilities.ATLEAST_U) {
+ options.setPendingIntentCreatorBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ }
+
+ mRecentsPendingIntent = LawnchairQuickstepCompat.ATLEAST_V ? PendingIntent.getActivity(mContext, 0, baseIntent,
+ PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT
+ | Intent.FILL_IN_COMPONENT, options.toBundle()) : PendingIntent.getActivity(mContext, 0, baseIntent,
+ PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT
+ | Intent.FILL_IN_COMPONENT) ;
+
+ mUnfoldTransitionProvider =
+ (enableUnfoldStateAnimation() && new ResourceUnfoldTransitionConfig().isEnabled())
+ ? new ProxyUnfoldTransitionProvider() : null;
}
- mRecentsPendingIntent = LawnchairQuickstepCompat.ATLEAST_V ? PendingIntent.getActivity(mContext, 0, baseIntent,
- PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT
- | Intent.FILL_IN_COMPONENT) : PendingIntent.getActivity(mContext, 0, baseIntent,
- PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT
- | Intent.FILL_IN_COMPONENT, options.toBundle()) ;
-
- mUnfoldTransitionProvider =
- (enableUnfoldStateAnimation() && new ResourceUnfoldTransitionConfig().isEnabled())
- ? new ProxyUnfoldTransitionProvider() : null;
}
@Override
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 53932849fc..acd2bfa416 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -228,7 +228,7 @@ public class InstallSessionHelper implements SafeCloseable {
&& !promiseIconAddedForId(sessionInfo.getSessionId())) {
// In case of unarchival, we do not want to add a workspace promise icon if one is
// not already present. For general app installations however, we do support it.
- if (!Flags.enableSupportForArchiving() || !sessionInfo.isUnarchival()) {
+ if (ATLEAST_V && (!Flags.enableSupportForArchiving() || !sessionInfo.isUnarchival())) {
FileLog.d(LOG, "Adding package name to install queue: "
+ sessionInfo.getAppPackageName());
diff --git a/src/com/android/launcher3/pm/InstallSessionTracker.java b/src/com/android/launcher3/pm/InstallSessionTracker.java
index 24d58f3e98..1e00ca8b05 100644
--- a/src/com/android/launcher3/pm/InstallSessionTracker.java
+++ b/src/com/android/launcher3/pm/InstallSessionTracker.java
@@ -81,7 +81,7 @@ public class InstallSessionTracker extends PackageInstaller.SessionCallback {
helper.tryQueuePromiseAppIcon(sessionInfo);
- if (Flags.enableSupportForArchiving() && sessionInfo != null
+ if (Utilities.ATLEAST_V && Flags.enableSupportForArchiving() && sessionInfo != null
&& sessionInfo.isUnarchival()) {
// For archived apps, icon could already be present on the workspace. To make sure
// the icon state is updated, we send a change event.
diff --git a/src/com/android/launcher3/util/BackPressHandler.java b/src/com/android/launcher3/util/BackPressHandler.java
index b63f648b2d..fbd4225d64 100644
--- a/src/com/android/launcher3/util/BackPressHandler.java
+++ b/src/com/android/launcher3/util/BackPressHandler.java
@@ -15,16 +15,12 @@
*/
package com.android.launcher3.util;
-import android.os.Build;
import android.window.OnBackAnimationCallback;
-import androidx.annotation.RequiresApi;
-
/**
* Extension of {@link OnBackAnimationCallback} that allows a check to determine
* if this callback supports handling back or not
*/
-@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public interface BackPressHandler extends OnBackAnimationCallback {
boolean canHandleBack();
}