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

Commit 6ba77858 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Synchronize screen turning on and unfold overlay" into sc-v2-dev

parents ed14802c c055dbb3
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -292,11 +292,18 @@ public class SurfaceControlViewHost {
     */
    @TestApi
    public void relayout(WindowManager.LayoutParams attrs) {
        relayout(attrs, SurfaceControl.Transaction::apply);
    }

    /**
     * Forces relayout and draw and allows to set a custom callback when it is finished
     * @hide
     */
    public void relayout(WindowManager.LayoutParams attrs,
            WindowlessWindowManager.ResizeCompleteCallback callback) {
        mViewRoot.setLayoutParams(attrs, false);
        mViewRoot.setReportNextDraw();
        mWm.setCompletionCallback(mViewRoot.mWindow.asBinder(), (SurfaceControl.Transaction t) -> {
            t.apply();
        });
        mWm.setCompletionCallback(mViewRoot.mWindow.asBinder(), callback);
    }

    /**
+114 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.wm.shell;

import android.util.SparseArray;
import android.view.SurfaceControl;
import android.window.DisplayAreaAppearedInfo;
import android.window.DisplayAreaInfo;
import android.window.DisplayAreaOrganizer;

import androidx.annotation.NonNull;

import java.io.PrintWriter;
import java.util.List;
import java.util.concurrent.Executor;

/** Display area organizer for the root display areas */
public class RootDisplayAreaOrganizer extends DisplayAreaOrganizer {

    private static final String TAG = RootDisplayAreaOrganizer.class.getSimpleName();

    /** {@link DisplayAreaInfo} list, which is mapped by display IDs. */
    private final SparseArray<DisplayAreaInfo> mDisplayAreasInfo = new SparseArray<>();
    /** Display area leashes, which is mapped by display IDs. */
    private final SparseArray<SurfaceControl> mLeashes = new SparseArray<>();

    public RootDisplayAreaOrganizer(Executor executor) {
        super(executor);
        List<DisplayAreaAppearedInfo> infos = registerOrganizer(FEATURE_ROOT);
        for (int i = infos.size() - 1; i >= 0; --i) {
            onDisplayAreaAppeared(infos.get(i).getDisplayAreaInfo(), infos.get(i).getLeash());
        }
    }

    public void attachToDisplayArea(int displayId, SurfaceControl.Builder b) {
        final SurfaceControl sc = mLeashes.get(displayId);
        if (sc != null) {
            b.setParent(sc);
        }
    }

    @Override
    public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo,
            @NonNull SurfaceControl leash) {
        if (displayAreaInfo.featureId != FEATURE_ROOT) {
            throw new IllegalArgumentException(
                    "Unknown feature: " + displayAreaInfo.featureId
                            + "displayAreaInfo:" + displayAreaInfo);
        }

        final int displayId = displayAreaInfo.displayId;
        if (mDisplayAreasInfo.get(displayId) != null) {
            throw new IllegalArgumentException(
                    "Duplicate DA for displayId: " + displayId
                            + " displayAreaInfo:" + displayAreaInfo
                            + " mDisplayAreasInfo.get():" + mDisplayAreasInfo.get(displayId));
        }

        mDisplayAreasInfo.put(displayId, displayAreaInfo);
        mLeashes.put(displayId, leash);
    }

    @Override
    public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) {
        final int displayId = displayAreaInfo.displayId;
        if (mDisplayAreasInfo.get(displayId) == null) {
            throw new IllegalArgumentException(
                    "onDisplayAreaVanished() Unknown DA displayId: " + displayId
                            + " displayAreaInfo:" + displayAreaInfo
                            + " mDisplayAreasInfo.get():" + mDisplayAreasInfo.get(displayId));
        }

        mDisplayAreasInfo.remove(displayId);
    }

    @Override
    public void onDisplayAreaInfoChanged(@NonNull DisplayAreaInfo displayAreaInfo) {
        final int displayId = displayAreaInfo.displayId;
        if (mDisplayAreasInfo.get(displayId) == null) {
            throw new IllegalArgumentException(
                    "onDisplayAreaInfoChanged() Unknown DA displayId: " + displayId
                            + " displayAreaInfo:" + displayAreaInfo
                            + " mDisplayAreasInfo.get():" + mDisplayAreasInfo.get(displayId));
        }

        mDisplayAreasInfo.put(displayId, displayAreaInfo);
    }

    public void dump(@NonNull PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
        final String childPrefix = innerPrefix + "  ";
        pw.println(prefix + this);
    }

    @Override
    public String toString() {
        return TAG + "#" + mDisplayAreasInfo.size();
    }

}
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.wm.shell.displayareahelper;

import android.view.SurfaceControl;

import java.util.function.Consumer;

/**
 * Interface that allows to perform various display area related actions
 */
public interface DisplayAreaHelper {

    /**
     * Updates SurfaceControl builder to reparent it to the root display area
     * @param displayId id of the display to which root display area it should be reparented to
     * @param builder surface control builder that should be updated
     * @param onUpdated callback that is invoked after updating the builder, called on
     *                  the shell main thread
     */
    default void attachToRootDisplayArea(int displayId, SurfaceControl.Builder builder,
            Consumer<SurfaceControl.Builder> onUpdated) {
    }

}
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.wm.shell.displayareahelper;

import android.view.SurfaceControl;

import com.android.wm.shell.RootDisplayAreaOrganizer;

import java.util.concurrent.Executor;
import java.util.function.Consumer;

public class DisplayAreaHelperController implements DisplayAreaHelper {

    private final Executor mExecutor;
    private final RootDisplayAreaOrganizer mRootDisplayAreaOrganizer;

    public DisplayAreaHelperController(Executor executor,
            RootDisplayAreaOrganizer rootDisplayAreaOrganizer) {
        mExecutor = executor;
        mRootDisplayAreaOrganizer = rootDisplayAreaOrganizer;
    }

    @Override
    public void attachToRootDisplayArea(int displayId, SurfaceControl.Builder builder,
            Consumer<SurfaceControl.Builder> onUpdated) {
        mExecutor.execute(() -> {
            mRootDisplayAreaOrganizer.attachToDisplayArea(displayId, builder);
            onUpdated.accept(builder);
        });
    }
}
+24 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.systemui.unfold.progress

import android.os.Handler
import android.util.Log
import android.util.MathUtils.saturate
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.FloatPropertyCompat
@@ -92,8 +93,15 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
                }
            }
            FOLD_UPDATE_FINISH_FULL_OPEN -> {
                // Do not cancel if we haven't started the transition yet.
                // This could happen when we fully unfolded the device before the screen
                // became available. In this case we start and immediately cancel the animation
                // in FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE event handler, so we don't need to
                // cancel it here.
                if (isTransitionRunning) {
                    cancelTransition(endValue = 1f, animate = true)
                }
            }
            FOLD_UPDATE_FINISH_CLOSED -> {
                cancelTransition(endValue = 0f, animate = false)
            }
@@ -101,6 +109,10 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
                startTransition(startValue = 1f)
            }
        }

        if (DEBUG) {
            Log.d(TAG, "onFoldUpdate = $update")
        }
    }

    private fun cancelTransition(endValue: Float, animate: Boolean) {
@@ -118,6 +130,10 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
            listeners.forEach {
                it.onTransitionFinished()
            }

            if (DEBUG) {
                Log.d(TAG, "onTransitionFinished")
            }
        }
    }

@@ -137,6 +153,10 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
            it.onTransitionStarted()
        }
        isTransitionRunning = true

        if (DEBUG) {
            Log.d(TAG, "onTransitionStarted")
        }
    }

    private fun startTransition(startValue: Float) {
@@ -189,6 +209,9 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
    }
}

private const val TAG = "PhysicsBasedUnfoldTransitionProgressProvider"
private const val DEBUG = true

private const val TRANSITION_TIMEOUT_MILLIS = 2000L
private const val SPRING_STIFFNESS = 200.0f
private const val MINIMAL_VISIBLE_CHANGE = 0.001f
Loading