diff options
11 files changed, 186 insertions, 87 deletions
diff --git a/services/Android.bp b/services/Android.bp index 89643704658a..4d38b067d3a4 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -58,6 +58,7 @@ system_optimized_java_defaults { // retracing infra. optimize: false, shrink: true, + ignore_warnings: false, proguard_flags_files: ["proguard.flags"], }, // Note: Optimizations are disabled by default if unspecified in @@ -174,6 +175,8 @@ java_library { "android.hidl.manager-V1.0-java", "framework-tethering.stubs.module_lib", "service-art.stubs.system_server", + "service-permission.stubs.system_server", + "service-sdksandbox.stubs.system_server", ], // Uncomment to enable output of certain warnings (deprecated, unchecked) diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 56990eda3e78..cd81b906d878 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -667,6 +667,7 @@ public class AdbDebuggingManager { + " Not enabling adbwifi."); Settings.Global.putInt(mContentResolver, Settings.Global.ADB_WIFI_ENABLED, 0); + return; } // Check for network change @@ -675,6 +676,7 @@ public class AdbDebuggingManager { Slog.e(TAG, "Unable to get the wifi ap's BSSID. Disabling adbwifi."); Settings.Global.putInt(mContentResolver, Settings.Global.ADB_WIFI_ENABLED, 0); + return; } synchronized (mAdbConnectionInfo) { if (!bssid.equals(mAdbConnectionInfo.getBSSID())) { diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS index 15887f0df406..da209f095897 100644 --- a/services/core/java/com/android/server/am/OWNERS +++ b/services/core/java/com/android/server/am/OWNERS @@ -37,3 +37,7 @@ per-file SettingsToPropertiesMapper.java = omakoto@google.com, yamasani@google.c per-file CarUserSwitchingDialog.java = file:platform/packages/services/Car:/OWNERS per-file ContentProviderHelper.java = varunshah@google.com, omakoto@google.com, jsharkey@google.com, yamasani@google.com + +# Multiuser +per-file User* = file:/MULTIUSER_OWNERS + diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java index 5b26672c7de2..dd44af1b68ee 100644 --- a/services/core/java/com/android/server/audio/SpatializerHelper.java +++ b/services/core/java/com/android/server/audio/SpatializerHelper.java @@ -280,18 +280,13 @@ public class SpatializerHelper { } // for both transaural / binaural, we are not forcing enablement as the init() method // could have been called another time after boot in case of audioserver restart - if (mTransauralSupported) { - // not force-enabling as this device might already be in the device list - addCompatibleAudioDevice( - new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""), - false /*forceEnable*/); - } - if (mBinauralSupported) { - // not force-enabling as this device might already be in the device list - addCompatibleAudioDevice( - new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, ""), - false /*forceEnable*/); - } + addCompatibleAudioDevice( + new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""), + false /*forceEnable*/); + // not force-enabling as this device might already be in the device list + addCompatibleAudioDevice( + new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, ""), + false /*forceEnable*/); } catch (RemoteException e) { resetCapabilities(); } finally { @@ -497,10 +492,9 @@ public class SpatializerHelper { synchronized @NonNull List<AudioDeviceAttributes> getCompatibleAudioDevices() { // build unionOf(mCompatibleAudioDevices, mEnabledDevice) - mDisabledAudioDevices ArrayList<AudioDeviceAttributes> compatList = new ArrayList<>(); - for (SADeviceState dev : mSADevices) { - if (dev.mEnabled) { - compatList.add(new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT, - dev.mDeviceType, dev.mDeviceAddress == null ? "" : dev.mDeviceAddress)); + for (SADeviceState deviceState : mSADevices) { + if (deviceState.mEnabled) { + compatList.add(deviceState.getAudioDeviceAttributes()); } } return compatList; @@ -521,15 +515,15 @@ public class SpatializerHelper { */ private void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada, boolean forceEnable) { + if (!isDeviceCompatibleWithSpatializationModes(ada)) { + return; + } loglogi("addCompatibleAudioDevice: dev=" + ada); - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); boolean isInList = false; SADeviceState deviceUpdated = null; // non-null on update. for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (!wireless || ada.getAddress().equals(deviceState.mDeviceAddress))) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { isInList = true; if (forceEnable) { deviceState.mEnabled = true; @@ -539,11 +533,10 @@ public class SpatializerHelper { } } if (!isInList) { - final SADeviceState dev = new SADeviceState(deviceType, - wireless ? ada.getAddress() : ""); - dev.mEnabled = true; - mSADevices.add(dev); - deviceUpdated = dev; + final SADeviceState deviceState = new SADeviceState(ada.getType(), ada.getAddress()); + deviceState.mEnabled = true; + mSADevices.add(deviceState); + deviceUpdated = deviceState; } if (deviceUpdated != null) { onRoutingUpdated(); @@ -574,13 +567,10 @@ public class SpatializerHelper { synchronized void removeCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { loglogi("removeCompatibleAudioDevice: dev=" + ada); - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); SADeviceState deviceUpdated = null; // non-null on update. for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (!wireless || ada.getAddress().equals(deviceState.mDeviceAddress))) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { deviceState.mEnabled = false; deviceUpdated = deviceState; break; @@ -602,10 +592,9 @@ public class SpatializerHelper { // if not a wireless device, this value will be overwritten to map the type // to TYPE_BUILTIN_SPEAKER or TYPE_WIRED_HEADPHONES @AudioDeviceInfo.AudioDeviceType int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); // if not a wireless device: find if media device is in the speaker, wired headphones - if (!wireless) { + if (!isWireless(deviceType)) { // is the device type capable of doing SA? if (!mSACapableDeviceTypes.contains(deviceType)) { Log.i(TAG, "Device incompatible with Spatial Audio dev:" + ada); @@ -640,9 +629,7 @@ public class SpatializerHelper { boolean enabled = false; boolean available = false; for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { available = true; enabled = deviceState.mEnabled; break; @@ -652,11 +639,12 @@ public class SpatializerHelper { } private synchronized void addWirelessDeviceIfNew(@NonNull AudioDeviceAttributes ada) { + if (!isDeviceCompatibleWithSpatializationModes(ada)) { + return; + } boolean knownDevice = false; for (SADeviceState deviceState : mSADevices) { - // wireless device so always check address - if (ada.getType() == deviceState.mDeviceType - && ada.getAddress().equals(deviceState.mDeviceAddress)) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { knownDevice = true; break; } @@ -704,13 +692,8 @@ public class SpatializerHelper { if (ada.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) { return false; } - - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { return true; } } @@ -719,12 +702,19 @@ public class SpatializerHelper { private synchronized boolean canBeSpatializedOnDevice(@NonNull AudioAttributes attributes, @NonNull AudioFormat format, @NonNull AudioDeviceAttributes[] devices) { - final byte modeForDevice = (byte) SPAT_MODE_FOR_DEVICE_TYPE.get(devices[0].getType(), + if (isDeviceCompatibleWithSpatializationModes(devices[0])) { + return AudioSystem.canBeSpatialized(attributes, format, devices); + } + return false; + } + + private boolean isDeviceCompatibleWithSpatializationModes(@NonNull AudioDeviceAttributes ada) { + final byte modeForDevice = (byte) SPAT_MODE_FOR_DEVICE_TYPE.get(ada.getType(), /*default when type not found*/ SpatializationMode.SPATIALIZER_BINAURAL); if ((modeForDevice == SpatializationMode.SPATIALIZER_BINAURAL && mBinauralSupported) || (modeForDevice == SpatializationMode.SPATIALIZER_TRANSAURAL && mTransauralSupported)) { - return AudioSystem.canBeSpatialized(attributes, format, devices); + return true; } return false; } @@ -1089,13 +1079,8 @@ public class SpatializerHelper { Log.v(TAG, "no headtracking support, ignoring setHeadTrackerEnabled to " + enabled + " for " + ada); } - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); - for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { if (!deviceState.mHasHeadTracker) { Log.e(TAG, "Called setHeadTrackerEnabled enabled:" + enabled + " device:" + ada + " on a device without headtracker"); @@ -1109,7 +1094,7 @@ public class SpatializerHelper { } } // check current routing to see if it affects the headtracking mode - if (ROUTING_DEVICES[0].getType() == deviceType + if (ROUTING_DEVICES[0].getType() == ada.getType() && ROUTING_DEVICES[0].getAddress().equals(ada.getAddress())) { setDesiredHeadTrackingMode(enabled ? mDesiredHeadTrackingModeWhenEnabled : Spatializer.HEAD_TRACKING_MODE_DISABLED); @@ -1121,13 +1106,8 @@ public class SpatializerHelper { Log.v(TAG, "no headtracking support, hasHeadTracker always false for " + ada); return false; } - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); - for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { return deviceState.mHasHeadTracker; } } @@ -1144,13 +1124,8 @@ public class SpatializerHelper { Log.v(TAG, "no headtracking support, setHasHeadTracker always false for " + ada); return false; } - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); - for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { if (!deviceState.mHasHeadTracker) { deviceState.mHasHeadTracker = true; mAudioService.persistSpatialAudioDeviceSettings(); @@ -1168,13 +1143,8 @@ public class SpatializerHelper { Log.v(TAG, "no headtracking support, isHeadTrackerEnabled always false for " + ada); return false; } - final int deviceType = ada.getType(); - final boolean wireless = isWireless(deviceType); - for (SADeviceState deviceState : mSADevices) { - if (deviceType == deviceState.mDeviceType - && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) - || !wireless) { + if (deviceState.matchesAudioDeviceAttributes(ada)) { if (!deviceState.mHasHeadTracker) { return false; } @@ -1531,7 +1501,7 @@ public class SpatializerHelper { SADeviceState(@AudioDeviceInfo.AudioDeviceType int deviceType, @NonNull String address) { mDeviceType = deviceType; - mDeviceAddress = Objects.requireNonNull(address); + mDeviceAddress = isWireless(deviceType) ? Objects.requireNonNull(address) : ""; } @Override @@ -1599,6 +1569,18 @@ public class SpatializerHelper { return null; } } + + public AudioDeviceAttributes getAudioDeviceAttributes() { + return new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT, + mDeviceType, mDeviceAddress == null ? "" : mDeviceAddress); + } + + public boolean matchesAudioDeviceAttributes(AudioDeviceAttributes ada) { + final int deviceType = ada.getType(); + final boolean wireless = isWireless(deviceType); + return (deviceType == mDeviceType) + && (!wireless || ada.getAddress().equals(mDeviceAddress)); + } } /*package*/ synchronized String getSADeviceSettings() { @@ -1619,7 +1601,9 @@ public class SpatializerHelper { // small list, not worth overhead of Arrays.stream(devSettings) for (String setting : devSettings) { SADeviceState devState = SADeviceState.fromPersistedString(setting); - if (devState != null) { + if (devState != null + && isDeviceCompatibleWithSpatializationModes( + devState.getAudioDeviceAttributes())) { mSADevices.add(devState); logDeviceState(devState, "setSADeviceSettings"); } diff --git a/services/core/java/com/android/server/logcat/OWNERS b/services/core/java/com/android/server/logcat/OWNERS index 87d30f3dd537..4ce93aa7df83 100644 --- a/services/core/java/com/android/server/logcat/OWNERS +++ b/services/core/java/com/android/server/logcat/OWNERS @@ -1,3 +1,5 @@ +# Bug component: 1218649 + cbrubaker@google.com eunjeongshin@google.com georgechan@google.com diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 829b9c7692fe..a4f10ba05106 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -6275,21 +6275,40 @@ public class NotificationManagerService extends SystemService { checkCallerIsSystem(); mHandler.post(() -> { synchronized (mNotificationLock) { - // strip flag from all enqueued notifications. listeners will be informed - // in post runnable. - List<NotificationRecord> enqueued = findNotificationsByListLocked( - mEnqueuedNotifications, pkg, null, notificationId, userId); - for (int i = 0; i < enqueued.size(); i++) { - removeForegroundServiceFlagLocked(enqueued.get(i)); - } + int count = getNotificationCount(pkg, userId); + boolean removeFgsNotification = false; + if (count > MAX_PACKAGE_NOTIFICATIONS) { + mUsageStats.registerOverCountQuota(pkg); + removeFgsNotification = true; + } + if (removeFgsNotification) { + NotificationRecord r = findNotificationLocked(pkg, null, notificationId, + userId); + if (r != null) { + if (DBG) { + Slog.d(TAG, "Remove FGS flag not allow. Cancel FGS notification"); + } + removeFromNotificationListsLocked(r); + cancelNotificationLocked(r, false, REASON_APP_CANCEL, true, + null, SystemClock.elapsedRealtime()); + } + } else { + // strip flag from all enqueued notifications. listeners will be informed + // in post runnable. + List<NotificationRecord> enqueued = findNotificationsByListLocked( + mEnqueuedNotifications, pkg, null, notificationId, userId); + for (int i = 0; i < enqueued.size(); i++) { + removeForegroundServiceFlagLocked(enqueued.get(i)); + } - // if posted notification exists, strip its flag and tell listeners - NotificationRecord r = findNotificationByListLocked( - mNotificationList, pkg, null, notificationId, userId); - if (r != null) { - removeForegroundServiceFlagLocked(r); - mRankingHelper.sort(mNotificationList); - mListeners.notifyPostedLocked(r, r); + // if posted notification exists, strip its flag and tell listeners + NotificationRecord r = findNotificationByListLocked( + mNotificationList, pkg, null, notificationId, userId); + if (r != null) { + removeForegroundServiceFlagLocked(r); + mRankingHelper.sort(mNotificationList); + mListeners.notifyPostedLocked(r, r); + } } } }); @@ -6967,6 +6986,29 @@ public class NotificationManagerService extends SystemService { return mPermissionHelper.hasPermission(uid); } + private int getNotificationCount(String pkg, int userId) { + int count = 0; + synchronized (mNotificationLock) { + final int numListSize = mNotificationList.size(); + for (int i = 0; i < numListSize; i++) { + final NotificationRecord existing = mNotificationList.get(i); + if (existing.getSbn().getPackageName().equals(pkg) + && existing.getSbn().getUserId() == userId) { + count++; + } + } + final int numEnqSize = mEnqueuedNotifications.size(); + for (int i = 0; i < numEnqSize; i++) { + final NotificationRecord existing = mEnqueuedNotifications.get(i); + if (existing.getSbn().getPackageName().equals(pkg) + && existing.getSbn().getUserId() == userId) { + count++; + } + } + } + return count; + } + protected int getNotificationCount(String pkg, int userId, int excludedId, String excludedTag) { int count = 0; diff --git a/services/proguard.flags b/services/proguard.flags index c648f7d3ac45..eb5c7144c967 100644 --- a/services/proguard.flags +++ b/services/proguard.flags @@ -118,3 +118,7 @@ -keep,allowoptimization,allowaccessmodification class com.android.server.usage.StorageStatsManagerLocal { *; } -keep,allowoptimization,allowaccessmodification class com.android.internal.util.** { *; } -keep,allowoptimization,allowaccessmodification class android.os.** { *; } + +# CoverageService guards optional jacoco class references with a runtime guard, so we can safely +# suppress build-time warnings. +-dontwarn org.jacoco.agent.rt.* 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 22721a1bcc92..709c928dad9c 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -6039,6 +6039,62 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testCannotRemoveForegroundFlagWhenOverLimit_enqueued() { + for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) { + Notification n = new Notification.Builder(mContext, "").build(); + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, i, null, mUid, 0, + n, UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + mService.addEnqueuedNotification(r); + } + Notification n = new Notification.Builder(mContext, "").build(); + n.flags |= FLAG_FOREGROUND_SERVICE; + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, + NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, null, mUid, 0, + n, UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addEnqueuedNotification(r); + + mInternalService.removeForegroundServiceFlagFromNotification( + PKG, r.getSbn().getId(), r.getSbn().getUserId()); + + waitForIdle(); + + assertEquals(NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, + mService.getNotificationRecordCount()); + } + + @Test + public void testCannotRemoveForegroundFlagWhenOverLimit_posted() { + for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) { + Notification n = new Notification.Builder(mContext, "").build(); + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, i, null, mUid, 0, + n, UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + mService.addNotification(r); + } + Notification n = new Notification.Builder(mContext, "").build(); + n.flags |= FLAG_FOREGROUND_SERVICE; + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, + NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, null, mUid, 0, + n, UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addNotification(r); + + mInternalService.removeForegroundServiceFlagFromNotification( + PKG, r.getSbn().getId(), r.getSbn().getUserId()); + + waitForIdle(); + + assertEquals(NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, + mService.getNotificationRecordCount()); + } + + @Test public void testAllowForegroundCustomToasts() throws Exception { final String testPackage = "testPackageName"; assertEquals(0, mService.mToastQueue.size()); diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java index 47f87d6d75ff..573b3b695a90 100644 --- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java +++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java @@ -102,6 +102,7 @@ public final class NotificationTest { @After public void tearDown() { mNotificationManager.cancelAll(); + mUiDevice.pressHome(); } @Test diff --git a/tools/preload-check/AndroidTest.xml b/tools/preload-check/AndroidTest.xml index a0645d5b1051..d486f0f914c6 100644 --- a/tools/preload-check/AndroidTest.xml +++ b/tools/preload-check/AndroidTest.xml @@ -14,7 +14,7 @@ limitations under the License. --> <configuration description="Config for PreloadCheck"> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> + <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> <option name="cleanup" value="true" /> <option name="push" value="preload-check-device.jar->/data/local/tmp/preload-check-device.jar" /> </target_preparer> diff --git a/tools/preload-check/OWNERS b/tools/preload-check/OWNERS new file mode 100644 index 000000000000..e71c7332ca90 --- /dev/null +++ b/tools/preload-check/OWNERS @@ -0,0 +1 @@ +include /ZYGOTE_OWNERS |