Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1a4dfe59 authored by Filip Gruszczynski's avatar Filip Gruszczynski
Browse files

Synchronize recents to freeform transition.

Recents to freeform animation must hang on the first frame and inform
Recents to hide its views. This mirrors the transition from freeform
to Recents, where the animation needs to hang on the last frame.

We need a special window flag for recents to force a redraw after the
animation launches. At this point Recents will become not visible
from the perspective of the activity manager, which would prevent
further drawing. We make recents ignore that and instead depend on
window visibility which will change after recents exit animation
finishes.

Bug: 24913782
Change-Id: Ief743b7e6fcebb3d8789d4745fb122ac607c1cf0
parent ff814adf
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.view;

import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;

import android.Manifest;
import android.animation.LayoutTransition;
import android.app.ActivityManagerNative;
@@ -37,7 +39,6 @@ import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.input.InputManager;
import android.media.AudioManager;
import android.os.Binder;
import android.os.Build;
@@ -74,7 +75,6 @@ import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.view.WindowCallbacks;
import android.widget.Scroller;

import com.android.internal.R;
@@ -176,6 +176,11 @@ public final class ViewRootImpl implements ViewParent,

    int mViewVisibility;
    boolean mAppVisible = true;
    // For recents to freeform transition we need to keep drawing after the app receives information
    // that it became invisible. This will ignore that information and depend on the decor view
    // visibility to control drawing. The decor view visibility will get adjusted when the app get
    // stopped and that's when the app will stop drawing further frames.
    private boolean mForceDecorViewVisibility = false;
    int mOrigWindowType = -1;

    /** Whether the window had focus during the most recent traversal. */
@@ -561,6 +566,8 @@ public final class ViewRootImpl implements ViewParent,
                        & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
                    mInputChannel = new InputChannel();
                }
                mForceDecorViewVisibility = (mWindowAttributes.privateFlags
                        & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
                try {
                    mOrigWindowType = mWindowAttributes.type;
                    mAttachInfo.mRecomputeGlobalAttributes = true;
@@ -1063,7 +1070,7 @@ public final class ViewRootImpl implements ViewParent,
    }

    int getHostVisibility() {
        return mAppVisible ? mView.getVisibility() : View.GONE;
        return (mAppVisible || mForceDecorViewVisibility) ? mView.getVisibility() : View.GONE;
    }

    /**
@@ -1568,7 +1575,7 @@ public final class ViewRootImpl implements ViewParent,
        boolean insetsPending = false;
        int relayoutResult = 0;

        boolean isViewVisible = viewVisibility == View.VISIBLE;
        final boolean isViewVisible = viewVisibility == View.VISIBLE;
        if (mFirst || windowShouldResize || insetsChanged ||
                viewVisibilityChanged || params != null) {

@@ -2471,8 +2478,7 @@ public final class ViewRootImpl implements ViewParent,
                if (callbacks != null) {
                    for (SurfaceHolder.Callback c : callbacks) {
                        if (c instanceof SurfaceHolder.Callback2) {
                            ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
                                    mSurfaceHolder);
                            ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(mSurfaceHolder);
                        }
                    }
                }
+10 −3
Original line number Diff line number Diff line
@@ -118,8 +118,7 @@ public interface WindowManager extends ViewManager {
     */
    public void removeViewImmediate(View view);

    public static class LayoutParams extends ViewGroup.LayoutParams
            implements Parcelable {
    public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
        /**
         * X position for this window.  With the default gravity it is ignored.
         * When using {@link Gravity#LEFT} or {@link Gravity#START} or {@link Gravity#RIGHT} or
@@ -1156,6 +1155,14 @@ public interface WindowManager extends ViewManager {
         */
        public static final int PRIVATE_FLAG_PRESERVE_GEOMETRY = 0x00002000;

        /**
         * Flag that will make window ignore app visibility and instead depend purely on the decor
         * view visibility for determining window visibility. This is used by recents to keep
         * drawing after it launches an app.
         * @hide
         */
        public static final int PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY = 0x00004000;


        /**
         * Control flags that are private to the platform.
+28 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.systemui.recents;

import com.android.systemui.recents.events.EventBus;

/**
 * Event sent when the exit animation is started.
 *
 * This is sent so parts of UI can synchronize on this event and adjust their appearance. An example
 * of that is hiding the tasks when the launched application window becomes visible.
 */
public class ExitRecentsWindowFirstAnimationFrameEvent extends EventBus.Event {
}
+8 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.recents.events.EventBus;
@@ -352,6 +353,8 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
        mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub);
        mScrimViews = new SystemBarScrimViews(this);
        getWindow().getAttributes().privateFlags |=
                WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;

        // Create the home intent runnable
        Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
@@ -648,6 +651,11 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
        mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
    }

    public final void onBusEvent(ExitRecentsWindowFirstAnimationFrameEvent event) {
        mRecentsView.setStackViewVisibility(View.INVISIBLE);
        mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
    }

    public final void onBusEvent(CancelEnterRecentsWindowAnimationEvent event) {
        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
        int launchToTaskId = launchState.launchedToTaskId;
+2 −2
Original line number Diff line number Diff line
@@ -68,8 +68,8 @@ import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 * An implementation of the Recents component for the current user.  For secondary users, this can
 * be called remotely from the system user.
 */
public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub
        implements ActivityOptions.OnAnimationFinishedListener {
public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub implements
        ActivityOptions.OnAnimationFinishedListener {

    private final static String TAG = "RecentsImpl";
    private final static boolean DEBUG = false;
Loading