Loading cmds/bootanimation/BootAnimation.cpp +48 −1 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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); Loading @@ -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; } Loading @@ -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(), Loading cmds/bootanimation/BootAnimation.h +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading core/java/android/app/ActivityThread.java +11 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading services/core/java/com/android/server/display/DisplayManagerService.java +43 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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( Loading @@ -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() { Loading Loading @@ -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); Loading Loading @@ -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); } } Loading Loading @@ -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++) { Loading Loading @@ -991,6 +1016,7 @@ public final class DisplayManagerService extends SystemService { configureColorModeLocked(display, device); if (isDefault) { recordStableDisplayStatsIfNeededLocked(display); recordTopInsetLocked(display); } mLogicalDisplays.put(displayId, display); Loading Loading @@ -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 { Loading Loading @@ -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; } } Loading services/core/java/com/android/server/display/LogicalDisplay.java +14 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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 Loading
cmds/bootanimation/BootAnimation.cpp +48 −1 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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); Loading @@ -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; } Loading @@ -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(), Loading
cmds/bootanimation/BootAnimation.h +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
core/java/android/app/ActivityThread.java +11 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
services/core/java/com/android/server/display/DisplayManagerService.java +43 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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( Loading @@ -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() { Loading Loading @@ -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); Loading Loading @@ -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); } } Loading Loading @@ -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++) { Loading Loading @@ -991,6 +1016,7 @@ public final class DisplayManagerService extends SystemService { configureColorModeLocked(display, device); if (isDefault) { recordStableDisplayStatsIfNeededLocked(display); recordTopInsetLocked(display); } mLogicalDisplays.put(displayId, display); Loading Loading @@ -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 { Loading Loading @@ -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; } } Loading
services/core/java/com/android/server/display/LogicalDisplay.java +14 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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