diff options
82 files changed, 681 insertions, 135 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java index 687b1d4e0bde..f36084386f48 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -463,9 +463,6 @@ public class AppStandbyController implements AppStandbyInternal { userFileExists = mAppIdleHistory.userFileExists(UserHandle.USER_SYSTEM); } - // Offload to handler thread to avoid boottime impact. - mHandler.post(this::loadHeadlessSystemAppCache); - if (mPendingInitializeDefaults || !userFileExists) { initializeDefaultsForSystemApps(UserHandle.USER_SYSTEM); } @@ -475,6 +472,10 @@ public class AppStandbyController implements AppStandbyInternal { } } else if (phase == PHASE_BOOT_COMPLETED) { setChargingState(mInjector.isCharging()); + + // Offload to handler thread after boot completed to avoid boot time impact. This means + // that headless system apps may be put in a lower bucket until boot has completed. + mHandler.post(this::loadHeadlessSystemAppCache); } } diff --git a/api/test-current.txt b/api/test-current.txt index 7fd56984799f..3838bad57aa7 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5149,7 +5149,7 @@ package android.view { } public final class SurfaceControl implements android.os.Parcelable { - ctor public SurfaceControl(@NonNull android.view.SurfaceControl); + ctor public SurfaceControl(@NonNull android.view.SurfaceControl, @NonNull String); method public static long acquireFrameRateFlexibilityToken(); method public boolean isSameSurface(@NonNull android.view.SurfaceControl); method public static void releaseFrameRateFlexibilityToken(long); diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp index 5722f923d11e..6d9beb8f718d 100644 --- a/cmds/statsd/src/anomaly/AlarmTracker.cpp +++ b/cmds/statsd/src/anomaly/AlarmTracker.cpp @@ -60,11 +60,11 @@ void AlarmTracker::addSubscription(const Subscription& subscription) { } int64_t AlarmTracker::findNextAlarmSec(int64_t currentTimeSec) { - if (currentTimeSec <= mAlarmSec) { + if (currentTimeSec < mAlarmSec) { return mAlarmSec; } int64_t periodsForward = - ((currentTimeSec - mAlarmSec) * MS_PER_SEC - 1) / mAlarmConfig.period_millis() + 1; + ((currentTimeSec - mAlarmSec) * MS_PER_SEC) / mAlarmConfig.period_millis() + 1; return mAlarmSec + periodsForward * mAlarmConfig.period_millis() / MS_PER_SEC; } diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 02c0763c9d83..12e428ce5674 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -4948,6 +4948,8 @@ message BlobCommitted { ERROR_DURING_COMMIT = 2; // Commit Failed: Digest of the data did not match Blob digest DIGEST_MISMATCH = 3; + // Commit Failed: Allowed count limit exceeded + COUNT_LIMIT_EXCEEDED = 4; } optional Result result = 4; } @@ -4980,6 +4982,8 @@ message BlobLeased{ LEASE_EXPIRY_INVALID = 4; // Lease Failed: Leasee has exceeded the total data lease limit DATA_SIZE_LIMIT_EXCEEDED = 5; + // Leasee Failed: Allowed count limit exceeded + COUNT_LIMIT_EXCEEDED = 6; } optional Result result = 4; } diff --git a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp index 322cfaf68a41..64ea219c8465 100644 --- a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp +++ b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp @@ -43,23 +43,47 @@ TEST(AlarmTrackerTest, TestTriggerTimestamp) { alarm.set_offset_millis(15 * MS_PER_SEC); alarm.set_period_millis(60 * 60 * MS_PER_SEC); // 1hr int64_t startMillis = 100000000 * MS_PER_SEC; + int64_t nextAlarmTime = startMillis / MS_PER_SEC + 15; AlarmTracker tracker(startMillis, startMillis, alarm, kConfigKey, subscriberAlarmMonitor); - EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15)); + EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime); uint64_t currentTimeSec = startMillis / MS_PER_SEC + 10; std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec)); EXPECT_TRUE(firedAlarmSet.empty()); tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet); - EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15)); + EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime); + EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime); currentTimeSec = startMillis / MS_PER_SEC + 7000; + nextAlarmTime = startMillis / MS_PER_SEC + 15 + 2 * 60 * 60; firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec)); ASSERT_EQ(firedAlarmSet.size(), 1u); tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet); EXPECT_TRUE(firedAlarmSet.empty()); - EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15 + 2 * 60 * 60)); + EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime); + EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime); + + // Alarm fires exactly on time. + currentTimeSec = startMillis / MS_PER_SEC + 15 + 2 * 60 * 60; + nextAlarmTime = startMillis / MS_PER_SEC + 15 + 3 * 60 * 60; + firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec)); + ASSERT_EQ(firedAlarmSet.size(), 1u); + tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet); + EXPECT_TRUE(firedAlarmSet.empty()); + EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime); + EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime); + + // Alarm fires exactly 1 period late. + currentTimeSec = startMillis / MS_PER_SEC + 15 + 4 * 60 * 60; + nextAlarmTime = startMillis / MS_PER_SEC + 15 + 5 * 60 * 60; + firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec)); + ASSERT_EQ(firedAlarmSet.size(), 1u); + tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet); + EXPECT_TRUE(firedAlarmSet.empty()); + EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime); + EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime); } } // namespace statsd diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java index 2d2dda04b146..e385cd2b7ecd 100644 --- a/core/java/android/hardware/biometrics/BiometricManager.java +++ b/core/java/android/hardware/biometrics/BiometricManager.java @@ -121,7 +121,7 @@ public class BiometricManager { /** * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the - * requirements for <strong>Tier 3</strong> (formerly <strong>Strong</strong>), as defined + * requirements for <strong>Class 3</strong> (formerly <strong>Strong</strong>), as defined * by the Android CDD. * * <p>This corresponds to {@link KeyProperties#AUTH_BIOMETRIC_STRONG} during key generation. @@ -132,7 +132,7 @@ public class BiometricManager { /** * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the - * requirements for <strong>Tier 2</strong> (formerly <strong>Weak</strong>), as defined by + * requirements for <strong>Class 2</strong> (formerly <strong>Weak</strong>), as defined by * the Android CDD. * * <p>Note that this is a superset of {@link #BIOMETRIC_STRONG} and is defined such that @@ -142,7 +142,7 @@ public class BiometricManager { /** * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the - * requirements for <strong>Tier 1</strong> (formerly <strong>Convenience</strong>), as + * requirements for <strong>Class 1</strong> (formerly <strong>Convenience</strong>), as * defined by the Android CDD. * * <p>This constant is intended for use by {@link android.provider.DeviceConfig} to adjust diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 8d65c92db52e..257bc5b64285 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -1918,9 +1918,16 @@ public final class StrictMode { } private static class AndroidCloseGuardReporter implements CloseGuard.Reporter { + + @Override public void report(String message, Throwable allocationSite) { onVmPolicyViolation(new LeakedClosableViolation(message, allocationSite)); } + + @Override + public void report(String message) { + onVmPolicyViolation(new LeakedClosableViolation(message)); + } } /** Called from Parcel.writeNoException() */ diff --git a/core/java/android/os/strictmode/LeakedClosableViolation.java b/core/java/android/os/strictmode/LeakedClosableViolation.java index c795a6b89ec0..a2b02833afa0 100644 --- a/core/java/android/os/strictmode/LeakedClosableViolation.java +++ b/core/java/android/os/strictmode/LeakedClosableViolation.java @@ -21,4 +21,9 @@ public final class LeakedClosableViolation extends Violation { super(message); initCause(allocationSite); } + + /** @hide */ + public LeakedClosableViolation(String message) { + super(message); + } } diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java index 2c2ecd504519..51b49214387a 100644 --- a/core/java/android/view/InsetsSourceControl.java +++ b/core/java/android/view/InsetsSourceControl.java @@ -45,7 +45,7 @@ public class InsetsSourceControl implements Parcelable { public InsetsSourceControl(InsetsSourceControl other) { mType = other.mType; if (other.mLeash != null) { - mLeash = new SurfaceControl(other.mLeash); + mLeash = new SurfaceControl(other.mLeash, "InsetsSourceControl"); } else { mLeash = null; } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index daeb1c9c1e01..87b2f4b46df7 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -499,14 +499,12 @@ public final class SurfaceControl implements Parcelable { private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696; private static final int INTERNAL_DATASPACE_SCRGB = 411107328; - private void assignNativeObject(long nativeObject) { + private void assignNativeObject(long nativeObject, String callsite) { if (mNativeObject != 0) { release(); } if (nativeObject != 0) { - Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "closeGuard"); - mCloseGuard.open("release"); - Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); + mCloseGuard.openWithCallSite("release", callsite); } mNativeObject = nativeObject; mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0; @@ -515,12 +513,12 @@ public final class SurfaceControl implements Parcelable { /** * @hide */ - public void copyFrom(@NonNull SurfaceControl other) { + public void copyFrom(@NonNull SurfaceControl other, String callsite) { mName = other.mName; mWidth = other.mWidth; mHeight = other.mHeight; mLocalOwnerView = other.mLocalOwnerView; - assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject)); + assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite); } /** @@ -621,6 +619,7 @@ public final class SurfaceControl implements Parcelable { private WeakReference<View> mLocalOwnerView; private SurfaceControl mParent; private SparseIntArray mMetadata; + private String mCallsite = "SurfaceControl.Builder"; /** * Begin building a SurfaceControl with a given {@link SurfaceSession}. @@ -654,7 +653,7 @@ public final class SurfaceControl implements Parcelable { } return new SurfaceControl( mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata, - mLocalOwnerView); + mLocalOwnerView, mCallsite); } /** @@ -912,6 +911,18 @@ public final class SurfaceControl implements Parcelable { return this; } + /** + * Sets the callsite this SurfaceControl is constructed from. + * + * @param callsite String uniquely identifying callsite that created this object. Used for + * leakage tracking. + * @hide + */ + public Builder setCallsite(String callsite) { + mCallsite = callsite; + return this; + } + private Builder setFlags(int flags, int mask) { mFlags = (mFlags & ~mask) | flags; return this; @@ -943,10 +954,13 @@ public final class SurfaceControl implements Parcelable { * @param h The surface initial height. * @param flags The surface creation flags. * @param metadata Initial metadata. + * @param callsite String uniquely identifying callsite that created this object. Used for + * leakage tracking. * @throws throws OutOfResourcesException If the SurfaceControl cannot be created. */ private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, - SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView) + SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView, + String callsite) throws OutOfResourcesException, IllegalArgumentException { if (name == null) { throw new IllegalArgumentException("name must not be null"); @@ -978,18 +992,20 @@ public final class SurfaceControl implements Parcelable { "Couldn't allocate SurfaceControl native object"); } mNativeHandle = nativeGetHandle(mNativeObject); - mCloseGuard.open("release"); + mCloseGuard.openWithCallSite("release", callsite); } /** * Copy constructor. Creates a new native object pointing to the same surface as {@code other}. * * @param other The object to copy the surface from. + * @param callsite String uniquely identifying callsite that created this object. Used for + * leakage tracking. * @hide */ @TestApi - public SurfaceControl(@NonNull SurfaceControl other) { - copyFrom(other); + public SurfaceControl(@NonNull SurfaceControl other, @NonNull String callsite) { + copyFrom(other, callsite); } private SurfaceControl(Parcel in) { @@ -1015,7 +1031,7 @@ public final class SurfaceControl implements Parcelable { if (in.readInt() != 0) { object = nativeReadFromParcel(in); } - assignNativeObject(object); + assignNativeObject(object, "readFromParcel"); } @Override @@ -2209,7 +2225,7 @@ public final class SurfaceControl implements Parcelable { public static SurfaceControl mirrorSurface(SurfaceControl mirrorOf) { long nativeObj = nativeMirrorSurface(mirrorOf.mNativeObject); SurfaceControl sc = new SurfaceControl(); - sc.assignNativeObject(nativeObj); + sc.assignNativeObject(nativeObj, "mirrorSurface"); return sc; } diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index 86a4fe170387..66ab3a32edfa 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -167,9 +167,10 @@ public class SurfaceControlViewHost { public SurfaceControlViewHost(@NonNull Context context, @NonNull Display display, @Nullable IBinder hostToken) { mSurfaceControl = new SurfaceControl.Builder() - .setContainerLayer() - .setName("SurfaceControlViewHost") - .build(); + .setContainerLayer() + .setName("SurfaceControlViewHost") + .setCallsite("SurfaceControlViewHost") + .build(); mWm = new WindowlessWindowManager(context.getResources().getConfiguration(), mSurfaceControl, hostToken); mViewRoot = new ViewRootImpl(context, display, mWm); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 0d21eb5cf920..bb0de120dedc 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -993,6 +993,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall .setFormat(mFormat) .setParent(viewRoot.getBoundsLayer()) .setFlags(mSurfaceFlags) + .setCallsite("SurfaceView.updateSurface") .build(); mBackgroundControl = new SurfaceControl.Builder(mSurfaceSession) .setName("Background for -" + name) @@ -1000,6 +1001,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall .setOpaque(true) .setColorLayer() .setParent(mSurfaceControl) + .setCallsite("SurfaceView.updateSurface") .build(); } else if (mSurfaceControl == null) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index df1c672eb9eb..ca424e79ed7b 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -26372,6 +26372,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, .setParent(root.getSurfaceControl()) .setBufferSize(shadowSize.x, shadowSize.y) .setFormat(PixelFormat.TRANSLUCENT) + .setCallsite("View.startDragAndDrop") .build(); final Surface surface = new Surface(); surface.copyFrom(surfaceControl); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 896a2de8b135..a58642517a20 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1782,6 +1782,7 @@ public final class ViewRootImpl implements ViewParent, .setContainerLayer() .setName("Bounds for - " + getTitle().toString()) .setParent(getRenderSurfaceControl()) + .setCallsite("ViewRootImpl.getBoundsLayer") .build(); setBoundsLayerCrop(); mTransaction.show(mBoundsLayer).apply(); diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index d2e506ea550c..1af4c3636ac5 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -136,7 +136,8 @@ public class WindowlessWindowManager implements IWindowSession { .setParent(mRootSurface) .setFormat(attrs.format) .setBufferSize(getSurfaceWidth(attrs), getSurfaceHeight(attrs)) - .setName(attrs.getTitle().toString()); + .setName(attrs.getTitle().toString()) + .setCallsite("WindowlessWindowManager.addToDisplay"); final SurfaceControl sc = b.build(); if (((attrs.inputFeatures & @@ -248,7 +249,7 @@ public class WindowlessWindowManager implements IWindowSession { if (viewFlags == View.VISIBLE) { t.setBufferSize(sc, getSurfaceWidth(attrs), getSurfaceHeight(attrs)) .setOpaque(sc, isOpaque(attrs)).show(sc).apply(); - outSurfaceControl.copyFrom(sc); + outSurfaceControl.copyFrom(sc, "WindowlessWindowManager.relayout"); } else { t.hide(sc).apply(); outSurfaceControl.release(); diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java index 8ea824d3ce82..7fa8f9a31526 100644 --- a/core/java/android/widget/Magnifier.java +++ b/core/java/android/widget/Magnifier.java @@ -1000,6 +1000,7 @@ public final class Magnifier { .setName("magnifier surface") .setFlags(SurfaceControl.HIDDEN) .setParent(parentSurfaceControl) + .setCallsite("InternalPopupWindow") .build(); mSurface = new Surface(); mSurface.copyFrom(mSurfaceControl); diff --git a/core/java/android/window/TaskEmbedder.java b/core/java/android/window/TaskEmbedder.java index ca6c568c2668..0687a037df32 100644 --- a/core/java/android/window/TaskEmbedder.java +++ b/core/java/android/window/TaskEmbedder.java @@ -164,6 +164,7 @@ public abstract class TaskEmbedder { .setContainerLayer() .setParent(parent) .setName(name) + .setCallsite("TaskEmbedder.initialize") .build(); if (!onInitialize()) { diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index a30c3c52f42c..8c2358d253be 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -819,7 +819,8 @@ public class ChooserActivity extends ResolverActivity implements if (chooserListAdapter.getCount() == 0) { return; } - if (resultList.isEmpty()) { + if (resultList.isEmpty() + && shouldQueryShortcutManager(chooserListAdapter.getUserHandle())) { // APS may be disabled, so try querying targets ourselves. queryDirectShareTargets(chooserListAdapter, true); return; @@ -2025,6 +2026,26 @@ public class ChooserActivity extends ResolverActivity implements }); } + /** + * Returns {@code false} if {@code userHandle} is the work profile and it's either + * in quiet mode or not running. + */ + private boolean shouldQueryShortcutManager(UserHandle userHandle) { + if (!shouldShowTabs()) { + return true; + } + if (!getWorkProfileUserHandle().equals(userHandle)) { + return true; + } + if (!isUserRunning(userHandle)) { + return false; + } + if (isQuietModeEnabled(userHandle)) { + return false; + } + return true; + } + private void sendChooserTargetRankingScore(List<AppTarget> chooserTargetScores, UserHandle userHandle) { final Message msg = Message.obtain(); @@ -2839,8 +2860,8 @@ public class ChooserActivity extends ResolverActivity implements return; } - // no need to query direct share for work profile when its turned off - if (isQuietModeEnabled(chooserListAdapter.getUserHandle())) { + // no need to query direct share for work profile when its locked or disabled + if (!shouldQueryShortcutManager(chooserListAdapter.getUserHandle())) { getChooserActivityLogger().logSharesheetAppLoadComplete(); return; } @@ -2865,6 +2886,12 @@ public class ChooserActivity extends ResolverActivity implements } @VisibleForTesting + protected boolean isUserRunning(UserHandle userHandle) { + UserManager userManager = getSystemService(UserManager.class); + return userManager.isUserRunning(userHandle); + } + + @VisibleForTesting protected boolean isQuietModeEnabled(UserHandle userHandle) { UserManager userManager = getSystemService(UserManager.class); return userManager.isQuietModeEnabled(userHandle); diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java index 31e6cb9b5591..00b5cb646bca 100644 --- a/core/java/com/android/internal/app/ChooserListAdapter.java +++ b/core/java/com/android/internal/app/ChooserListAdapter.java @@ -917,6 +917,7 @@ public class ChooserListAdapter extends ResolverListAdapter { if (getAppPredictor() != null) { getAppPredictor().unregisterPredictionUpdates(mAppPredictorCallback); getAppPredictor().destroy(); + setAppPredictor(null); } } diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index 964ae21d6086..702f2fa65487 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -717,7 +717,7 @@ public class InsetsControllerTest { // Simulate binder behavior by copying SurfaceControl. Otherwise, InsetsController will // attempt to release mLeash directly. - SurfaceControl copy = new SurfaceControl(mLeash); + SurfaceControl copy = new SurfaceControl(mLeash, "InsetsControllerTest.createControl"); return new InsetsSourceControl(type, copy, new Point()); } diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java index 49de7c80057f..0bf10cb710cb 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -1995,6 +1995,70 @@ public class ChooserActivityTest { isQueryTargetServicesCalledOnWorkProfile[0]); } + @Test + public void testWorkTab_selectingWorkTabWithLockedWorkUser_directShareTargetsNotQueried() { + // enable the work tab feature flag + ResolverActivity.ENABLE_TABBED_VIEW = true; + markWorkProfileUserAvailable(); + List<ResolvedComponentInfo> personalResolvedComponentInfos = + createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); + List<ResolvedComponentInfo> workResolvedComponentInfos = + createResolvedComponentsForTest(3); + setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); + sOverrides.isWorkProfileUserRunning = false; + boolean[] isQueryDirectShareCalledOnWorkProfile = new boolean[] { false }; + sOverrides.onQueryDirectShareTargets = chooserListAdapter -> { + isQueryDirectShareCalledOnWorkProfile[0] = + (chooserListAdapter.getUserHandle().getIdentifier() == 10); + return null; + }; + boolean[] isQueryTargetServicesCalledOnWorkProfile = new boolean[] { false }; + sOverrides.onQueryTargetServices = chooserListAdapter -> { + isQueryTargetServicesCalledOnWorkProfile[0] = + (chooserListAdapter.getUserHandle().getIdentifier() == 10); + return null; + }; + Intent sendIntent = createSendTextIntent(); + sendIntent.setType("TestType"); + + mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); + waitForIdle(); + onView(withId(R.id.contentPanel)) + .perform(swipeUp()); + onView(withText(R.string.resolver_work_tab)).perform(click()); + waitForIdle(); + + assertFalse("Direct share targets were queried on a locked work profile user", + isQueryDirectShareCalledOnWorkProfile[0]); + assertFalse("Target services were queried on a locked work profile user", + isQueryTargetServicesCalledOnWorkProfile[0]); + } + + @Test + public void testWorkTab_workUserLocked_workTargetsShown() { + // enable the work tab feature flag + ResolverActivity.ENABLE_TABBED_VIEW = true; + markWorkProfileUserAvailable(); + List<ResolvedComponentInfo> personalResolvedComponentInfos = + createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); + List<ResolvedComponentInfo> workResolvedComponentInfos = + createResolvedComponentsForTest(3); + setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); + Intent sendIntent = createSendTextIntent(); + sendIntent.setType("TestType"); + sOverrides.isWorkProfileUserRunning = false; + + final ChooserWrapperActivity activity = + mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); + waitForIdle(); + onView(withId(R.id.contentPanel)) + .perform(swipeUp()); + onView(withText(R.string.resolver_work_tab)).perform(click()); + waitForIdle(); + + assertEquals(3, activity.getWorkListAdapter().getCount()); + } + private Intent createChooserIntent(Intent intent, Intent[] initialIntents) { Intent chooserIntent = new Intent(); chooserIntent.setAction(Intent.ACTION_CHOOSER); diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java index 0f6b51f82116..b7d6c6196495 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java @@ -227,6 +227,11 @@ public class ChooserWrapperActivity extends ChooserActivity { return sOverrides.isQuietModeEnabled; } + @Override + protected boolean isUserRunning(UserHandle userHandle) { + return sOverrides.isWorkProfileUserRunning; + } + /** * We cannot directly mock the activity created since instrumentation creates it. * <p> @@ -252,6 +257,7 @@ public class ChooserWrapperActivity extends ChooserActivity { public UserHandle workProfileUserHandle; public boolean hasCrossProfileIntents; public boolean isQuietModeEnabled; + public boolean isWorkProfileUserRunning; public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; public PackageManager packageManager; @@ -274,6 +280,7 @@ public class ChooserWrapperActivity extends ChooserActivity { workProfileUserHandle = null; hasCrossProfileIntents = true; isQuietModeEnabled = false; + isWorkProfileUserRunning = true; packageManager = null; multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { @Override diff --git a/data/etc/Android.bp b/data/etc/Android.bp index 1d3a3997d857..fb8b17c1f159 100644 --- a/data/etc/Android.bp +++ b/data/etc/Android.bp @@ -63,6 +63,14 @@ prebuilt_etc { } prebuilt_etc { + name: "privapp_whitelist_com.android.cellbroadcastreceiver", + system_ext_specific: true, + sub_dir: "permissions", + src: "com.android.cellbroadcastreceiver.xml", + filename_from_src: true, +} + +prebuilt_etc { name: "privapp_whitelist_com.android.contacts", product_specific: true, sub_dir: "permissions", diff --git a/data/etc/com.android.cellbroadcastreceiver.xml b/data/etc/com.android.cellbroadcastreceiver.xml new file mode 100644 index 000000000000..dd2df42e442f --- /dev/null +++ b/data/etc/com.android.cellbroadcastreceiver.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> +<permissions> + <privapp-permissions package="com.android.cellbroadcastreceiver"> + <permission name="android.permission.INTERACT_ACROSS_USERS"/> + <permission name="android.permission.MANAGE_USERS"/> + <permission name="android.permission.MODIFY_PHONE_STATE"/> + <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> + <permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/> + <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/> + </privapp-permissions> +</permissions> diff --git a/packages/SystemUI/res/layout/media_view.xml b/packages/SystemUI/res/layout/media_view.xml index 6792c647d666..8441282bd46d 100644 --- a/packages/SystemUI/res/layout/media_view.xml +++ b/packages/SystemUI/res/layout/media_view.xml @@ -27,6 +27,14 @@ android:forceHasOverlappingRendering="false" android:background="@drawable/qs_media_background"> + <androidx.constraintlayout.widget.Guideline + android:id="@+id/center_vertical_guideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_percent="0.5" + /> + <!-- As per Material Design on Biderectionality, this is forced to LTR in code --> <FrameLayout android:id="@+id/notification_media_progress_time" @@ -133,6 +141,7 @@ android:layout_width="@dimen/qs_seamless_icon_size" android:layout_height="@dimen/qs_seamless_icon_size" android:layout_marginEnd="8dp" + android:layout_gravity="center_vertical" android:tint="@color/media_primary_text" android:src="@*android:drawable/ic_media_seamless" /> @@ -140,6 +149,7 @@ android:id="@+id/media_seamless_text" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_gravity="center_vertical" android:fontFamily="@*android:string/config_headlineFontFamily" android:singleLine="true" android:text="@*android:string/ext_media_seamless_action" @@ -156,15 +166,6 @@ android:src="@drawable/ic_cast_connected" android:forceHasOverlappingRendering="false" /> - <androidx.constraintlayout.widget.Barrier - android:id="@+id/media_seamless_barrier" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:barrierDirection="start" - app:constraint_referenced_ids="media_seamless,media_seamless_fallback" - app:barrierAllowsGoneWidgets="false" - /> - <!-- Seek Bar --> <!-- As per Material Design on Biderectionality, this is forced to LTR in code --> <SeekBar diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index f1a0e3e2dc95..87e1499713bd 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1221,9 +1221,9 @@ <!-- Padding of bubble overflow empty state subtitle --> <dimen name="bubble_empty_overflow_subtitle_padding">50dp</dimen> <!-- Height of the triangle that points to the expanded bubble --> - <dimen name="bubble_pointer_height">4dp</dimen> + <dimen name="bubble_pointer_height">8dp</dimen> <!-- Width of the triangle that points to the expanded bubble --> - <dimen name="bubble_pointer_width">6dp</dimen> + <dimen name="bubble_pointer_width">12dp</dimen> <!-- Extra padding around the dismiss target for bubbles --> <dimen name="bubble_dismiss_slop">16dp</dimen> <!-- Height of button allowing users to adjust settings for bubbles. --> @@ -1269,6 +1269,7 @@ <dimen name="qs_media_padding">16dp</dimen> <dimen name="qs_media_panel_outer_padding">16dp</dimen> <dimen name="qs_media_album_size">52dp</dimen> + <dimen name="qs_center_guideline_padding">10dp</dimen> <dimen name="qs_seamless_icon_size">20dp</dimen> <dimen name="qs_seamless_fallback_icon_size">20dp</dimen> <dimen name="qs_seamless_fallback_top_margin">18dp</dimen> diff --git a/packages/SystemUI/res/xml/media_collapsed.xml b/packages/SystemUI/res/xml/media_collapsed.xml index 811e0e351bd3..0926a9802ff4 100644 --- a/packages/SystemUI/res/xml/media_collapsed.xml +++ b/packages/SystemUI/res/xml/media_collapsed.xml @@ -31,12 +31,12 @@ android:id="@+id/app_name" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="10dp" + android:layout_marginEnd="@dimen/qs_center_guideline_padding" android:layout_marginStart="10dp" android:layout_marginTop="20dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toEndOf="@id/icon" - app:layout_constraintEnd_toStartOf="@id/media_seamless_barrier" + app:layout_constraintEnd_toStartOf="@id/center_vertical_guideline" app:layout_constraintHorizontal_bias="0" /> @@ -47,8 +47,11 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintWidth_min="60dp" + app:layout_constraintStart_toEndOf="@id/center_vertical_guideline" + app:layout_constraintHorizontal_bias="1" android:layout_marginTop="@dimen/qs_media_panel_outer_padding" android:layout_marginEnd="@dimen/qs_media_panel_outer_padding" + android:layout_marginStart="@dimen/qs_center_guideline_padding" /> <Constraint @@ -57,10 +60,13 @@ android:layout_height="@dimen/qs_seamless_fallback_icon_size" android:layout_marginTop="@dimen/qs_seamless_fallback_top_margin" android:layout_marginEnd="@dimen/qs_seamless_fallback_end_margin" + android:layout_marginStart="@dimen/qs_center_guideline_padding" android:alpha="0.5" android:visibility="gone" + app:layout_constraintHorizontal_bias="1" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toEndOf="@id/center_vertical_guideline" /> <Constraint diff --git a/packages/SystemUI/res/xml/media_expanded.xml b/packages/SystemUI/res/xml/media_expanded.xml index 8432abcc16cb..dd15d5d8bb4e 100644 --- a/packages/SystemUI/res/xml/media_expanded.xml +++ b/packages/SystemUI/res/xml/media_expanded.xml @@ -31,12 +31,12 @@ android:id="@+id/app_name" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="10dp" + android:layout_marginEnd="@dimen/qs_center_guideline_padding" android:layout_marginStart="10dp" android:layout_marginTop="20dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toEndOf="@id/icon" - app:layout_constraintEnd_toStartOf="@id/media_seamless_barrier" + app:layout_constraintEnd_toStartOf="@id/center_vertical_guideline" app:layout_constraintHorizontal_bias="0" /> @@ -46,9 +46,12 @@ android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toEndOf="@id/center_vertical_guideline" + app:layout_constraintHorizontal_bias="1" app:layout_constraintWidth_min="60dp" android:layout_marginTop="@dimen/qs_media_panel_outer_padding" android:layout_marginEnd="@dimen/qs_media_panel_outer_padding" + android:layout_marginStart="@dimen/qs_center_guideline_padding" /> <Constraint @@ -57,10 +60,13 @@ android:layout_height="@dimen/qs_seamless_fallback_icon_size" android:layout_marginTop="@dimen/qs_seamless_fallback_top_margin" android:layout_marginEnd="@dimen/qs_seamless_fallback_end_margin" + android:layout_marginStart="@dimen/qs_center_guideline_padding" android:alpha="0.5" android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toEndOf="@id/center_vertical_guideline" + app:layout_constraintHorizontal_bias="1" /> <Constraint diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index ee31706c0b94..7792afa3d84c 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -251,7 +251,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private boolean mDeviceProvisioned; // Battery status - private BatteryStatus mBatteryStatus; + @VisibleForTesting + BatteryStatus mBatteryStatus; private StrongAuthTracker mStrongAuthTracker; @@ -1698,6 +1699,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab .getServiceStateForSubscriber(subId); mHandler.sendMessage( mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState)); + + // Get initial state. Relying on Sticky behavior until API for getting info. + if (mBatteryStatus == null) { + Intent intent = mContext.registerReceiver( + null, + new IntentFilter(Intent.ACTION_BATTERY_CHANGED) + ); + if (intent != null && mBatteryStatus == null) { + mBroadcastReceiver.onReceive(mContext, intent); + } + } }); mHandler.post(this::registerRingerTracker); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index b739999fb652..6ea0cde44282 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -1307,7 +1307,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi for (Pair<Bubble, Integer> removed : removedBubbles) { final Bubble bubble = removed.first; @DismissReason final int reason = removed.second; - mStackView.removeBubble(bubble); + + if (mStackView != null) { + mStackView.removeBubble(bubble); + } // If the bubble is removed for user switching, leave the notification in place. if (reason == DISMISS_USER_CHANGED) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 2bfe015c2787..1211fb491ced 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -495,12 +495,9 @@ public class BubbleExpandedView extends LinearLayout { } final float alpha = visibility ? 1f : 0f; - if (alpha == mActivityView.getAlpha()) { - return; - } - mPointerView.setAlpha(alpha); - if (mActivityView != null) { + + if (mActivityView != null && alpha != mActivityView.getAlpha()) { mActivityView.setAlpha(alpha); mActivityView.bringToFront(); } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 1f3d981b8c9f..cd27fdf9c947 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -273,7 +273,6 @@ public class BubbleStackView extends FrameLayout private int mBubbleTouchPadding; private int mExpandedViewPadding; private int mCornerRadius; - private int mPointerHeight; private int mStatusBarHeight; private int mImeOffset; @Nullable private BubbleViewProvider mExpandedBubble; @@ -784,7 +783,6 @@ public class BubbleStackView extends FrameLayout mBubbleElevation = res.getDimensionPixelSize(R.dimen.bubble_elevation); mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top); mBubbleTouchPadding = res.getDimensionPixelSize(R.dimen.bubble_touch_padding); - mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height); mStatusBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); @@ -1581,7 +1579,13 @@ public class BubbleStackView extends FrameLayout if (DEBUG_BUBBLE_STACK_VIEW) { Log.d(TAG, "setSelectedBubble: " + bubbleToSelect); } - if (mExpandedBubble != null && mExpandedBubble.equals(bubbleToSelect)) { + + // Ignore this new bubble only if it is the exact same bubble object. Otherwise, we'll want + // to re-render it even if it has the same key (equals() returns true). If the currently + // expanded bubble is removed and instantly re-added, we'll get back a new Bubble instance + // with the same key (with newly inflated expanded views), and we need to render those new + // views. + if (mExpandedBubble == bubbleToSelect) { return; } if (bubbleToSelect == null || bubbleToSelect.getKey() != BubbleOverflow.KEY) { @@ -1661,6 +1665,13 @@ public class BubbleStackView extends FrameLayout if (DEBUG_BUBBLE_STACK_VIEW) { Log.d(TAG, "setExpanded: " + shouldExpand); } + + if (!shouldExpand) { + // If we're collapsing, release the animating-out surface immediately since we have no + // need for it, and this ensures it cannot remain visible as we collapse. + releaseAnimatingOutBubbleBuffer(); + } + if (shouldExpand == mIsExpanded) { return; } @@ -2390,7 +2401,7 @@ public class BubbleStackView extends FrameLayout * Calculates the y position of the expanded view when it is expanded. */ float getExpandedViewY() { - return getStatusBarHeight() + mBubbleSize + mBubblePaddingTop + mPointerHeight; + return getStatusBarHeight() + mBubbleSize + mBubblePaddingTop; } /** @@ -2663,7 +2674,7 @@ public class BubbleStackView extends FrameLayout * expanded bubble. */ private void screenshotAnimatingOutBubbleIntoSurface(Consumer<Boolean> onComplete) { - if (mExpandedBubble == null || mExpandedBubble.getExpandedView() == null) { + if (!mIsExpanded || mExpandedBubble == null || mExpandedBubble.getExpandedView() == null) { // You can't animate null. onComplete.accept(false); return; diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt index 15d15e8ffbc7..4ed610675093 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt @@ -41,7 +41,7 @@ import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.util.LifecycleActivity import javax.inject.Inject -class ControlsRequestDialog @Inject constructor( +open class ControlsRequestDialog @Inject constructor( private val controller: ControlsController, private val broadcastDispatcher: BroadcastDispatcher, private val controlsListingController: ControlsListingController @@ -51,7 +51,7 @@ class ControlsRequestDialog @Inject constructor( private const val TAG = "ControlsRequestDialog" } - private lateinit var component: ComponentName + private lateinit var controlComponent: ComponentName private lateinit var control: Control private var dialog: Dialog? = null private val callback = object : ControlsListingController.ControlsListingCallback { @@ -86,7 +86,7 @@ class ControlsRequestDialog @Inject constructor( finish() } - component = intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME) ?: run { + controlComponent = intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME) ?: run { Log.e(TAG, "Request did not contain componentName") finish() return @@ -103,7 +103,7 @@ class ControlsRequestDialog @Inject constructor( super.onResume() val label = verifyComponentAndGetLabel() if (label == null) { - Log.e(TAG, "The component specified (${component.flattenToString()} " + + Log.e(TAG, "The component specified (${controlComponent.flattenToString()} " + "is not a valid ControlsProviderService") finish() return @@ -127,16 +127,16 @@ class ControlsRequestDialog @Inject constructor( } private fun verifyComponentAndGetLabel(): CharSequence? { - return controlsListingController.getAppLabel(component) + return controlsListingController.getAppLabel(controlComponent) } private fun isCurrentFavorite(): Boolean { - val favorites = controller.getFavoritesForComponent(component) + val favorites = controller.getFavoritesForComponent(controlComponent) return favorites.any { it.controls.any { it.controlId == control.controlId } } } fun createDialog(label: CharSequence): Dialog { - val renderInfo = RenderInfo.lookup(this, component, control.deviceType) + val renderInfo = RenderInfo.lookup(this, controlComponent, control.deviceType) val frame = LayoutInflater.from(this).inflate(R.layout.controls_dialog, null).apply { requireViewById<ImageView>(R.id.icon).apply { setImageDrawable(renderInfo.icon) @@ -170,7 +170,7 @@ class ControlsRequestDialog @Inject constructor( override fun onClick(dialog: DialogInterface?, which: Int) { if (which == Dialog.BUTTON_POSITIVE) { controller.addFavorite( - componentName, + controlComponent, control.structure ?: "", ControlInfo(control.controlId, control.title, control.subtitle, control.deviceType) ) diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt index c073642afa4e..22d6b6bb75c3 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt @@ -128,15 +128,22 @@ class ControlActionCoordinatorImpl @Inject constructor( } private fun bouncerOrRun(action: Action) { - if (!keyguardStateController.isUnlocked()) { - context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) + if (keyguardStateController.isShowing()) { + var closeGlobalActions = !keyguardStateController.isUnlocked() + if (closeGlobalActions) { + context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) - // pending actions will only run after the control state has been refreshed - pendingAction = action + // pending actions will only run after the control state has been refreshed + pendingAction = action + } activityStarter.dismissKeyguardThenExecute({ Log.d(ControlsUiController.TAG, "Device unlocked, invoking controls action") - globalActionsComponent.handleShowGlobalActionsMenu() + if (closeGlobalActions) { + globalActionsComponent.handleShowGlobalActionsMenu() + } else { + action.invoke() + } true }, { pendingAction = null }, true /* afterKeyguardGone */) } else { diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index eed52004923d..b2e91643bed2 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -2637,10 +2637,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } private boolean shouldShowControls() { - return (mKeyguardStateController.isUnlocked() || mShowLockScreenCardsAndControls) - && controlsAvailable() - && mLockPatternUtils.getStrongAuthForUser(getCurrentUser().id) - != STRONG_AUTH_REQUIRED_AFTER_BOOT; + boolean showOnLockScreen = mShowLockScreenCardsAndControls && mLockPatternUtils + .getStrongAuthForUser(getCurrentUser().id) != STRONG_AUTH_REQUIRED_AFTER_BOOT; + return controlsAvailable() + && (mKeyguardStateController.isUnlocked() || showOnLockScreen); } private boolean controlsAvailable() { diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 5052386e65e1..d6b6660b778c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -193,12 +193,15 @@ class MediaDataManager( private fun clearData() { // Called on user change. Remove all current MediaData objects and inform listeners val listenersCopy = listeners.toSet() - mediaEntries.forEach { + val keyCopy = mediaEntries.keys.toMutableList() + // Clear the list first, to make sure callbacks from listeners if we have any entries + // are up to date + mediaEntries.clear() + keyCopy.forEach { listenersCopy.forEach { listener -> - listener.onMediaDataRemoved(it.key) + listener.onMediaDataRemoved(it) } } - mediaEntries.clear() } private fun removeAllForPackage(packageName: String) { diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java index 078c540939aa..66804bef8f53 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java @@ -225,6 +225,8 @@ public class PowerUI extends SystemUI implements CommandQueue.Callbacks { @VisibleForTesting final class Receiver extends BroadcastReceiver { + private boolean mHasReceivedBattery = false; + public void init() { // Register for Intent broadcasts for... IntentFilter filter = new IntentFilter(); @@ -234,6 +236,17 @@ public class PowerUI extends SystemUI implements CommandQueue.Callbacks { filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_USER_SWITCHED); mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mHandler); + // Force get initial values. Relying on Sticky behavior until API for getting info. + if (!mHasReceivedBattery) { + // Get initial state + Intent intent = mContext.registerReceiver( + null, + new IntentFilter(Intent.ACTION_BATTERY_CHANGED) + ); + if (intent != null) { + onReceive(mContext, intent); + } + } } @Override @@ -246,6 +259,7 @@ public class PowerUI extends SystemUI implements CommandQueue.Callbacks { } }); } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { + mHasReceivedBattery = true; final int oldBatteryLevel = mBatteryLevel; mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100); final int oldBatteryStatus = mBatteryStatus; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index 6b12e478f627..eba4465018ab 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -96,6 +96,11 @@ public class QSContainerImpl extends FrameLayout { mAnimateBottomOnNextLayout = true; } }); + mQSPanel.setMediaVisibilityChangedListener((visible) -> { + if (mQSPanel.isShown()) { + mAnimateBottomOnNextLayout = true; + } + }); setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java index 4a2cad705c17..7a313dc0622b 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java @@ -102,10 +102,14 @@ class SplitScreenTaskOrganizer extends TaskOrganizer { // Initialize dim surfaces: mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession) .setParent(mPrimarySurface).setColorLayer() - .setName("Primary Divider Dim").build(); + .setName("Primary Divider Dim") + .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared") + .build(); mSecondaryDim = new SurfaceControl.Builder(mSurfaceSession) .setParent(mSecondarySurface).setColorLayer() - .setName("Secondary Divider Dim").build(); + .setName("Secondary Divider Dim") + .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared") + .build(); SurfaceControl.Transaction t = getTransaction(); t.setLayer(mPrimaryDim, Integer.MAX_VALUE); t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f}); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java index 00419e671814..7f3516194298 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java @@ -74,7 +74,8 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC protected boolean mPowerSave; private boolean mAodPowerSave; private boolean mTestmode = false; - private boolean mHasReceivedBattery = false; + @VisibleForTesting + boolean mHasReceivedBattery = false; private Estimate mEstimate; private boolean mFetchingEstimate = false; @@ -102,6 +103,16 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC @Override public void init() { registerReceiver(); + if (!mHasReceivedBattery) { + // Get initial state. Relying on Sticky behavior until API for getting info. + Intent intent = mContext.registerReceiver( + null, + new IntentFilter(Intent.ACTION_BATTERY_CHANGED) + ); + if (intent != null && !mHasReceivedBattery) { + onReceive(mContext, intent); + } + } updatePowerSave(); updateEstimate(); } diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java index bc2a55c8d5c4..7561af770298 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java @@ -139,13 +139,18 @@ public class UsbDebuggingActivity extends AlertActivity if (mDisconnectedReceiver != null) { mBroadcastDispatcher.unregisterReceiver(mDisconnectedReceiver); } + super.onStop(); + } + + @Override + protected void onDestroy() { // If the ADB service has not yet been notified due to this dialog being closed in some // other way then notify the service to deny the connection to ensure system_server sends // a response to adbd. if (!mServiceNotified) { notifyService(false); } - super.onStop(); + super.onDestroy(); } @Override diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml index 9c94b8693b9f..65e5baa7926a 100644 --- a/packages/SystemUI/tests/AndroidManifest.xml +++ b/packages/SystemUI/tests/AndroidManifest.xml @@ -74,6 +74,11 @@ android:excludeFromRecents="true" android:exported="false" /> + <activity android:name="com.android.systemui.controls.management.TestControlsRequestDialog" + android:exported="false" + android:excludeFromRecents="true" + /> + <provider android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer" tools:replace="android:authorities" diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 7bc453ac9aa1..9e056cf16ec7 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -211,6 +211,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } @Test + public void testInitialBatteryLevelRequested() { + mTestableLooper.processAllMessages(); + + assertThat(mKeyguardUpdateMonitor.mBatteryStatus).isNotNull(); + } + + @Test public void testReceiversRegistered() { verify(mBroadcastDispatcher, atLeastOnce()).registerReceiverWithHandler( eq(mKeyguardUpdateMonitor.mBroadcastReceiver), diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java index 95ff98ae620b..f29f04244901 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java +++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java @@ -67,27 +67,35 @@ public class SysuiTestableContext extends TestableContext { @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { - mRegisteredReceivers.add(receiver); + if (receiver != null) { + mRegisteredReceivers.add(receiver); + } return super.registerReceiver(receiver, filter); } @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { - mRegisteredReceivers.add(receiver); + if (receiver != null) { + mRegisteredReceivers.add(receiver); + } return super.registerReceiver(receiver, filter, broadcastPermission, scheduler); } @Override public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler) { - mRegisteredReceivers.add(receiver); + if (receiver != null) { + mRegisteredReceivers.add(receiver); + } return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission, scheduler); } @Override public void unregisterReceiver(BroadcastReceiver receiver) { - mRegisteredReceivers.remove(receiver); + if (receiver != null) { + mRegisteredReceivers.remove(receiver); + } super.unregisterReceiver(receiver); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt new file mode 100644 index 000000000000..0122db6c4965 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt @@ -0,0 +1,145 @@ +/* + * 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.systemui.controls.management + +import android.app.Dialog +import android.app.PendingIntent +import android.content.ComponentName +import android.content.IIntentSender +import android.content.Intent +import android.os.UserHandle +import android.service.controls.Control +import android.service.controls.ControlsProviderService +import android.service.controls.DeviceTypes +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.lifecycle.Lifecycle +import androidx.test.filters.MediumTest +import androidx.test.rule.ActivityTestRule +import androidx.test.runner.intercepting.SingleActivityFactory +import com.android.systemui.SysuiTestCase +import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.controls.controller.ControlInfo +import com.android.systemui.controls.controller.ControlsController +import com.android.systemui.util.mockito.capture +import com.android.systemui.util.mockito.eq +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotEquals +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor +import org.mockito.Captor +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@MediumTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper +class ControlsRequestDialogTest : SysuiTestCase() { + + companion object { + private val CONTROL_COMPONENT = ComponentName.unflattenFromString("TEST_PKG/.TEST_CLS")!! + private const val LABEL = "TEST_LABEL" + + private val USER_ID = UserHandle.USER_SYSTEM + private const val CONTROL_ID = "id" + } + + @Mock + private lateinit var controller: ControlsController + + @Mock + private lateinit var listingController: ControlsListingController + @Mock + private lateinit var broadcastDispatcher: BroadcastDispatcher + @Mock + private lateinit var iIntentSender: IIntentSender + @Captor + private lateinit var captor: ArgumentCaptor<ControlInfo> + + @Rule + @JvmField + var activityRule = ActivityTestRule<TestControlsRequestDialog>( + object : SingleActivityFactory<TestControlsRequestDialog>( + TestControlsRequestDialog::class.java + ) { + override fun create(intent: Intent?): TestControlsRequestDialog { + return TestControlsRequestDialog( + controller, + broadcastDispatcher, + listingController + ) + } + }, false, false) + + private lateinit var control: Control + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + control = Control.StatelessBuilder(CONTROL_ID, PendingIntent(iIntentSender)) + .setTitle("TITLE") + .setSubtitle("SUBTITLE") + .setDeviceType(DeviceTypes.TYPE_LIGHT) + .setStructure("STRUCTURE") + .build() + + val intent = Intent(mContext, TestControlsRequestDialog::class.java) + intent.putExtra(Intent.EXTRA_USER_ID, USER_ID) + intent.putExtra(Intent.EXTRA_COMPONENT_NAME, CONTROL_COMPONENT) + intent.putExtra(ControlsProviderService.EXTRA_CONTROL, control) + + `when`(controller.currentUserId).thenReturn(USER_ID) + `when`(controller.available).thenReturn(true) + `when`(listingController.getAppLabel(CONTROL_COMPONENT)).thenReturn(LABEL) + `when`(controller.getFavoritesForComponent(CONTROL_COMPONENT)).thenReturn(emptyList()) + + activityRule.launchActivity(intent) + } + + @After + fun tearDown() { + activityRule.finishActivity() + } + + @Test + fun testActivityNotFinished() { + assertNotEquals(Lifecycle.State.DESTROYED, + activityRule.getActivity().lifecycle.currentState) + } + + @Test + fun testDialogAddsCorrectControl() { + activityRule.activity.onClick(null, Dialog.BUTTON_POSITIVE) + + verify(controller) + .addFavorite(eq(CONTROL_COMPONENT), eq(control.structure!!), capture(captor)) + + captor.value.let { + assertEquals(control.controlId, it.controlId) + assertEquals(control.title, it.controlTitle) + assertEquals(control.subtitle, it.controlSubtitle) + assertEquals(control.deviceType, it.deviceType) + } + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt new file mode 100644 index 000000000000..3f6308b18d03 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt @@ -0,0 +1,26 @@ +/* + * 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.systemui.controls.management + +import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.controls.controller.ControlsController + +class TestControlsRequestDialog( + controller: ControlsController, + dispatcher: BroadcastDispatcher, + listingController: ControlsListingController +) : ControlsRequestDialog(controller, dispatcher, listingController)
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java index f83fbd478bf3..eca48c8c2ee1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java @@ -59,6 +59,11 @@ public class BatteryControllerTest extends SysuiTestCase { } @Test + public void testBatteryInitialized() { + Assert.assertTrue(mBatteryController.mHasReceivedBattery); + } + + @Test public void testIndependentAODBatterySaver_true() { PowerSaveState state = new PowerSaveState.Builder() .setBatterySaverEnabled(true) diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index df3b6880fdfb..ed83a644cbfb 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -878,6 +878,7 @@ public class AdbDebuggingManager { case MESSAGE_ADB_DENY: if (mThread != null) { + Slog.w(TAG, "Denying adb confirmation"); mThread.sendResponse("NO"); logAdbConnectionChanged(null, AdbProtoEnums.USER_DENIED, false); } @@ -887,7 +888,7 @@ public class AdbDebuggingManager { String key = (String) msg.obj; if ("trigger_restart_min_framework".equals( SystemProperties.get("vold.decrypt"))) { - Slog.d(TAG, "Deferring adb confirmation until after vold decrypt"); + Slog.w(TAG, "Deferring adb confirmation until after vold decrypt"); if (mThread != null) { mThread.sendResponse("NO"); logAdbConnectionChanged(key, AdbProtoEnums.DENIED_VOLD_DECRYPT, false); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index e77b361c8c06..c9dbacda368c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -8086,6 +8086,12 @@ public class ActivityManagerService extends IActivityManager.Stub } int checkContentProviderUriPermission(Uri uri, int userId, int callingUid, int modeFlags) { + if (Thread.holdsLock(mActivityTaskManager.getGlobalLock())) { + Slog.wtf(TAG, new IllegalStateException("Unable to check Uri permission" + + " because caller is holding WM lock; assuming permission denied")); + return PackageManager.PERMISSION_DENIED; + } + final String name = uri.getAuthority(); final long ident = Binder.clearCallingIdentity(); ContentProviderHolder holder = null; diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java index 29026e8affcf..ec2b0c0a6830 100644 --- a/services/core/java/com/android/server/display/ColorFade.java +++ b/services/core/java/com/android/server/display/ColorFade.java @@ -588,8 +588,9 @@ final class ColorFade { if (mSurfaceControl == null) { Transaction t = new Transaction(); try { - final SurfaceControl.Builder builder = - new SurfaceControl.Builder(mSurfaceSession).setName("ColorFade"); + final SurfaceControl.Builder builder = new SurfaceControl.Builder(mSurfaceSession) + .setName("ColorFade") + .setCallsite("ColorFade.createSurface"); if (mMode == MODE_FADE) { builder.setColorLayer(); } else { diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 9bc702d4c094..ca5e38df066e 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -892,6 +892,7 @@ final class AccessibilityController { .setName(SURFACE_TITLE) .setBufferSize(mTempPoint.x, mTempPoint.y) // not a typo .setFormat(PixelFormat.TRANSLUCENT) + .setCallsite("ViewportWindow") .build(); } catch (OutOfResourcesException oore) { /* ignore */ diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 2a68a194b369..c4663ca19f87 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -5908,7 +5908,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ProtoLog.i(WM_DEBUG_APP_TRANSITIONS_ANIM, "Creating animation bounds layer"); final SurfaceControl.Builder builder = makeAnimationLeash() .setParent(getAnimationLeashParent()) - .setName(getSurfaceControl() + " - animation-bounds"); + .setName(getSurfaceControl() + " - animation-bounds") + .setCallsite("ActivityRecord.createAnimationBoundsLayer"); final SurfaceControl boundsLayer = builder.build(); t.show(boundsLayer); return boundsLayer; diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 31712ef85add..b3786212ea72 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -640,13 +640,10 @@ class ActivityStarter { } // If the caller hasn't already resolved the activity, we're willing - // to do so here, but because that may require acquiring the AM lock - // as part of calculating the NeededUriGrants, we must never hold - // the WM lock here to avoid deadlocking. + // to do so here. If the caller is already holding the WM lock here, + // and we need to check dynamic Uri permissions, then we're forced + // to assume those permissions are denied to avoid deadlocking. if (mRequest.activityInfo == null) { - if (Thread.holdsLock(mService.mGlobalLock)) { - Slog.wtf(TAG, new IllegalStateException("Caller must not hold WM lock")); - } mRequest.resolveActivity(mSupervisor); } diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java index 8ab17950f4fc..f563e57b363e 100644 --- a/services/core/java/com/android/server/wm/BlackFrame.java +++ b/services/core/java/com/android/server/wm/BlackFrame.java @@ -50,6 +50,7 @@ public class BlackFrame { .setName("BlackSurface") .setColorLayer() .setParent(surfaceControl) + .setCallsite("BlackSurface") .build(); transaction.setWindowCrop(surface, w, h); transaction.setAlpha(surface, 1); diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java index d43a7b87ee35..07729d17d7b2 100644 --- a/services/core/java/com/android/server/wm/Dimmer.java +++ b/services/core/java/com/android/server/wm/Dimmer.java @@ -175,6 +175,7 @@ class Dimmer { .setParent(mHost.getSurfaceControl()) .setColorLayer() .setName("Dim Layer for - " + mHost.getName()) + .setCallsite("Dimmer.makeDimLayer") .build(); } diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java index b6c71bb17631..9a397fe07f4e 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java +++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java @@ -114,7 +114,8 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) { try { - SurfaceControl outSurfaceControl = new SurfaceControl(da.getSurfaceControl()); + SurfaceControl outSurfaceControl = new SurfaceControl(da.getSurfaceControl(), + "DisplayAreaOrganizerController.onDisplayAreaAppeared"); organizer.onDisplayAreaAppeared(da.getDisplayAreaInfo(), outSurfaceControl); } catch (RemoteException e) { // Oh well... diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 0b8716a8aa40..241de2e0e068 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -987,7 +987,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(mSession) .setOpaque(true) .setContainerLayer(); - mSurfaceControl = b.setName("Root").setContainerLayer().build(); + mSurfaceControl = b.setName("Root") + .setContainerLayer() + .setCallsite("DisplayContent") + .build(); getPendingTransaction() .setLayer(mSurfaceControl, 0) @@ -1110,7 +1113,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return null; } mShellRoots.put(windowType, root); - SurfaceControl out = new SurfaceControl(rootLeash); + SurfaceControl out = new SurfaceControl(rootLeash, "DisplayContent.addShellRoot"); return out; } diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index a26dfdb1bcd4..f840d9273f60 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -152,7 +152,9 @@ class DragState { mInputSurface = mService.makeSurfaceBuilder( mService.mRoot.getDisplayContent(mDisplayContent.getDisplayId()).getSession()) .setContainerLayer() - .setName("Drag and Drop Input Consumer").build(); + .setName("Drag and Drop Input Consumer") + .setCallsite("DragState.showInputSurface") + .build(); } final InputWindowHandle h = getInputWindowHandle(); if (h == null) { diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java index c9cc94423fe2..724747daaa5b 100644 --- a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java +++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java @@ -62,6 +62,7 @@ class EmulatorDisplayOverlay { .setName("EmulatorDisplayOverlay") .setBufferSize(mScreenSize.x, mScreenSize.y) .setFormat(PixelFormat.TRANSLUCENT) + .setCallsite("EmulatorDisplayOverlay") .build(); t.setLayer(ctrl, zOrder); t.setPosition(ctrl, 0, 0); diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java index a6066684d850..3b39b6ba18c5 100644 --- a/services/core/java/com/android/server/wm/InputConsumerImpl.java +++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java @@ -89,8 +89,10 @@ class InputConsumerImpl implements IBinder.DeathRecipient { mWindowHandle.inputFeatures = 0; mWindowHandle.scaleFactor = 1.0f; - mInputSurface = mService.makeSurfaceBuilder(mService.mRoot.getDisplayContent(displayId) - .getSession()).setContainerLayer().setName("Input Consumer " + name) + mInputSurface = mService.makeSurfaceBuilder(mService.mRoot.getDisplayContent(displayId).getSession()) + .setContainerLayer() + .setName("Input Consumer " + name) + .setCallsite("InputConsumerImpl") .build(); } diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java index 00a4be3d1e35..5d1c85dfc7a3 100644 --- a/services/core/java/com/android/server/wm/Letterbox.java +++ b/services/core/java/com/android/server/wm/Letterbox.java @@ -261,8 +261,12 @@ public class Letterbox { } private void createSurface(SurfaceControl.Transaction t) { - mSurface = mSurfaceControlFactory.get().setName("Letterbox - " + mType) - .setFlags(HIDDEN).setColorLayer().build(); + mSurface = mSurfaceControlFactory.get() + .setName("Letterbox - " + mType) + .setFlags(HIDDEN) + .setColorLayer() + .setCallsite("LetterboxSurface.createSurface") + .build(); t.setLayer(mSurface, -1) .setColor(mSurface, new float[]{0, 0, 0}) .setColorSpaceAgnostic(mSurface, true); diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index 14ab2e364a1b..c34956c13fae 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -188,17 +188,20 @@ class ScreenRotationAnimation { mBackColorSurface = displayContent.makeChildSurface(null) .setName("BackColorSurface") .setColorLayer() + .setCallsite("ScreenRotationAnimation") .build(); mScreenshotLayer = displayContent.makeOverlay() .setName("RotationLayer") .setBufferSize(mWidth, mHeight) .setSecure(isSecure) + .setCallsite("ScreenRotationAnimation") .build(); mEnterBlackFrameLayer = displayContent.makeOverlay() .setName("EnterBlackFrameLayer") .setContainerLayer() + .setCallsite("ScreenRotationAnimation") .build(); // In case display bounds change, screenshot buffer and surface may mismatch so set a diff --git a/services/core/java/com/android/server/wm/ShellRoot.java b/services/core/java/com/android/server/wm/ShellRoot.java index 0ae9ca9b882e..759f341c0fe0 100644 --- a/services/core/java/com/android/server/wm/ShellRoot.java +++ b/services/core/java/com/android/server/wm/ShellRoot.java @@ -60,7 +60,10 @@ public class ShellRoot { mToken = new WindowToken( dc.mWmService, client.asBinder(), windowType, true, dc, true, false); mSurfaceControl = mToken.makeChildSurface(null) - .setContainerLayer().setName("Shell Root Leash " + dc.getDisplayId()).build(); + .setContainerLayer() + .setName("Shell Root Leash " + dc.getDisplayId()) + .setCallsite("ShellRoot") + .build(); mToken.getPendingTransaction().show(mSurfaceControl); } diff --git a/services/core/java/com/android/server/wm/StrictModeFlash.java b/services/core/java/com/android/server/wm/StrictModeFlash.java index fa62daaff3fc..39ac16a2f5d3 100644 --- a/services/core/java/com/android/server/wm/StrictModeFlash.java +++ b/services/core/java/com/android/server/wm/StrictModeFlash.java @@ -48,6 +48,7 @@ class StrictModeFlash { .setName("StrictModeFlash") .setBufferSize(1, 1) .setFormat(PixelFormat.TRANSLUCENT) + .setCallsite("StrictModeFlash") .build(); // one more than Watermark? arbitrary. diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 0e5d7d910084..33935d61ead2 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -395,7 +395,8 @@ class SurfaceAnimator { // doesn't work, you will can see the 2/3 button nav bar flicker during seamless // rotation. .setHidden(hidden) - .setEffectLayer(); + .setEffectLayer() + .setCallsite("SurfaceAnimator.createAnimationLeash"); final SurfaceControl leash = builder.build(); t.setWindowCrop(leash, width, height); t.setPosition(leash, x, y); diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java index 8ab5043dc5d9..efa439169c5e 100644 --- a/services/core/java/com/android/server/wm/SurfaceFreezer.java +++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java @@ -162,6 +162,7 @@ class SurfaceFreezer { .setBufferSize(width, height) .setFormat(PixelFormat.TRANSLUCENT) .setParent(parent) + .setCallsite("SurfaceFreezer.Snapshot") .build(); ProtoLog.i(WM_SHOW_TRANSACTIONS, " THUMBNAIL %s: CREATE", mSurfaceControl); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index a7b120942163..748244e1a5c2 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -4515,6 +4515,7 @@ class Task extends WindowContainer<WindowContainer> { */ void setMainWindowSizeChangeTransaction(SurfaceControl.Transaction t) { setMainWindowSizeChangeTransaction(t, this); + forAllWindows(WindowState::requestRedrawForSync, true); } private void setMainWindowSizeChangeTransaction(SurfaceControl.Transaction t, Task origin) { diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index e23080724000..3360951a8f3f 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -689,15 +689,19 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { super.onParentChanged(newParent, oldParent, () -> { mAppAnimationLayer = makeChildSurface(null) .setName("animationLayer") + .setCallsite("TaskDisplayArea.onParentChanged") .build(); mBoostedAppAnimationLayer = makeChildSurface(null) .setName("boostedAnimationLayer") + .setCallsite("TaskDisplayArea.onParentChanged") .build(); mHomeAppAnimationLayer = makeChildSurface(null) .setName("homeAnimationLayer") + .setCallsite("TaskDisplayArea.onParentChanged") .build(); mSplitScreenDividerAnchor = makeChildSurface(null) .setName("splitScreenDividerAnchor") + .setCallsite("TaskDisplayArea.onParentChanged") .build(); getSyncTransaction() .show(mAppAnimationLayer) diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 574f37b87443..f70bf18cdea5 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -117,7 +117,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { final RunningTaskInfo taskInfo = task.getTaskInfo(); mDeferTaskOrgCallbacksConsumer.accept(() -> { try { - SurfaceControl outSurfaceControl = new SurfaceControl(task.getSurfaceControl()); + SurfaceControl outSurfaceControl = new SurfaceControl(task.getSurfaceControl(), + "TaskOrganizerController.onTaskAppeared"); if (!task.mCreatedByOrganizer && !visible) { // To prevent flashes, we hide the task prior to sending the leash to the // task org if the task has previously hidden (ie. when entering PIP) diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java index d343daf46f13..b9a449f558f0 100644 --- a/services/core/java/com/android/server/wm/TaskPositioningController.java +++ b/services/core/java/com/android/server/wm/TaskPositioningController.java @@ -86,7 +86,9 @@ class TaskPositioningController { if (mInputSurface == null) { mInputSurface = mService.makeSurfaceBuilder(dc.getSession()) .setContainerLayer() - .setName("Drag and Drop Input Consumer").build(); + .setName("Drag and Drop Input Consumer") + .setCallsite("TaskPositioningController.showInputSurface") + .build(); } final InputWindowHandle h = getDragWindowHandleLocked(); diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java index adecc36671c9..23f55051af90 100644 --- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java +++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java @@ -52,6 +52,7 @@ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable { mSurfaceControl = surfaceControlFactory.apply(new SurfaceSession()) .setName("RecentTaskScreenshotSurface") .setBufferSize(mWidth, mHeight) + .setCallsite("TaskScreenshotAnimatable") .build(); if (buffer != null) { final Surface surface = new Surface(); diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index f1f576220a9a..3fc09c93550c 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -374,6 +374,7 @@ class TaskSnapshotSurface implements StartingSurface { .setBufferSize(buffer.getWidth(), buffer.getHeight()) .setFormat(buffer.getFormat()) .setParent(mSurfaceControl) + .setCallsite("TaskSnapshotSurface.drawSizeMismatchSnapshot") .build(); Surface surface = mService.mSurfaceFactory.get(); surface.copyFrom(mChildSurfaceControl); diff --git a/services/core/java/com/android/server/wm/Watermark.java b/services/core/java/com/android/server/wm/Watermark.java index 3d49ebe306e6..7f28ffc5634c 100644 --- a/services/core/java/com/android/server/wm/Watermark.java +++ b/services/core/java/com/android/server/wm/Watermark.java @@ -121,6 +121,7 @@ class Watermark { .setName("WatermarkSurface") .setBufferSize(1, 1) .setFormat(PixelFormat.TRANSLUCENT) + .setCallsite("Watermark") .build(); t.setLayer(ctrl, WindowManagerService.TYPE_LAYER_MULTIPLIER * 100) .setPosition(ctrl, 0, 0) diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 1a6d85547c92..2977968f5754 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -413,7 +413,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } void setInitialSurfaceControlProperties(SurfaceControl.Builder b) { - setSurfaceControl(b.build()); + setSurfaceControl(b.setCallsite("WindowContainer.setInitialSurfaceControlProperties").build()); getSyncTransaction().show(mSurfaceControl); onSurfaceShown(getSyncTransaction()); updateSurfacePosition(); diff --git a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java index 126154b10350..ee99f45b48ff 100644 --- a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java +++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java @@ -103,6 +103,7 @@ class WindowContainerThumbnail implements Animatable { .setFormat(PixelFormat.TRANSLUCENT) .setMetadata(METADATA_WINDOW_TYPE, mWindowContainer.getWindowingMode()) .setMetadata(METADATA_OWNER_UID, Process.myUid()) + .setCallsite("WindowContainerThumbnail") .build(); ProtoLog.i(WM_SHOW_TRANSACTIONS, " THUMBNAIL %s: CREATE", mSurfaceControl); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 564eecf725cc..b1756b07ad83 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -8229,7 +8229,7 @@ public class WindowManagerService extends IWindowManager.Stub } final SurfaceControl mirror = SurfaceControl.mirrorSurface(displaySc); - outSurfaceControl.copyFrom(mirror); + outSurfaceControl.copyFrom(mirror, "WMS.mirrorDisplay"); return true; } diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 46e1bf04bdbe..930bfded39a4 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -459,6 +459,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub .setBufferSize(bounds.width(), bounds.height()) .setFormat(PixelFormat.TRANSLUCENT) .setParent(wc.getParentSurfaceControl()) + .setCallsite("WindowOrganizerController.takeScreenshot") .build(); Surface surface = new Surface(); @@ -466,7 +467,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub surface.attachAndQueueBufferWithColorSpace(buffer.getGraphicBuffer(), null); surface.release(); - outSurfaceControl.copyFrom(screenshot); + outSurfaceControl.copyFrom(screenshot, "WindowOrganizerController.takeScreenshot"); return true; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 708abe28c806..f1acee5031d8 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -339,7 +339,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP private boolean mDragResizing; private boolean mDragResizingChangeReported = true; private int mResizeMode; - private boolean mResizeForBlastSyncReported; + private boolean mRedrawForSyncReported; /** * Special mode that is intended only for the rounded corner overlay: during rotation @@ -1402,7 +1402,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP || configChanged || dragResizingChanged || mReportOrientationChanged - || requestResizeForBlastSync()) { + || shouldSendRedrawForSync()) { ProtoLog.v(WM_DEBUG_RESIZE, "Resize reasons for w=%s: %s surfaceResized=%b configChanged=%b " + "dragResizingChanged=%b reportOrientationChanged=%b", @@ -3564,7 +3564,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mReportOrientationChanged = false; mDragResizingChangeReported = true; mWinAnimator.mSurfaceResized = false; - mResizeForBlastSyncReported = true; mWindowFrames.resetInsetsChanged(); final Rect frame = mWindowFrames.mCompatFrame; @@ -3572,11 +3571,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP final Rect visibleInsets = mWindowFrames.mLastVisibleInsets; final Rect stableInsets = mWindowFrames.mLastStableInsets; final MergedConfiguration mergedConfiguration = mLastReportedConfiguration; - final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING || useBLASTSync(); - final boolean forceRelayout = reportOrientation || isDragResizeChanged(); + final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING || useBLASTSync() || !mRedrawForSyncReported; + final boolean forceRelayout = reportOrientation || isDragResizeChanged() || !mRedrawForSyncReported; final int displayId = getDisplayId(); final DisplayCutout displayCutout = getWmDisplayCutout().getDisplayCutout(); + mRedrawForSyncReported = true; + try { mClient.resized(frame, contentInsets, visibleInsets, stableInsets, reportDraw, mergedConfiguration, getBackdropFrame(frame), forceRelayout, @@ -5823,7 +5824,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (!willSync) { return false; } - mResizeForBlastSyncReported = false; + requestRedrawForSync(); mLocalSyncId = mBLASTSyncEngine.startSyncSet(this); addChildrenToSyncSet(mLocalSyncId); @@ -5884,7 +5885,20 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP notifyBlastSyncTransaction(); } - private boolean requestResizeForBlastSync() { - return useBLASTSync() && !mResizeForBlastSyncReported; + /** + * When using the two WindowOrganizer sync-primitives (BoundsChangeTransaction, BLASTSync) + * it can be a little difficult to predict whether your change will actually trigger redrawing + * on the client side. To ease the burden on shell developers, we force send MSG_RESIZED + * for Windows involved in these Syncs + */ + private boolean shouldSendRedrawForSync() { + final Task task = getTask(); + if (task != null && task.getMainWindowSizeChangeTransaction() != null) + return !mRedrawForSyncReported; + return useBLASTSync() && !mRedrawForSyncReported; + } + + void requestRedrawForSync() { + mRedrawForSyncReported = false; } } diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index b2bfcdc8a900..b89cdd32e132 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -116,7 +116,8 @@ class WindowSurfaceController { .setFormat(format) .setFlags(flags) .setMetadata(METADATA_WINDOW_TYPE, windowType) - .setMetadata(METADATA_OWNER_UID, ownerUid); + .setMetadata(METADATA_OWNER_UID, ownerUid) + .setCallsite("WindowSurfaceController"); final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0); @@ -132,6 +133,7 @@ class WindowSurfaceController { .setName(name + "(BLAST)") .setHidden(false) .setBLASTLayer() + .setCallsite("WindowSurfaceController") .build(); } @@ -493,12 +495,12 @@ class WindowSurfaceController { } void getSurfaceControl(SurfaceControl outSurfaceControl) { - outSurfaceControl.copyFrom(mSurfaceControl); + outSurfaceControl.copyFrom(mSurfaceControl, "WindowSurfaceController.getSurfaceControl"); } void getBLASTSurfaceControl(SurfaceControl outSurfaceControl) { if (mBLASTSurfaceControl != null) { - outSurfaceControl.copyFrom(mBLASTSurfaceControl); + outSurfaceControl.copyFrom(mBLASTSurfaceControl, "WindowSurfaceController.getBLASTSurfaceControl"); } } diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowCloseGuard.java b/services/robotests/src/com/android/server/testing/shadows/ShadowCloseGuard.java index c9984bf07059..4055dfc08f90 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowCloseGuard.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowCloseGuard.java @@ -44,5 +44,10 @@ public class ShadowCloseGuard { public void report(String message, Throwable allocationSite) { mReports += 1; } + + @Override + public void report(String message) { + mReports += 1; + } } } diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java index 2251ee047d29..ce3f270460c1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java @@ -18,6 +18,7 @@ package com.android.server.wm; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; diff --git a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java b/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java index 6b194550cc11..67e1b440e28a 100644 --- a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java +++ b/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java @@ -120,7 +120,7 @@ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { return; } - Log.i(TAG, String.format("Transition from %s to %s", state, State.INTENT_STARTED)); + Log.d(TAG, String.format("Transition from %s to %s", state, State.INTENT_STARTED)); state = State.INTENT_STARTED; } @@ -138,7 +138,7 @@ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { return; } - Log.i(TAG, String.format("Transition from %s to %s", state, State.INTENT_FAILED)); + Log.d(TAG, String.format("Transition from %s to %s", state, State.INTENT_FAILED)); state = State.INTENT_FAILED; } @@ -156,7 +156,7 @@ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { return; } - Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_LAUNCHED)); + Log.d(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_LAUNCHED)); state = State.ACTIVITY_LAUNCHED; } @@ -174,7 +174,7 @@ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { return; } - Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_CANCELLED)); + Log.d(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_CANCELLED)); state = State.ACTIVITY_CANCELLED; } @@ -194,7 +194,7 @@ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { return; } - Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_FINISHED)); + Log.d(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_FINISHED)); state = State.ACTIVITY_FINISHED; } @@ -215,7 +215,7 @@ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { return; } - Log.i(TAG, String.format("Transition from %s to %s", state, State.REPORT_FULLY_DRAWN)); + Log.d(TAG, String.format("Transition from %s to %s", state, State.REPORT_FULLY_DRAWN)); state = State.REPORT_FULLY_DRAWN; } @@ -238,7 +238,7 @@ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { state = State.UNKNOWN; } ++accIntentStartedEvents; - Log.i(TAG, + Log.d(TAG, String.format("inc AccIntentStartedEvents to %d", accIntentStartedEvents)); } @@ -250,7 +250,7 @@ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { state = State.INIT; } --accIntentStartedEvents; - Log.i(TAG, + Log.d(TAG, String.format("dec AccIntentStartedEvents to %d", accIntentStartedEvents)); } @@ -258,6 +258,6 @@ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); new Throwable("EventSequenceValidator#getStackTrace").printStackTrace(pw); - Log.w(TAG, String.format("%s\n%s", log, sw)); + Log.d(TAG, String.format("%s\n%s", log, sw)); } } |