summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java7
-rw-r--r--api/test-current.txt2
-rw-r--r--cmds/statsd/src/anomaly/AlarmTracker.cpp4
-rw-r--r--cmds/statsd/src/atoms.proto4
-rw-r--r--cmds/statsd/tests/anomaly/AlarmTracker_test.cpp30
-rw-r--r--core/java/android/hardware/biometrics/BiometricManager.java6
-rw-r--r--core/java/android/os/StrictMode.java7
-rw-r--r--core/java/android/os/strictmode/LeakedClosableViolation.java5
-rw-r--r--core/java/android/view/InsetsSourceControl.java2
-rw-r--r--core/java/android/view/SurfaceControl.java42
-rw-r--r--core/java/android/view/SurfaceControlViewHost.java7
-rw-r--r--core/java/android/view/SurfaceView.java2
-rw-r--r--core/java/android/view/View.java1
-rw-r--r--core/java/android/view/ViewRootImpl.java1
-rw-r--r--core/java/android/view/WindowlessWindowManager.java5
-rw-r--r--core/java/android/widget/Magnifier.java1
-rw-r--r--core/java/android/window/TaskEmbedder.java1
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java33
-rw-r--r--core/java/com/android/internal/app/ChooserListAdapter.java1
-rw-r--r--core/tests/coretests/src/android/view/InsetsControllerTest.java2
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java64
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java7
-rw-r--r--data/etc/Android.bp8
-rw-r--r--data/etc/com.android.cellbroadcastreceiver.xml26
-rw-r--r--packages/SystemUI/res/layout/media_view.xml19
-rw-r--r--packages/SystemUI/res/values/dimens.xml5
-rw-r--r--packages/SystemUI/res/xml/media_collapsed.xml10
-rw-r--r--packages/SystemUI/res/xml/media_expanded.xml10
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerUI.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java7
-rw-r--r--packages/SystemUI/tests/AndroidManifest.xml5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt145
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt26
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java5
-rw-r--r--services/core/java/com/android/server/adb/AdbDebuggingManager.java3
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java6
-rw-r--r--services/core/java/com/android/server/display/ColorFade.java5
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java1
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java9
-rw-r--r--services/core/java/com/android/server/wm/BlackFrame.java1
-rw-r--r--services/core/java/com/android/server/wm/Dimmer.java1
-rw-r--r--services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java3
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java7
-rw-r--r--services/core/java/com/android/server/wm/DragState.java4
-rw-r--r--services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java1
-rw-r--r--services/core/java/com/android/server/wm/InputConsumerImpl.java6
-rw-r--r--services/core/java/com/android/server/wm/Letterbox.java8
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java3
-rw-r--r--services/core/java/com/android/server/wm/ShellRoot.java5
-rw-r--r--services/core/java/com/android/server/wm/StrictModeFlash.java1
-rw-r--r--services/core/java/com/android/server/wm/SurfaceAnimator.java3
-rw-r--r--services/core/java/com/android/server/wm/SurfaceFreezer.java1
-rw-r--r--services/core/java/com/android/server/wm/Task.java1
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java4
-rw-r--r--services/core/java/com/android/server/wm/TaskOrganizerController.java3
-rw-r--r--services/core/java/com/android/server/wm/TaskPositioningController.java4
-rw-r--r--services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java1
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotSurface.java1
-rw-r--r--services/core/java/com/android/server/wm/Watermark.java1
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowContainerThumbnail.java1
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java30
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java8
-rw-r--r--services/robotests/src/com/android/server/testing/shadows/ShadowCloseGuard.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java1
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java18
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));
}
}