summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-08-23 01:27:34 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-08-23 01:27:34 +0000
commit97a3d6b758b8eb3564115240e8a59e77a36feb31 (patch)
treec4da2c9128fcc3cfb578409507b6570d8624b38b
parent1d1b6dfb36800732cfefc8429ff621c0eef527e3 (diff)
parent7a88f4a955fa5ee121a162957eb299e649f8cc5c (diff)
downloadbase-pie-dr1-release.tar.gz
Merge cherrypicks of [4847409, 4847410, 4851733, 4851734, 4851815, 4851835, 4851836, 4851837, 4851855] into pi-dr1-releaseandroid-9.0.0_r12android-9.0.0_r11pie-dr1-release
Change-Id: Ib4222aa8b25a0b285578acedca25a77a412c4345
-rw-r--r--cmds/bootanimation/BootAnimation.cpp49
-rw-r--r--cmds/bootanimation/BootAnimation.h4
-rw-r--r--core/java/android/app/ActivityThread.java11
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java9
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java45
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplay.java14
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java23
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java7
-rw-r--r--services/java/com/android/server/SystemServer.java11
9 files changed, 162 insertions, 11 deletions
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 8ffe5bf59315..ed6c25dc49c3 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -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(),
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 56e131523bcb..b4699d884681 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -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;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 87b334992d2d..ab0b88c22d28 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -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
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3faa1deb5c40..473bb996e945 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -26853,14 +26853,11 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public void notifyDefaultDisplaySizeChanged() {
synchronized (this) {
- if (mSystemServiceManager.isBootCompleted()) {
- Slog.i(TAG, "Killing processes because of display size change");
- killAllBackgroundProcessesExcept(-1, ActivityManager.PROCESS_STATE_SERVICE);
+ if (mSystemServiceManager.isBootCompleted() && mHomeProcess != null) {
// TODO: Ugly hack to unblock the release
- if (mHomeProcess != null) {
- removeProcessLocked(mHomeProcess, false, true, "kill home screen size");
- }
+ Slog.i(TAG, "Killing home process because of display size change");
+ removeProcessLocked(mHomeProcess, false, true, "kill home screen size");
}
}
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index ddd8855f3199..cc5a8271eb5f 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -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;
}
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 373de63c0ec9..5b7c5205ce3a 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -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
@@ -297,6 +300,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.
*/
private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) {
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index f082271ab094..c73870189002 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -22,11 +22,14 @@ import static android.content.Intent.ACTION_PACKAGE_CHANGED;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.content.Intent.ACTION_USER_ADDED;
import static android.content.Intent.ACTION_USER_REMOVED;
+import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.SIGNATURE_MATCH;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.ActivityThread;
import android.app.IActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -34,6 +37,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
+import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManagerInternal;
@@ -269,13 +273,30 @@ public final class OverlayManagerService extends SystemService {
@Override
public void onBootPhase(int phase) {
- if (phase == PHASE_SYSTEM_SERVICES_READY) {
+ if (phase == PHASE_SYSTEM_SERVICES_READY && mInitCompleteSignal != null) {
ConcurrentUtils.waitForFutureNoInterrupt(mInitCompleteSignal,
"Wait for OverlayManagerService init");
mInitCompleteSignal = null;
}
}
+ public void updateSystemUiContext() {
+ if (mInitCompleteSignal != null) {
+ ConcurrentUtils.waitForFutureNoInterrupt(mInitCompleteSignal,
+ "Wait for OverlayManagerService init");
+ mInitCompleteSignal = null;
+ }
+
+ final ApplicationInfo ai;
+ try {
+ ai = mPackageManager.mPackageManager.getApplicationInfo("android",
+ GET_SHARED_LIBRARY_FILES, UserHandle.USER_SYSTEM);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ ActivityThread.currentActivityThread().handleSystemApplicationInfoChanged(ai);
+ }
+
private void initIfNeeded() {
final UserManager um = getContext().getSystemService(UserManager.class);
final List<UserInfo> users = um.getUsers(true /*excludeDying*/);
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index fa8a5c66aeea..755a571cf5f7 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -37,6 +37,7 @@ import android.view.DisplayInfo;
import android.view.Surface;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -268,6 +269,12 @@ class ScreenRotationAnimation {
.setSecure(isSecure)
.build();
+ // In case display bounds change, screenshot buffer and surface may mismatch so set a
+ // scaling mode.
+ Transaction t2 = new Transaction();
+ t2.setOverrideScalingMode(mSurfaceControl, Surface.SCALING_MODE_SCALE_TO_WINDOW);
+ t2.apply(true /* sync */);
+
// capture a screenshot into the surface we just created
// TODO(multidisplay): we should use the proper display
final int displayId = SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 1880e9fa362c..bb474d8b9e00 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -28,6 +28,7 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources.Theme;
import android.database.sqlite.SQLiteCompatibilityWalFlags;
+import android.hardware.display.DisplayManagerInternal;
import android.os.BaseBundle;
import android.os.Binder;
import android.os.Build;
@@ -672,9 +673,17 @@ public final class SystemServer {
// Manages Overlay packages
traceBeginAndSlog("StartOverlayManagerService");
- mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
+ OverlayManagerService overlayManagerService = new OverlayManagerService(
+ mSystemContext, installer);
+ mSystemServiceManager.startService(overlayManagerService);
traceEnd();
+ if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) {
+ // DisplayManager needs the overlay immediately.
+ overlayManagerService.updateSystemUiContext();
+ LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged();
+ }
+
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
// Start sensor service in a separate thread. Completion should be checked