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

Commit e387ce18 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by Android (Google) Code Review
Browse files

Merge "BootAnimation: Fix boot animation with hidden cutout" into pi-dev

parents ab39f605 9ee5dff8
Loading
Loading
Loading
Loading
+48 −1
Original line number Diff line number Diff line
@@ -302,6 +302,7 @@ status_t BootAnimation::readyToRun() {
    mHeight = h;
    mFlingerSurfaceControl = control;
    mFlingerSurface = s;
    mTargetInset = -1;

    // If the device has encryption turned on or is in process
    // of being encrypted we show the encrypted boot animation.
@@ -942,6 +943,7 @@ bool BootAnimation::playAnimation(const Animation& animation)
                if (mClockEnabled && mTimeIsAccurate && validClock(part)) {
                    drawClock(animation.clockFont, part.clockPosX, part.clockPosY);
                }
                handleViewport(frameDuration);

                eglSwapBuffers(mDisplay, mSurface);

@@ -966,7 +968,7 @@ bool BootAnimation::playAnimation(const Animation& animation)
            usleep(part.pause * ns2us(frameDuration));

            // For infinite parts, we've now played them at least once, so perhaps exit
            if(exitPending() && !part.count)
            if(exitPending() && !part.count && mCurrentInset >= mTargetInset)
                break;
        }

@@ -986,6 +988,51 @@ bool BootAnimation::playAnimation(const Animation& animation)
    return true;
}

void BootAnimation::handleViewport(nsecs_t timestep) {
    if (mShuttingDown || !mFlingerSurfaceControl || mTargetInset == 0) {
        return;
    }
    if (mTargetInset < 0) {
        // Poll the amount for the top display inset. This will return -1 until persistent properties
        // have been loaded.
        mTargetInset = android::base::GetIntProperty("persist.sys.displayinset.top",
                -1 /* default */, -1 /* min */, mHeight / 2 /* max */);
    }
    if (mTargetInset <= 0) {
        return;
    }

    if (mCurrentInset < mTargetInset) {
        // After the device boots, the inset will effectively be cropped away. We animate this here.
        float fraction = static_cast<float>(mCurrentInset) / mTargetInset;
        int interpolatedInset = (cosf((fraction + 1) * M_PI) / 2.0f + 0.5f) * mTargetInset;

        SurfaceComposerClient::Transaction()
                .setCrop(mFlingerSurfaceControl, Rect(0, interpolatedInset, mWidth, mHeight))
                .apply();
    } else {
        // At the end of the animation, we switch to the viewport that DisplayManager will apply
        // later. This changes the coordinate system, and means we must move the surface up by
        // the inset amount.
        sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
                ISurfaceComposer::eDisplayIdMain));

        Rect layerStackRect(0, 0, mWidth, mHeight - mTargetInset);
        Rect displayRect(0, mTargetInset, mWidth, mHeight);

        SurfaceComposerClient::Transaction t;
        t.setPosition(mFlingerSurfaceControl, 0, -mTargetInset)
                .setCrop(mFlingerSurfaceControl, Rect(0, mTargetInset, mWidth, mHeight));
        t.setDisplayProjection(dtoken, 0 /* orientation */, layerStackRect, displayRect);
        t.apply();

        mTargetInset = mCurrentInset = 0;
    }

    int delta = timestep * mTargetInset / ms2ns(200);
    mCurrentInset += delta;
}

void BootAnimation::releaseAnimation(Animation* animation) const
{
    for (Vector<Animation::Part>::iterator it = animation->parts.begin(),
+4 −0
Original line number Diff line number Diff line
@@ -157,11 +157,15 @@ private:

    void checkExit();

    void handleViewport(nsecs_t timestep);

    sp<SurfaceComposerClient>       mSession;
    AssetManager mAssets;
    Texture     mAndroid[2];
    int         mWidth;
    int         mHeight;
    int         mCurrentInset;
    int         mTargetInset;
    bool        mUseNpotTextures = false;
    EGLDisplay  mDisplay;
    EGLDisplay  mContext;
+11 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ import com.android.internal.os.RuntimeInit;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.org.conscrypt.OpenSSLSocketImpl;
import com.android.org.conscrypt.TrustedCertificateStore;
@@ -5144,6 +5145,16 @@ public final class ActivityThread extends ClientTransactionHandler {
        }
    }

    /**
     * Updates the application info.
     *
     * This only works in the system process. Must be called on the main thread.
     */
    public void handleSystemApplicationInfoChanged(@NonNull ApplicationInfo ai) {
        Preconditions.checkState(mSystemThread, "Must only be called in the system process");
        handleApplicationInfoChanged(ai);
    }

    void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) {
        // Updates triggered by package installation go through a package update
        // receiver. Here we try to capture ApplicationInfo changes that are
+43 −2
Original line number Diff line number Diff line
@@ -151,6 +151,8 @@ public final class DisplayManagerService extends SystemService {
    // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
    private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";

    private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top";

    private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;

    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
@@ -243,6 +245,15 @@ public final class DisplayManagerService extends SystemService {
    // device).
    private Point mStableDisplaySize = new Point();

    // Whether the system has finished booting or not.
    private boolean mSystemReady;

    // The top inset of the default display.
    // This gets persisted so that the boot animation knows how to transition from the display's
    // full size to the size configured by the user. Right now we only persist and animate the top
    // inset, but theoretically we could do it for all of them.
    private int mDefaultDisplayTopInset;

    // Viewports of the default display and the display that should receive touch
    // input from an external source.  Used by the input system.
    private final DisplayViewport mDefaultViewport = new DisplayViewport();
@@ -301,6 +312,7 @@ public final class DisplayManagerService extends SystemService {
        Resources resources = mContext.getResources();
        mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
        mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1);
        float[] lux = getFloatArray(resources.obtainTypedArray(
                com.android.internal.R.array.config_minimumBrightnessCurveLux));
        float[] nits = getFloatArray(resources.obtainTypedArray(
@@ -311,6 +323,8 @@ public final class DisplayManagerService extends SystemService {
        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
        mCurrentUserId = UserHandle.USER_SYSTEM;

        mSystemReady = false;
    }

    public void setupSchedulerPolicies() {
@@ -400,6 +414,10 @@ public final class DisplayManagerService extends SystemService {
        synchronized (mSyncRoot) {
            mSafeMode = safeMode;
            mOnlyCore = onlyCore;
            mSystemReady = true;
            // Just in case the top inset changed before the system was ready. At this point, any
            // relevant configuration should be in place.
            recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY));
        }

        mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
@@ -457,7 +475,7 @@ public final class DisplayManagerService extends SystemService {
            LogicalDisplay display = mLogicalDisplays.get(displayId);
            if (display != null) {
                if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
                    sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
                    handleLogicalDisplayChanged(displayId, display);
                    scheduleTraversalLocked(false);
                }
            }
@@ -938,6 +956,13 @@ public final class DisplayManagerService extends SystemService {
        scheduleTraversalLocked(false);
    }

    private void handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display) {
        if (displayId == Display.DEFAULT_DISPLAY) {
            recordTopInsetLocked(display);
        }
        sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
    }

    private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
        final int count = mDisplayDevices.size();
        for (int i = 0; i < count; i++) {
@@ -991,6 +1016,7 @@ public final class DisplayManagerService extends SystemService {
        configureColorModeLocked(display, device);
        if (isDefault) {
            recordStableDisplayStatsIfNeededLocked(display);
            recordTopInsetLocked(display);
        }

        mLogicalDisplays.put(displayId, display);
@@ -1039,6 +1065,21 @@ public final class DisplayManagerService extends SystemService {
        }
    }

    private void recordTopInsetLocked(@Nullable LogicalDisplay d) {
        // We must only persist the inset after boot has completed, otherwise we will end up
        // overwriting the persisted value before the masking flag has been loaded from the
        // resource overlay.
        if (!mSystemReady || d == null) {
            return;
        }
        int topInset = d.getInsets().top;
        if (topInset == mDefaultDisplayTopInset) {
            return;
        }
        mDefaultDisplayTopInset = topInset;
        SystemProperties.set(PROP_DEFAULT_DISPLAY_TOP_INSET, Integer.toString(topInset));
    }

    private void setStableDisplaySizeLocked(int width, int height) {
        mStableDisplaySize = new Point(width, height);
        try {
@@ -1118,7 +1159,7 @@ public final class DisplayManagerService extends SystemService {
                sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
                changed = true;
            } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
                sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
                handleLogicalDisplayChanged(displayId, display);
                changed = true;
            }
        }
+14 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.display;

import android.graphics.Rect;
import android.hardware.display.DisplayManagerInternal;
import android.os.SystemProperties;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
@@ -57,6 +58,8 @@ import java.util.Objects;
 * </p>
 */
final class LogicalDisplay {
    private static final String PROP_MASKING_INSET_TOP = "persist.sys.displayinset.top";

    private final DisplayInfo mBaseDisplayInfo = new DisplayInfo();

    // The layer stack we use when the display has been blanked to prevent any
@@ -296,6 +299,17 @@ final class LogicalDisplay {
        }
    }

    /**
     * Return the insets currently applied to the display.
     *
     * Note that the base DisplayInfo already takes these insets into account, so if you want to
     * find out the <b>true</b> size of the display, you need to add them back to the logical
     * dimensions.
     */
    public Rect getInsets() {
        return getMaskingInsets(mPrimaryDisplayDeviceInfo);
    }

    /**
     * Returns insets in ROTATION_0 for areas that are masked.
     */
Loading