summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/Notification.java39
-rw-r--r--core/java/android/content/pm/TEST_MAPPING28
-rw-r--r--core/java/android/hardware/usb/OWNERS4
-rw-r--r--core/java/android/hardware/usb/UsbConfiguration.java3
-rw-r--r--core/java/android/os/PersistableBundle.java42
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java48
-rw-r--r--packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java25
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt97
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java71
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java5
-rw-r--r--services/core/java/com/android/server/PendingIntentUtils.java1
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java23
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java14
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java2
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java22
-rw-r--r--services/core/java/com/android/server/pm/TEST_MAPPING6
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java26
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java8
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerTests.java4
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java43
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java10
-rw-r--r--services/usb/OWNERS4
32 files changed, 532 insertions, 77 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index a0fe6c504932..c60c66614a8b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2850,18 +2850,14 @@ public class Notification implements Parcelable
visitor.accept(Uri.parse(extras.getString(EXTRA_BACKGROUND_IMAGE_URI)));
}
- ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST);
+ ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST,
+ Person.class);
if (people != null && !people.isEmpty()) {
for (Person p : people) {
visitor.accept(p.getIconUri());
}
}
- final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON, Person.class);
- if (person != null) {
- visitor.accept(person.getIconUri());
- }
-
final RemoteInputHistoryItem[] history = extras.getParcelableArray(
Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS,
RemoteInputHistoryItem.class);
@@ -2873,10 +2869,16 @@ public class Notification implements Parcelable
}
}
}
- }
- if (isStyle(MessagingStyle.class) && extras != null) {
- final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES);
+ // Extras for MessagingStyle. We visit them even if not isStyle(MessagingStyle), since
+ // Notification Listeners might use directly (without the isStyle check).
+ final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON, Person.class);
+ if (person != null) {
+ visitor.accept(person.getIconUri());
+ }
+
+ final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES,
+ Parcelable.class);
if (!ArrayUtils.isEmpty(messages)) {
for (MessagingStyle.Message message : MessagingStyle.Message
.getMessagesFromBundleArray(messages)) {
@@ -2889,7 +2891,8 @@ public class Notification implements Parcelable
}
}
- final Parcelable[] historic = extras.getParcelableArray(EXTRA_HISTORIC_MESSAGES);
+ final Parcelable[] historic = extras.getParcelableArray(EXTRA_HISTORIC_MESSAGES,
+ Parcelable.class);
if (!ArrayUtils.isEmpty(historic)) {
for (MessagingStyle.Message message : MessagingStyle.Message
.getMessagesFromBundleArray(historic)) {
@@ -2902,15 +2905,14 @@ public class Notification implements Parcelable
}
}
- visitIconUri(visitor, extras.getParcelable(EXTRA_CONVERSATION_ICON));
- }
+ visitIconUri(visitor, extras.getParcelable(EXTRA_CONVERSATION_ICON, Icon.class));
- if (isStyle(CallStyle.class) & extras != null) {
- Person callPerson = extras.getParcelable(EXTRA_CALL_PERSON);
+ // Extras for CallStyle (same reason for visiting without checking isStyle).
+ Person callPerson = extras.getParcelable(EXTRA_CALL_PERSON, Person.class);
if (callPerson != null) {
visitor.accept(callPerson.getIconUri());
}
- visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON));
+ visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON, Icon.class));
}
if (mBubbleMetadata != null) {
@@ -3413,8 +3415,11 @@ public class Notification implements Parcelable
*
* @hide
*/
- public void setAllowlistToken(@Nullable IBinder token) {
- mAllowlistToken = token;
+ public void clearAllowlistToken() {
+ mAllowlistToken = null;
+ if (publicVersion != null) {
+ publicVersion.clearAllowlistToken();
+ }
}
/**
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index 1c1f58a19abc..187a21e45331 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -53,20 +53,6 @@
],
"presubmit-large": [
{
- "name": "CtsContentTestCases",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
- {
- "include-filter": "android.content.pm.cts"
- }
- ]
- },
- {
"name": "CtsUsesNativeLibraryTest",
"options": [
{
@@ -152,6 +138,20 @@
],
"postsubmit": [
{
+ "name": "CtsContentTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.pm.cts"
+ }
+ ]
+ },
+ {
"name": "CtsAppSecurityHostTestCases",
"options": [
{
diff --git a/core/java/android/hardware/usb/OWNERS b/core/java/android/hardware/usb/OWNERS
index 8f5c2a025672..a753f9634d0d 100644
--- a/core/java/android/hardware/usb/OWNERS
+++ b/core/java/android/hardware/usb/OWNERS
@@ -1,3 +1,7 @@
# Bug component: 175220
+aprasath@google.com
+kumarashishg@google.com
+sarup@google.com
+anothermark@google.com
badhri@google.com
diff --git a/core/java/android/hardware/usb/UsbConfiguration.java b/core/java/android/hardware/usb/UsbConfiguration.java
index 66269cb772f8..b25f47b11532 100644
--- a/core/java/android/hardware/usb/UsbConfiguration.java
+++ b/core/java/android/hardware/usb/UsbConfiguration.java
@@ -172,7 +172,8 @@ public class UsbConfiguration implements Parcelable {
String name = in.readString();
int attributes = in.readInt();
int maxPower = in.readInt();
- Parcelable[] interfaces = in.readParcelableArray(UsbInterface.class.getClassLoader());
+ Parcelable[] interfaces = in.readParcelableArray(
+ UsbInterface.class.getClassLoader(), UsbInterface.class);
UsbConfiguration configuration = new UsbConfiguration(id, name, attributes, maxPower);
configuration.setInterfaces(interfaces);
return configuration;
diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java
index f4edcb1317f4..acfd15cb005e 100644
--- a/core/java/android/os/PersistableBundle.java
+++ b/core/java/android/os/PersistableBundle.java
@@ -21,6 +21,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArrayMap;
+import android.util.Slog;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.Xml;
@@ -50,6 +51,8 @@ import java.util.ArrayList;
*/
public final class PersistableBundle extends BaseBundle implements Cloneable, Parcelable,
XmlUtils.WriteMapCallback {
+ private static final String TAG = "PersistableBundle";
+
private static final String TAG_PERSISTABLEMAP = "pbundle_as_map";
/** An unmodifiable {@code PersistableBundle} that is always {@link #isEmpty() empty}. */
@@ -118,7 +121,11 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
* @hide
*/
public PersistableBundle(Bundle b) {
- this(b.getItemwiseMap());
+ this(b, true);
+ }
+
+ private PersistableBundle(Bundle b, boolean throwException) {
+ this(b.getItemwiseMap(), throwException);
}
/**
@@ -127,7 +134,7 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
* @param map a Map containing only those items that can be persisted.
* @throws IllegalArgumentException if any element of #map cannot be persisted.
*/
- private PersistableBundle(ArrayMap<String, Object> map) {
+ private PersistableBundle(ArrayMap<String, Object> map, boolean throwException) {
super();
mFlags = FLAG_DEFUSABLE;
@@ -136,16 +143,23 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
// Now verify each item throwing an exception if there is a violation.
final int N = mMap.size();
- for (int i=0; i<N; i++) {
+ for (int i = N - 1; i >= 0; --i) {
Object value = mMap.valueAt(i);
if (value instanceof ArrayMap) {
// Fix up any Maps by replacing them with PersistableBundles.
- mMap.setValueAt(i, new PersistableBundle((ArrayMap<String, Object>) value));
+ mMap.setValueAt(i,
+ new PersistableBundle((ArrayMap<String, Object>) value, throwException));
} else if (value instanceof Bundle) {
- mMap.setValueAt(i, new PersistableBundle(((Bundle) value)));
+ mMap.setValueAt(i, new PersistableBundle((Bundle) value, throwException));
} else if (!isValidType(value)) {
- throw new IllegalArgumentException("Bad value in PersistableBundle key="
- + mMap.keyAt(i) + " value=" + value);
+ final String errorMsg = "Bad value in PersistableBundle key="
+ + mMap.keyAt(i) + " value=" + value;
+ if (throwException) {
+ throw new IllegalArgumentException(errorMsg);
+ } else {
+ Slog.wtfStack(TAG, errorMsg);
+ mMap.removeAt(i);
+ }
}
}
}
@@ -268,6 +282,15 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
/** @hide */
public void saveToXml(TypedXmlSerializer out) throws IOException, XmlPullParserException {
unparcel();
+ // Explicitly drop invalid types an attacker may have added before persisting.
+ for (int i = mMap.size() - 1; i >= 0; --i) {
+ final Object value = mMap.valueAt(i);
+ if (!isValidType(value)) {
+ Slog.e(TAG, "Dropping bad data before persisting: "
+ + mMap.keyAt(i) + "=" + value);
+ mMap.removeAt(i);
+ }
+ }
XmlUtils.writeMapXml(mMap, out, this);
}
@@ -322,9 +345,12 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
(event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
if (event == XmlPullParser.START_TAG) {
+ // Don't throw an exception when restoring from XML since an attacker could try to
+ // input invalid data in the persisted file.
return new PersistableBundle((ArrayMap<String, Object>)
XmlUtils.readThisArrayMapXml(in, startTag, tagName,
- new MyReadMapCallback()));
+ new MyReadMapCallback()),
+ /* throwException */ false);
}
}
return new PersistableBundle(); // An empty mutable PersistableBundle
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 84a559391343..34328dedaf8d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1928,6 +1928,9 @@ public class SettingsProvider extends ContentProvider {
cacheName = Settings.System.ALARM_ALERT_CACHE;
}
if (cacheName != null) {
+ if (!isValidAudioUri(name, value)) {
+ return false;
+ }
final File cacheFile = new File(
getRingtoneCacheDir(owningUserId), cacheName);
cacheFile.delete();
@@ -1960,6 +1963,34 @@ public class SettingsProvider extends ContentProvider {
}
}
+ private boolean isValidAudioUri(String name, String uri) {
+ if (uri != null) {
+ Uri audioUri = Uri.parse(uri);
+ if (Settings.AUTHORITY.equals(
+ ContentProvider.getAuthorityWithoutUserId(audioUri.getAuthority()))) {
+ // Don't accept setting the default uri to self-referential URIs like
+ // Settings.System.DEFAULT_RINGTONE_URI, which is an alias to the value of this
+ // setting.
+ return false;
+ }
+ final String mimeType = getContext().getContentResolver().getType(audioUri);
+ if (mimeType == null) {
+ Slog.e(LOG_TAG,
+ "mutateSystemSetting for setting: " + name + " URI: " + audioUri
+ + " ignored: failure to find mimeType (no access from this context?)");
+ return false;
+ }
+ if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg")
+ || mimeType.equals("application/x-flac"))) {
+ Slog.e(LOG_TAG,
+ "mutateSystemSetting for setting: " + name + " URI: " + audioUri
+ + " ignored: associated mimeType: " + mimeType + " is not an audio type");
+ return false;
+ }
+ }
+ return true;
+ }
+
private boolean hasWriteSecureSettingsPermission() {
// Write secure settings is a more protected permission. If caller has it we are good.
return getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
@@ -3101,6 +3132,15 @@ public class SettingsProvider extends ContentProvider {
return settingsState.getSettingLocked(name);
}
+ private boolean shouldExcludeSettingFromReset(Setting setting, String prefix) {
+ // If a prefix was specified, exclude settings whose names don't start with it.
+ if (prefix != null && !setting.getName().startsWith(prefix)) {
+ return true;
+ }
+ // Never reset SECURE_FRP_MODE, as it could be abused to bypass FRP via RescueParty.
+ return Secure.SECURE_FRP_MODE.equals(setting.getName());
+ }
+
public void resetSettingsLocked(int type, int userId, String packageName, int mode,
String tag) {
resetSettingsLocked(type, userId, packageName, mode, tag, /*prefix=*/
@@ -3123,7 +3163,7 @@ public class SettingsProvider extends ContentProvider {
Setting setting = settingsState.getSettingLocked(name);
if (packageName.equals(setting.getPackageName())) {
if ((tag != null && !tag.equals(setting.getTag()))
- || (prefix != null && !setting.getName().startsWith(prefix))) {
+ || shouldExcludeSettingFromReset(setting, prefix)) {
continue;
}
if (settingsState.resetSettingLocked(name)) {
@@ -3143,7 +3183,7 @@ public class SettingsProvider extends ContentProvider {
Setting setting = settingsState.getSettingLocked(name);
if (!SettingsState.isSystemPackage(getContext(),
setting.getPackageName())) {
- if (prefix != null && !setting.getName().startsWith(prefix)) {
+ if (shouldExcludeSettingFromReset(setting, prefix)) {
continue;
}
if (settingsState.resetSettingLocked(name)) {
@@ -3163,7 +3203,7 @@ public class SettingsProvider extends ContentProvider {
Setting setting = settingsState.getSettingLocked(name);
if (!SettingsState.isSystemPackage(getContext(),
setting.getPackageName())) {
- if (prefix != null && !setting.getName().startsWith(prefix)) {
+ if (shouldExcludeSettingFromReset(setting, prefix)) {
continue;
}
if (setting.isDefaultFromSystem()) {
@@ -3186,7 +3226,7 @@ public class SettingsProvider extends ContentProvider {
for (String name : settingsState.getSettingNamesLocked()) {
Setting setting = settingsState.getSettingLocked(name);
boolean someSettingChanged = false;
- if (prefix != null && !setting.getName().startsWith(prefix)) {
+ if (shouldExcludeSettingFromReset(setting, prefix)) {
continue;
}
if (setting.isDefaultFromSystem()) {
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
index eaf0dcb9b4e7..1c6d2b08136c 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
@@ -464,6 +464,31 @@ public class SettingsProviderTest extends BaseSettingsProviderTest {
}
}
+ // To prevent FRP bypasses, the SECURE_FRP_MODE setting should not be reset when all other
+ // settings are reset. But it should still be possible to explicitly set its value.
+ @Test
+ public void testSecureFrpModeSettingCannotBeReset() throws Exception {
+ final String name = Settings.Secure.SECURE_FRP_MODE;
+ final String origValue = getSetting(SETTING_TYPE_GLOBAL, name);
+ setSettingViaShell(SETTING_TYPE_GLOBAL, name, "1", false);
+ try {
+ assertEquals("1", getSetting(SETTING_TYPE_GLOBAL, name));
+ for (int type : new int[] { SETTING_TYPE_GLOBAL, SETTING_TYPE_SECURE }) {
+ resetSettingsViaShell(type, Settings.RESET_MODE_UNTRUSTED_DEFAULTS);
+ resetSettingsViaShell(type, Settings.RESET_MODE_UNTRUSTED_CHANGES);
+ resetSettingsViaShell(type, Settings.RESET_MODE_TRUSTED_DEFAULTS);
+ }
+ // The value should still be "1". It should not have been reset to null.
+ assertEquals("1", getSetting(SETTING_TYPE_GLOBAL, name));
+ // It should still be possible to explicitly set the value to "0".
+ setSettingViaShell(SETTING_TYPE_GLOBAL, name, "0", false);
+ assertEquals("0", getSetting(SETTING_TYPE_GLOBAL, name));
+ } finally {
+ setSettingViaShell(SETTING_TYPE_GLOBAL, name, origValue, false);
+ assertEquals(origValue, getSetting(SETTING_TYPE_GLOBAL, name));
+ }
+ }
+
private void doTestQueryStringInBracketsViaProviderApiForType(int type) {
// Make sure we have a clean slate.
deleteStringViaProviderApi(type, FAKE_SETTING_NAME);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 16299c7aff7b..4ebc0ad9267d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -78,6 +78,7 @@ import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.ViewController;
@@ -365,6 +366,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
}
};
+ private final DeviceProvisionedController mDeviceProvisionedController;
+
@Inject
public KeyguardSecurityContainerController(KeyguardSecurityContainer view,
AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory,
@@ -386,7 +389,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
FalsingA11yDelegate falsingA11yDelegate,
TelephonyManager telephonyManager,
ViewMediatorCallback viewMediatorCallback,
- AudioManager audioManager
+ AudioManager audioManager,
+ DeviceProvisionedController deviceProvisionedController
) {
super(view);
mLockPatternUtils = lockPatternUtils;
@@ -411,6 +415,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
mTelephonyManager = telephonyManager;
mViewMediatorCallback = viewMediatorCallback;
mAudioManager = audioManager;
+ mDeviceProvisionedController = deviceProvisionedController;
}
@Override
@@ -752,8 +757,11 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
case SimPuk:
// Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
- if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled(
- KeyguardUpdateMonitor.getCurrentUser())) {
+ boolean isLockscreenDisabled = mLockPatternUtils.isLockScreenDisabled(
+ KeyguardUpdateMonitor.getCurrentUser())
+ || !mDeviceProvisionedController.isUserSetup(targetUserId);
+
+ if (securityMode == SecurityMode.None && isLockscreenDisabled) {
finish = true;
eventSubtype = BOUNCER_DISMISS_SIM;
uiEvent = BouncerUiEvent.BOUNCER_DISMISS_SIM;
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index b4a30583f492..2cd822ab8fb3 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -104,7 +104,7 @@ object Flags {
// TODO(b/260335638): Tracking Bug
@JvmField
val NOTIFICATION_INLINE_REPLY_ANIMATION =
- releasedFlag(174148361, "notification_inline_reply_animation")
+ unreleasedFlag(174148361, "notification_inline_reply_animation")
val FILTER_UNSEEN_NOTIFS_ON_KEYGUARD =
releasedFlag(254647461, "filter_unseen_notifs_on_keyguard", teamfood = true)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java
index f73dde632051..f6d98977744f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java
@@ -54,6 +54,7 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
private Consumer<QS> mQSFragmentAttachedListener = qs -> {};
private QS mQs;
private View mQSContainer;
+ private int mLastQSPaddingBottom;
@Nullable
private Consumer<Configuration> mConfigurationChangedListener;
@@ -75,6 +76,10 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
mQs = (QS) fragment;
mQSFragmentAttachedListener.accept(mQs);
mQSContainer = mQs.getView().findViewById(R.id.quick_settings_container);
+ // We need to restore the bottom padding as the fragment may have been recreated due to
+ // some special Configuration change, so we apply the last known padding (this will be
+ // correct even if it has changed while the fragment was destroyed and re-created).
+ setQSContainerPaddingBottom(mLastQSPaddingBottom);
}
@Override
@@ -101,6 +106,7 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
}
public void setQSContainerPaddingBottom(int paddingBottom) {
+ mLastQSPaddingBottom = paddingBottom;
if (mQSContainer != null) {
mQSContainer.setPadding(
mQSContainer.getPaddingLeft(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index f21db0bde59a..783650bd8399 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -48,6 +48,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.os.UserManager;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.transition.ChangeBounds;
@@ -118,6 +119,8 @@ public class NotificationConversationInfo extends LinearLayout implements
private NotificationGuts mGutsContainer;
private OnConversationSettingsClickListener mOnConversationSettingsClickListener;
+ private UserManager mUm;
+
@VisibleForTesting
boolean mSkipPost = false;
private int mActualHeight;
@@ -155,7 +158,9 @@ public class NotificationConversationInfo extends LinearLayout implements
// People Tile add request.
if (mSelectedAction == ACTION_FAVORITE && getPriority() != mSelectedAction) {
mShadeController.animateCollapseShade();
- mPeopleSpaceWidgetManager.requestPinAppWidget(mShortcutInfo, new Bundle());
+ if (mUm.isSameProfileGroup(UserHandle.USER_SYSTEM, mSbn.getNormalizedUserId())) {
+ mPeopleSpaceWidgetManager.requestPinAppWidget(mShortcutInfo, new Bundle());
+ }
}
mGutsContainer.closeControls(v, /* save= */ true);
};
@@ -188,6 +193,7 @@ public class NotificationConversationInfo extends LinearLayout implements
public void bindNotification(
ShortcutManager shortcutManager,
PackageManager pm,
+ UserManager um,
PeopleSpaceWidgetManager peopleSpaceWidgetManager,
INotificationManager iNotificationManager,
OnUserInteractionCallback onUserInteractionCallback,
@@ -211,6 +217,7 @@ public class NotificationConversationInfo extends LinearLayout implements
mEntry = entry;
mSbn = entry.getSbn();
mPm = pm;
+ mUm = um;
mAppName = mPackageName;
mOnSettingsClickListener = onSettingsClick;
mNotificationChannel = notificationChannel;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 46f1bb5ebd6f..b5354130e1c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -30,6 +30,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
@@ -113,6 +114,9 @@ public class NotificationGutsManager implements NotifGutsViewManager {
private Runnable mOpenRunnable;
private final INotificationManager mNotificationManager;
private final PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
+
+ private final UserManager mUserManager;
+
private final LauncherApps mLauncherApps;
private final ShortcutManager mShortcutManager;
private final UserContextProvider mContextTracker;
@@ -128,6 +132,7 @@ public class NotificationGutsManager implements NotifGutsViewManager {
AccessibilityManager accessibilityManager,
HighPriorityProvider highPriorityProvider,
INotificationManager notificationManager,
+ UserManager userManager,
PeopleSpaceWidgetManager peopleSpaceWidgetManager,
LauncherApps launcherApps,
ShortcutManager shortcutManager,
@@ -149,6 +154,7 @@ public class NotificationGutsManager implements NotifGutsViewManager {
mAccessibilityManager = accessibilityManager;
mHighPriorityProvider = highPriorityProvider;
mNotificationManager = notificationManager;
+ mUserManager = userManager;
mPeopleSpaceWidgetManager = peopleSpaceWidgetManager;
mLauncherApps = launcherApps;
mShortcutManager = shortcutManager;
@@ -468,6 +474,7 @@ public class NotificationGutsManager implements NotifGutsViewManager {
notificationInfoView.bindNotification(
mShortcutManager,
pmUser,
+ mUserManager,
mPeopleSpaceWidgetManager,
mNotificationManager,
mOnUserInteractionCallback,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 1cfcf8cbbdcb..7f1deb5e3009 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -414,6 +414,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
@Override
public void destroy() {
+ Log.d(TAG, "destroy() called");
mController.removeCallback(mControllerCallbackH);
mHandler.removeCallbacksAndMessages(null);
mConfigurationController.removeCallback(this);
@@ -488,6 +489,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
}
private void initDialog(int lockTaskModeState) {
+ Log.d(TAG, "initDialog: called!");
mDialog = new CustomDialog(mContext);
initDimens();
@@ -1281,7 +1283,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
}
protected void tryToRemoveCaptionsTooltip() {
- if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipView != null) {
+ if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipView != null && mDialog != null) {
ViewGroup container = mDialog.findViewById(R.id.volume_dialog_container);
container.removeView(mODICaptionsTooltipView);
mODICaptionsTooltipView = null;
@@ -1471,8 +1473,16 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
mHandler.removeMessages(H.DISMISS);
mHandler.removeMessages(H.SHOW);
- if (mIsAnimatingDismiss) {
- Log.d(TAG, "dismissH: isAnimatingDismiss");
+
+ boolean showingStateInconsistent = !mShowing && mDialog != null && mDialog.isShowing();
+ // If incorrectly assuming dialog is not showing, continue and make the state consistent.
+ if (showingStateInconsistent) {
+ Log.d(TAG, "dismissH: volume dialog possible in inconsistent state:"
+ + "mShowing=" + mShowing + ", mDialog==null?" + (mDialog == null));
+ }
+ if (mIsAnimatingDismiss && !showingStateInconsistent) {
+ Log.d(TAG, "dismissH: skipping dismiss because isAnimatingDismiss is true"
+ + " and showingStateInconsistent is false");
Trace.endSection();
return;
}
@@ -1490,8 +1500,12 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
.setDuration(mDialogHideAnimationDurationMs)
.setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
.withEndAction(() -> mHandler.postDelayed(() -> {
- mController.notifyVisible(false);
- mDialog.dismiss();
+ if (mController != null) {
+ mController.notifyVisible(false);
+ }
+ if (mDialog != null) {
+ mDialog.dismiss();
+ }
tryToRemoveCaptionsTooltip();
mIsAnimatingDismiss = false;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index e387cdeffd8c..2a7c602e4e62 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -71,6 +71,7 @@ import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.settings.GlobalSettings;
@@ -207,7 +208,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
mConfigurationController, mFalsingCollector, mFalsingManager,
mUserSwitcherController, mFeatureFlags, mGlobalSettings,
mSessionTracker, Optional.of(mSideFpsController), mFalsingA11yDelegate,
- mTelephonyManager, mViewMediatorCallback, mAudioManager);
+ mTelephonyManager, mViewMediatorCallback, mAudioManager,
+ mock(DeviceProvisionedController.class));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
new file mode 100644
index 000000000000..8bb8f6247e25
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 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.shade
+
+import android.testing.AndroidTestingRunner
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.QSFragment
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class NotificationsQuickSettingsContainerTest : SysuiTestCase() {
+
+ @Mock private lateinit var qsFrame: View
+ @Mock private lateinit var stackScroller: View
+ @Mock private lateinit var keyguardStatusBar: View
+ @Mock private lateinit var qsFragment: QSFragment
+
+ private lateinit var qsView: ViewGroup
+ private lateinit var qsContainer: View
+
+ private lateinit var underTest: NotificationsQuickSettingsContainer
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ underTest = NotificationsQuickSettingsContainer(context, null)
+
+ setUpViews()
+ underTest.onFinishInflate()
+ underTest.onFragmentViewCreated("QS", qsFragment)
+ }
+
+ @Test
+ fun qsContainerPaddingSetAgainAfterQsRecreated() {
+ val padding = 100
+ underTest.setQSContainerPaddingBottom(padding)
+
+ assertThat(qsContainer.paddingBottom).isEqualTo(padding)
+
+ // We reset the padding before "creating" a new QSFragment
+ qsContainer.setPadding(0, 0, 0, 0)
+ underTest.onFragmentViewCreated("QS", qsFragment)
+
+ assertThat(qsContainer.paddingBottom).isEqualTo(padding)
+ }
+
+ private fun setUpViews() {
+ qsView = FrameLayout(context)
+ qsContainer = View(context)
+ qsContainer.id = R.id.quick_settings_container
+ qsView.addView(qsContainer)
+
+ whenever(qsFrame.findViewById<View>(R.id.qs_frame)).thenReturn(qsFrame)
+ whenever(stackScroller.findViewById<View>(R.id.notification_stack_scroller))
+ .thenReturn(stackScroller)
+ whenever(keyguardStatusBar.findViewById<View>(R.id.keyguard_header))
+ .thenReturn(keyguardStatusBar)
+ whenever(qsFragment.view).thenReturn(qsView)
+
+ val layoutParams = ConstraintLayout.LayoutParams(0, 0)
+ whenever(qsFrame.layoutParams).thenReturn(layoutParams)
+ whenever(stackScroller.layoutParams).thenReturn(layoutParams)
+ whenever(keyguardStatusBar.layoutParams).thenReturn(layoutParams)
+
+ underTest.addView(qsFrame)
+ underTest.addView(stackScroller)
+ underTest.addView(keyguardStatusBar)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 90adabfadd5d..596e9a2613d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -62,6 +62,7 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Handler;
import android.os.UserHandle;
+import android.os.UserManager;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
@@ -132,6 +133,8 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
@Mock
private PackageManager mMockPackageManager;
@Mock
+ private UserManager mUserManager;
+ @Mock
private OnUserInteractionCallback mOnUserInteractionCallback;
@Mock
private BubblesManager mBubblesManager;
@@ -238,6 +241,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -262,6 +266,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -314,6 +319,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -339,6 +345,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -363,6 +370,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -398,6 +406,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -423,6 +432,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -452,6 +462,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -476,6 +487,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -504,6 +516,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -532,6 +545,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -563,6 +577,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -600,6 +615,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -628,6 +644,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -663,6 +680,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -691,6 +709,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -735,6 +754,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -778,6 +798,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -822,6 +843,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -860,6 +882,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -896,6 +919,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -936,6 +960,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -967,6 +992,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -996,6 +1022,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -1033,6 +1060,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -1069,6 +1097,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -1104,6 +1133,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -1143,6 +1173,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -1173,6 +1204,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -1198,6 +1230,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -1219,11 +1252,13 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
@Test
public void testSelectPriorityRequestsPinPeopleTile() {
+ when(mUserManager.isSameProfileGroup(anyInt(), anyInt())).thenReturn(true);
//WHEN channel is default importance
mNotificationChannel.setImportantConversation(false);
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -1250,10 +1285,45 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
}
@Test
+ public void testSelectPriorityRequestsPinPeopleTile_noMultiuser() {
+ when(mUserManager.isSameProfileGroup(anyInt(), anyInt())).thenReturn(false);
+ //WHEN channel is default importance
+ mNotificationChannel.setImportantConversation(false);
+ mNotificationInfo.bindNotification(
+ mShortcutManager,
+ mMockPackageManager,
+ mUserManager,
+ mPeopleSpaceWidgetManager,
+ mMockINotificationManager,
+ mOnUserInteractionCallback,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ mEntry,
+ mBubbleMetadata,
+ null,
+ mIconFactory,
+ mContext,
+ true,
+ mTestHandler,
+ mTestHandler, null, Optional.of(mBubblesManager),
+ mShadeController);
+
+ // WHEN user clicks "priority"
+ mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
+
+ // and then done
+ mNotificationInfo.findViewById(R.id.done).performClick();
+
+ // No widget prompt; on a secondary user
+ verify(mPeopleSpaceWidgetManager, never()).requestPinAppWidget(any(), any());
+ }
+
+ @Test
public void testSelectDefaultDoesNotRequestPinPeopleTile() {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
@@ -1288,6 +1358,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mShortcutManager,
mMockPackageManager,
+ mUserManager,
mPeopleSpaceWidgetManager,
mMockINotificationManager,
mOnUserInteractionCallback,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 3d8a74466a5c..2507146a6200 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -52,6 +52,7 @@ import android.content.pm.ShortcutManager;
import android.graphics.Color;
import android.os.Binder;
import android.os.Handler;
+import android.os.UserManager;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
@@ -135,6 +136,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
@Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
@Mock private StatusBarStateController mStatusBarStateController;
+ @Mock private UserManager mUserManager;
+
@Before
public void setUp() {
mTestableLooper = TestableLooper.get(this);
@@ -145,7 +148,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
mGutsManager = new NotificationGutsManager(mContext,
() -> Optional.of(mCentralSurfaces), mHandler, mHandler, mAccessibilityManager,
- mHighPriorityProvider, mINotificationManager,
+ mHighPriorityProvider, mINotificationManager, mUserManager,
mPeopleSpaceWidgetManager, mLauncherApps, mShortcutManager,
mChannelEditorDialogController, mContextTracker, mAssistantFeedbackController,
Optional.of(mBubblesManager), new UiEventLoggerFake(), mOnUserInteractionCallback,
diff --git a/services/core/java/com/android/server/PendingIntentUtils.java b/services/core/java/com/android/server/PendingIntentUtils.java
index 1600101b20f4..a72a4d254a2a 100644
--- a/services/core/java/com/android/server/PendingIntentUtils.java
+++ b/services/core/java/com/android/server/PendingIntentUtils.java
@@ -34,6 +34,7 @@ public class PendingIntentUtils {
public static Bundle createDontSendToRestrictedAppsBundle(@Nullable Bundle bundle) {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setDontSendToRestrictedApps(true);
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
if (bundle == null) {
return options.toBundle();
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ba0aaa1b7d8c..13953d873c0f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2982,6 +2982,22 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
+ /**
+ * Enforces that the uid of the caller matches the uid of the package.
+ *
+ * @param packageName the name of the package to match uid against.
+ * @param callingUid the uid of the caller.
+ * @throws SecurityException if the calling uid doesn't match uid of the package.
+ */
+ private void enforceCallingPackage(String packageName, int callingUid) {
+ final int userId = UserHandle.getUserId(callingUid);
+ final int packageUid = getPackageManagerInternal().getPackageUid(packageName,
+ /*flags=*/ 0, userId);
+ if (packageUid != callingUid) {
+ throw new SecurityException(packageName + " does not belong to uid " + callingUid);
+ }
+ }
+
@Override
public void setPackageScreenCompatMode(String packageName, int mode) {
mActivityTaskManager.setPackageScreenCompatMode(packageName, mode);
@@ -12951,13 +12967,16 @@ public class ActivityManagerService extends IActivityManager.Stub
// A backup agent has just come up
@Override
public void backupAgentCreated(String agentPackageName, IBinder agent, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ enforceCallingPackage(agentPackageName, callingUid);
+
// Resolve the target user id and enforce permissions.
- userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid,
userId, /* allowAll */ false, ALLOW_FULL_ONLY, "backupAgentCreated", null);
if (DEBUG_BACKUP) {
Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName + " = " + agent
+ " callingUserId = " + UserHandle.getCallingUserId() + " userId = " + userId
- + " callingUid = " + Binder.getCallingUid() + " uid = " + Process.myUid());
+ + " callingUid = " + callingUid + " uid = " + Process.myUid());
}
synchronized(this) {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 59794f41d1b7..ac6843cc4994 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -2994,9 +2994,19 @@ public class LockSettingsService extends ILockSettings.Stub {
}
activateEscrowTokens(authToken, userId);
- if (isProfileWithSeparatedLock(userId)) {
- setDeviceUnlockedForUser(userId);
+ if (isCredentialSharableWithParent(userId)) {
+ if (getSeparateProfileChallengeEnabledInternal(userId)) {
+ setDeviceUnlockedForUser(userId);
+ } else {
+ // Here only clear StrongAuthFlags for a profile that has a unified challenge.
+ // StrongAuth for a profile with a separate challenge is handled differently and
+ // is cleared after the user successfully confirms the separate challenge to enter
+ // the profile. StrongAuth for the full user (e.g. userId 0) is also handled
+ // separately by Keyguard.
+ mStrongAuth.reportUnlock(userId);
+ }
}
+
mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
onAuthTokenKnownForUser(userId, authToken);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d0ae7d59a784..b10c51c67ce4 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4368,7 +4368,7 @@ public class NotificationManagerService extends SystemService {
// Remove background token before returning notification to untrusted app, this
// ensures the app isn't able to perform background operations that are
// associated with notification interactions.
- notification.setAllowlistToken(null);
+ notification.clearAllowlistToken();
return new StatusBarNotification(
sbn.getPackageName(),
sbn.getOpPkg(),
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index a2b2983a8f35..d5788295c3c9 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -34,6 +34,7 @@ import android.app.usage.UsageStatsManagerInternal;
import android.appwidget.AppWidgetProviderInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentProvider;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -1914,11 +1915,32 @@ public class ShortcutService extends IShortcutService.Stub {
}
if (shortcut.getIcon() != null) {
ShortcutInfo.validateIcon(shortcut.getIcon());
+ validateIconURI(shortcut);
}
shortcut.replaceFlags(shortcut.getFlags() & ShortcutInfo.FLAG_LONG_LIVED);
}
+ // Validates the calling process has permission to access shortcut icon's image uri
+ private void validateIconURI(@NonNull final ShortcutInfo si) {
+ final int callingUid = injectBinderCallingUid();
+ final Icon icon = si.getIcon();
+ if (icon == null) {
+ // There's no icon in this shortcut, nothing to validate here.
+ return;
+ }
+ int iconType = icon.getType();
+ if (iconType != Icon.TYPE_URI && iconType != Icon.TYPE_URI_ADAPTIVE_BITMAP) {
+ // The icon is not URI-based, nothing to validate.
+ return;
+ }
+ final Uri uri = icon.getUri();
+ mUriGrantsManagerInternal.checkGrantUriPermission(callingUid, si.getPackage(),
+ ContentProvider.getUriWithoutUserId(uri),
+ Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(callingUid)));
+ }
+
private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut, boolean forUpdate) {
fixUpIncomingShortcutInfo(shortcut, forUpdate, /*forPinRequest=*/ false);
}
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index 9c74dd795d30..9d76072cceeb 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -81,7 +81,7 @@
]
}
],
- "presubmit-large": [
+ "postsubmit": [
{
"name": "CtsContentTestCases",
"options": [
@@ -95,9 +95,7 @@
"include-filter": "android.content.pm.cts"
}
]
- }
- ],
- "postsubmit": [
+ },
{
"name": "CtsPermissionTestCases",
"options": [
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 0da178b2bcd0..7f32b09f1d92 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2004,6 +2004,9 @@ public class DisplayPolicy {
*/
final Rect mConfigFrame = new Rect();
+ /** The count of insets sources when calculating this info. */
+ int mLastInsetsSourceCount;
+
private boolean mNeedUpdate = true;
void update(DisplayContent dc, int rotation, int w, int h) {
@@ -2025,6 +2028,7 @@ public class DisplayPolicy {
mNonDecorFrame.inset(mNonDecorInsets);
mConfigFrame.set(displayFrame);
mConfigFrame.inset(mConfigInsets);
+ mLastInsetsSourceCount = dc.getDisplayPolicy().mInsetsSourceWindowsExceptIme.size();
mNeedUpdate = false;
}
@@ -2033,6 +2037,7 @@ public class DisplayPolicy {
mConfigInsets.set(other.mConfigInsets);
mNonDecorFrame.set(other.mNonDecorFrame);
mConfigFrame.set(other.mConfigFrame);
+ mLastInsetsSourceCount = other.mLastInsetsSourceCount;
mNeedUpdate = false;
}
@@ -2048,6 +2053,12 @@ public class DisplayPolicy {
static final int DECOR_TYPES = Type.displayCutout() | Type.navigationBars();
+ /**
+ * The types that may affect display configuration. This excludes cutout because it is
+ * known from display info.
+ */
+ static final int CONFIG_TYPES = Type.statusBars() | Type.navigationBars();
+
private final DisplayContent mDisplayContent;
private final Info[] mInfoForRotation = new Info[4];
final Info mTmpInfo = new Info();
@@ -2087,7 +2098,20 @@ public class DisplayPolicy {
final DecorInsets.Info newInfo = mDecorInsets.mTmpInfo;
newInfo.update(mDisplayContent, rotation, dw, dh);
final DecorInsets.Info currentInfo = getDecorInsetsInfo(rotation, dw, dh);
- if (newInfo.mNonDecorFrame.equals(currentInfo.mNonDecorFrame)) {
+ if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)) {
+ // Even if the config frame is not changed in current rotation, it may change the
+ // insets in other rotations if the source count is changed.
+ if (newInfo.mLastInsetsSourceCount != currentInfo.mLastInsetsSourceCount) {
+ for (int i = mDecorInsets.mInfoForRotation.length - 1; i >= 0; i--) {
+ if (i != rotation) {
+ final boolean flipSize = (i + rotation) % 2 == 1;
+ final int w = flipSize ? dh : dw;
+ final int h = flipSize ? dw : dh;
+ mDecorInsets.mInfoForRotation[i].update(mDisplayContent, i, w, h);
+ }
+ }
+ mDecorInsets.mInfoForRotation[rotation].set(newInfo);
+ }
return false;
}
mDecorInsets.invalidate();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 78ed43658dd5..706989069e4b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1885,7 +1885,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean needToSendNewConfiguration =
win.isVisibleRequestedOrAdding() && displayContent.updateOrientation();
- if (win.providesNonDecorInsets()) {
+ if (win.providesDisplayDecorInsets()) {
needToSendNewConfiguration |= displayPolicy.updateDecorInsetsInfo();
}
if (needToSendNewConfiguration) {
@@ -2358,7 +2358,7 @@ public class WindowManagerService extends IWindowManager.Stub
& WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED) != 0) {
win.mLayoutNeeded = true;
}
- if (layoutChanged && win.providesNonDecorInsets()) {
+ if (layoutChanged && win.providesDisplayDecorInsets()) {
configChanged = displayPolicy.updateDecorInsetsInfo();
}
if (win.mActivityRecord != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0169387c483d..b9d43d9eb220 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1897,13 +1897,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return (mPolicyVisibility & POLICY_VISIBILITY_ALL) == POLICY_VISIBILITY_ALL;
}
- boolean providesNonDecorInsets() {
+ boolean providesDisplayDecorInsets() {
if (mProvidedInsetsSources == null) {
return false;
}
for (int i = mProvidedInsetsSources.size() - 1; i >= 0; i--) {
final int type = mProvidedInsetsSources.keyAt(i);
- if ((InsetsState.toPublicType(type) & WindowInsets.Type.navigationBars()) != 0) {
+ if ((InsetsState.toPublicType(type) & DisplayPolicy.DecorInsets.CONFIG_TYPES) != 0) {
return true;
}
}
@@ -2631,13 +2631,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
// Check if window provides non decor insets before clearing its provided insets.
- final boolean windowProvidesNonDecorInsets = providesNonDecorInsets();
+ final boolean windowProvidesDisplayDecorInsets = providesDisplayDecorInsets();
removeImmediately();
// Removing a visible window may affect the display orientation so just update it if
// needed. Also recompute configuration if it provides screen decor insets.
boolean needToSendNewConfiguration = wasVisible && displayContent.updateOrientation();
- if (windowProvidesNonDecorInsets) {
+ if (windowProvidesDisplayDecorInsets) {
needToSendNewConfiguration |=
displayContent.getDisplayPolicy().updateDecorInsetsInfo();
}
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerTests.java
index ef6253b229df..8707a4f77845 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerTests.java
@@ -56,7 +56,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.StatFs;
import android.os.SystemClock;
-import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.Postsubmit;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.system.ErrnoException;
@@ -94,7 +94,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
-@Presubmit
+@Postsubmit
public class PackageManagerTests extends AndroidTestCase {
private static final boolean localLOGV = true;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 39b215d9a2ec..cb217fef33a7 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -5565,6 +5565,49 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testVisitUris_styleExtrasWithoutStyle() {
+ Notification notification = new Notification.Builder(mContext, "a")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .build();
+
+ Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle(
+ personWithIcon("content://user"))
+ .addHistoricMessage(new Notification.MessagingStyle.Message("Heyhey!",
+ System.currentTimeMillis(),
+ personWithIcon("content://historicalMessenger")))
+ .addMessage(new Notification.MessagingStyle.Message("Are you there",
+ System.currentTimeMillis(),
+ personWithIcon("content://messenger")))
+ .setShortcutIcon(
+ Icon.createWithContentUri("content://conversationShortcut"));
+ messagingStyle.addExtras(notification.extras); // Instead of Builder.setStyle(style).
+
+ Notification.CallStyle callStyle = Notification.CallStyle.forOngoingCall(
+ personWithIcon("content://caller"),
+ PendingIntent.getActivity(mContext, 0, new Intent(),
+ PendingIntent.FLAG_IMMUTABLE))
+ .setVerificationIcon(Icon.createWithContentUri("content://callVerification"));
+ callStyle.addExtras(notification.extras); // Same.
+
+ Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+ notification.visitUris(visitor);
+
+ verify(visitor).accept(eq(Uri.parse("content://user")));
+ verify(visitor).accept(eq(Uri.parse("content://historicalMessenger")));
+ verify(visitor).accept(eq(Uri.parse("content://messenger")));
+ verify(visitor).accept(eq(Uri.parse("content://conversationShortcut")));
+ verify(visitor).accept(eq(Uri.parse("content://caller")));
+ verify(visitor).accept(eq(Uri.parse("content://callVerification")));
+ }
+
+ private static Person personWithIcon(String iconUri) {
+ return new Person.Builder()
+ .setName("Mr " + iconUri)
+ .setIcon(Icon.createWithContentUri(iconUri))
+ .build();
+ }
+
+ @Test
public void testVisitUris_wearableExtender() {
Icon actionIcon = Icon.createWithContentUri("content://media/action");
Icon wearActionIcon = Icon.createWithContentUri("content://media/wearAction");
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index c91822279e7c..04c020285832 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -3117,7 +3117,7 @@ public class ActivityRecordTests extends WindowTestsBase {
.setSystemDecorations(true).build();
// Add a decor insets provider window.
final WindowState navbar = createNavBarWithProvidedInsets(squareDisplay);
- assertTrue(navbar.providesNonDecorInsets()
+ assertTrue(navbar.providesDisplayDecorInsets()
&& squareDisplay.getDisplayPolicy().updateDecorInsetsInfo());
squareDisplay.sendNewConfiguration();
final Task task = new TaskBuilder(mSupervisor).setDisplay(squareDisplay).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index ac8dd465adbe..5da3c36fbef8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -48,6 +48,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -301,20 +302,27 @@ public class DisplayPolicyTests extends WindowTestsBase {
@Test
public void testUpdateDisplayConfigurationByDecor() {
+ doReturn(NO_CUTOUT).when(mDisplayContent).calculateDisplayCutoutForRotation(anyInt());
final WindowState navbar = createNavBarWithProvidedInsets(mDisplayContent);
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
final DisplayInfo di = mDisplayContent.getDisplayInfo();
final int prevScreenHeightDp = mDisplayContent.getConfiguration().screenHeightDp;
- assertTrue(navbar.providesNonDecorInsets() && displayPolicy.updateDecorInsetsInfo());
+ assertTrue(navbar.providesDisplayDecorInsets() && displayPolicy.updateDecorInsetsInfo());
assertEquals(NAV_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation,
di.logicalWidth, di.logicalHeight).mConfigInsets.bottom);
mDisplayContent.sendNewConfiguration();
assertNotEquals(prevScreenHeightDp, mDisplayContent.getConfiguration().screenHeightDp);
- assertFalse(navbar.providesNonDecorInsets() && displayPolicy.updateDecorInsetsInfo());
+ assertFalse(navbar.providesDisplayDecorInsets() && displayPolicy.updateDecorInsetsInfo());
navbar.removeIfPossible();
assertEquals(0, displayPolicy.getDecorInsetsInfo(di.rotation, di.logicalWidth,
di.logicalHeight).mNonDecorInsets.bottom);
+
+ final WindowState statusBar = createStatusBarWithProvidedInsets(mDisplayContent);
+ assertTrue(statusBar.providesDisplayDecorInsets()
+ && displayPolicy.updateDecorInsetsInfo());
+ assertEquals(STATUS_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation,
+ di.logicalWidth, di.logicalHeight).mConfigInsets.top);
}
@UseTestDisplay(addWindows = { W_NAVIGATION_BAR, W_INPUT_METHOD })
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 57e7afd9f85a..d762651f511e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -438,6 +438,16 @@ class WindowTestsBase extends SystemServiceTestsBase {
return navbar;
}
+ WindowState createStatusBarWithProvidedInsets(DisplayContent dc) {
+ final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, dc, "statusBar");
+ statusBar.mAttrs.width = WindowManager.LayoutParams.MATCH_PARENT;
+ statusBar.mAttrs.height = STATUS_BAR_HEIGHT;
+ statusBar.mAttrs.gravity = Gravity.TOP;
+ statusBar.mAttrs.setFitInsetsTypes(0);
+ dc.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
+ return statusBar;
+ }
+
WindowState createAppWindow(Task task, int type, String name) {
final ActivityRecord activity = createNonAttachedActivityRecord(task.getDisplayContent());
task.addChild(activity, 0);
diff --git a/services/usb/OWNERS b/services/usb/OWNERS
index 60172a36128e..d35dbb56437b 100644
--- a/services/usb/OWNERS
+++ b/services/usb/OWNERS
@@ -1,3 +1,7 @@
+aprasath@google.com
+kumarashishg@google.com
+sarup@google.com
+anothermark@google.com
badhri@google.com
elaurent@google.com
albertccwang@google.com