From e6fc32e0122832129df3326f3a63b1017651c2fe Mon Sep 17 00:00:00 2001 From: Tavi Date: Wed, 19 Jun 2024 18:14:14 -0400 Subject: [PATCH] 17.1: June ASB work Signed-off-by: Tavi --- .../android_frameworks_base/393587.patch | 16 +- .../android_frameworks_base/393588.patch | 12 +- .../android_frameworks_base/394553.patch | 47 +++ .../android_frameworks_base/394554.patch | 46 +++ .../394555-backport.patch | 137 +++++++++ .../394556-backport.patch | 270 ++++++++++++++++++ .../394557-backport.patch | 70 +++++ .../394558-backport.patch | 31 ++ .../android_frameworks_base/394559.patch | 43 +++ .../android_frameworks_base/394560.patch | 68 +++++ .../android_frameworks_base/394561.patch | 47 +++ .../394562-backport.patch | 59 ++++ .../394563-backport.patch | 61 ++++ Scripts/LineageOS-17.1/Patch.sh | 13 +- 14 files changed, 905 insertions(+), 15 deletions(-) create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394553.patch create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394554.patch create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394555-backport.patch create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394556-backport.patch create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394557-backport.patch create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394558-backport.patch create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394559.patch create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394560.patch create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394561.patch create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394562-backport.patch create mode 100644 Patches/LineageOS-17.1/android_frameworks_base/394563-backport.patch diff --git a/Patches/LineageOS-17.1/android_frameworks_base/393587.patch b/Patches/LineageOS-17.1/android_frameworks_base/393587.patch index 5f374638..ff0a9588 100644 --- a/Patches/LineageOS-17.1/android_frameworks_base/393587.patch +++ b/Patches/LineageOS-17.1/android_frameworks_base/393587.patch @@ -1,7 +1,7 @@ -From 27549d452e6524778c69c1e7a5e0ab6cae04750e Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Valentin Iftime Date: Mon, 16 Oct 2023 09:29:17 +0200 -Subject: [PATCH] [BACKPORT] Prioritize system toasts +Subject: [PATCH] Prioritize system toasts Insert toasts from system packages at the front of the queue to ensure that apps can't spam with toast to delay system toasts from showing. @@ -17,10 +17,10 @@ Change-Id: I13547f853476bc88d12026c545aba9f857ce8724 2 files changed, 104 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java -index e09491867f91a..d769ff8e75055 100755 +index e09491867f91..d769ff8e7505 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java -@@ -744,17 +744,21 @@ private void writePolicyXml(OutputStream stream, boolean forBackup, int userId) +@@ -744,17 +744,21 @@ public class NotificationManagerService extends SystemService { private static final class ToastRecord { @@ -43,7 +43,7 @@ index e09491867f91a..d769ff8e75055 100755 this.callback = callback; this.duration = duration; this.token = token; -@@ -2481,10 +2485,21 @@ record = mToastQueue.get(index); +@@ -2481,10 +2485,21 @@ public class NotificationManagerService extends SystemService { Binder token = new Binder(); mWindowManagerInternal.addWindowToken(token, TYPE_TOAST, displayId); @@ -68,7 +68,7 @@ index e09491867f91a..d769ff8e75055 100755 keepProcessAliveIfNeededLocked(callingPid); } // If it's at index 0, it's the current toast. It doesn't matter if it's -@@ -2500,6 +2515,23 @@ record = new ToastRecord(callingPid, pkg, callback, duration, token, +@@ -2500,6 +2515,23 @@ public class NotificationManagerService extends SystemService { } } @@ -93,10 +93,10 @@ index e09491867f91a..d769ff8e75055 100755 public void cancelToast(String pkg, ITransientNotification callback) { Slog.i(TAG, "cancelToast pkg=" + pkg + " callback=" + callback); 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 bcb4c49336cf5..4a0aa7c9e8e74 100755 +index bcb4c49336cf..4a0aa7c9e8e7 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -@@ -4480,6 +4480,74 @@ public void testAlwaysAllowSystemToasts() throws Exception { +@@ -4480,6 +4480,74 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(1, mService.mToastQueue.size()); } diff --git a/Patches/LineageOS-17.1/android_frameworks_base/393588.patch b/Patches/LineageOS-17.1/android_frameworks_base/393588.patch index cf4e43ba..df9467fa 100644 --- a/Patches/LineageOS-17.1/android_frameworks_base/393588.patch +++ b/Patches/LineageOS-17.1/android_frameworks_base/393588.patch @@ -1,4 +1,4 @@ -From 9a28c009d937e060bb5c10034cb5370129b8ce81 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jan Tomljanovic Date: Fri, 6 Nov 2020 11:28:09 +0000 Subject: [PATCH] Don't try to show the current toast again while it's showing. @@ -19,7 +19,7 @@ Change-Id: Ie4953109314113efae49fa0c5e0c236e6e0dbb23 2 files changed, 39 insertions(+) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java -index d769ff8e75055..7b1c0ac27ab30 100755 +index d769ff8e7505..7b1c0ac27ab3 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -437,6 +437,10 @@ public class NotificationManagerService extends SystemService { @@ -33,7 +33,7 @@ index d769ff8e75055..7b1c0ac27ab30 100755 // The last key in this list owns the hardware. ArrayList mLights = new ArrayList<>(); -@@ -6482,12 +6486,17 @@ public void run() { +@@ -6482,12 +6486,17 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mToastQueue") void showNextToastLocked() { @@ -51,7 +51,7 @@ index d769ff8e75055..7b1c0ac27ab30 100755 return; } catch (RemoteException e) { Slog.w(TAG, "Object died trying to show notification " + record.callback -@@ -6519,6 +6528,10 @@ void cancelToastLocked(int index) { +@@ -6519,6 +6528,10 @@ public class NotificationManagerService extends SystemService { // the list anyway } @@ -63,10 +63,10 @@ index d769ff8e75055..7b1c0ac27ab30 100755 mWindowManagerInternal.removeWindowToken(lastToast.token, false /* removeWindows */, 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 4a0aa7c9e8e74..0e8cea43063b9 100755 +index 4a0aa7c9e8e7..0e8cea43063b 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -@@ -4415,6 +4415,32 @@ public void testAllowForegroundToasts() throws Exception { +@@ -4415,6 +4415,32 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394553.patch b/Patches/LineageOS-17.1/android_frameworks_base/394553.patch new file mode 100644 index 00000000..e70bea70 --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394553.patch @@ -0,0 +1,47 @@ +From 00961ad29e26dde5d4f56de90ac333ceb2fc8d34 Mon Sep 17 00:00:00 2001 +From: Jing Ji +Date: Tue, 25 Oct 2022 22:39:52 -0700 +Subject: [PATCH] DO NOT MERGE: ActivityManager#killBackgroundProcesses can + kill caller's own app only + +unless it's a system app. + +Bug: 239423414 +Bug: 223376078 +Test: atest CtsAppTestCases:ActivityManagerTest +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d1c95670b248df945784b0f2830acf83b5682de3) +Merged-In: Iac6baa889965b8ffecd9a43179a4c96632ad1d02 +AOSP-Change-Id: Iac6baa889965b8ffecd9a43179a4c96632ad1d02 + +Change-Id: I41cd6fa1f71e950db18a9fd450355c4e6f80ec7d +--- + .../server/am/ActivityManagerService.java | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java +index 234b23a996267..815ddf63e565a 100644 +--- a/services/core/java/com/android/server/am/ActivityManagerService.java ++++ b/services/core/java/com/android/server/am/ActivityManagerService.java +@@ -4486,6 +4486,22 @@ void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) { + throw new SecurityException(msg); + } + ++ final int callingUid = Binder.getCallingUid(); ++ final int callingPid = Binder.getCallingPid(); ++ ++ ProcessRecord proc; ++ synchronized (mPidsSelfLocked) { ++ proc = mPidsSelfLocked.get(callingPid); ++ } ++ if (callingUid >= FIRST_APPLICATION_UID ++ && (proc == null || !proc.info.isSystemApp())) { ++ final String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" ++ + callingPid + ", uid=" + callingUid + " is not allowed"; ++ Slog.w(TAG, msg); ++ // Silently return to avoid existing apps from crashing. ++ return; ++ } ++ + final long callingId = Binder.clearCallingIdentity(); + try { + synchronized (this) { diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394554.patch b/Patches/LineageOS-17.1/android_frameworks_base/394554.patch new file mode 100644 index 00000000..73255325 --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394554.patch @@ -0,0 +1,46 @@ +From 14804676d97278009b746073e8339374b0cce927 Mon Sep 17 00:00:00 2001 +From: Jing Ji +Date: Thu, 19 Oct 2023 14:22:58 -0700 +Subject: [PATCH] DO NOT MERGE: Fix ActivityManager#killBackgroundProcesses + permissions + +In the pevious CL, we incorrectly added the permission check in the +killBackgroundProcessesExcept. Now fix this issue. + +Bug: 239423414 +Bug: 223376078 +Test: atest CtsAppTestCases:ActivityManagerTest +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:140fce861944419a375c669010c6c47cd7ff5b37) +Merged-In: I9471a77188ee63ec32cd0c81569193e4ccad885b +Change-Id: I9471a77188ee63ec32cd0c81569193e4ccad885b +--- + .../server/am/ActivityManagerService.java | 16 ---------------- + 1 file changed, 16 deletions(-) + +diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java +index 815ddf63e565a..234b23a996267 100644 +--- a/services/core/java/com/android/server/am/ActivityManagerService.java ++++ b/services/core/java/com/android/server/am/ActivityManagerService.java +@@ -4486,22 +4486,6 @@ void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) { + throw new SecurityException(msg); + } + +- final int callingUid = Binder.getCallingUid(); +- final int callingPid = Binder.getCallingPid(); +- +- ProcessRecord proc; +- synchronized (mPidsSelfLocked) { +- proc = mPidsSelfLocked.get(callingPid); +- } +- if (callingUid >= FIRST_APPLICATION_UID +- && (proc == null || !proc.info.isSystemApp())) { +- final String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" +- + callingPid + ", uid=" + callingUid + " is not allowed"; +- Slog.w(TAG, msg); +- // Silently return to avoid existing apps from crashing. +- return; +- } +- + final long callingId = Binder.clearCallingIdentity(); + try { + synchronized (this) { diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394555-backport.patch b/Patches/LineageOS-17.1/android_frameworks_base/394555-backport.patch new file mode 100644 index 00000000..519fec75 --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394555-backport.patch @@ -0,0 +1,137 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Valentin Iftime +Date: Thu, 1 Feb 2024 13:58:49 +0100 +Subject: [PATCH] Verify URI permission for channel sound update from + NotificationListenerService + + Check that a privileged NotificationListenerService (CDM) has the permission to access the sound URI + when updating a notification channel. + +Test: atest com.android.server.notification.NotificationManagerServiceTest#testUpdateNotificationChannelFromPrivilegedListener_noSoundUriPermission +Bug: 317357401 +(cherry picked from commit 9b7bbbf5ad542ecf9ecbf8cd819b468791b443c0) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f090c0538a27d8658d8a860046d5c5e931302341) +Merged-In: Ic7d2e96e43565e98d2aa29b8f2ba35c142387ba9 +Change-Id: Ic7d2e96e43565e98d2aa29b8f2ba35c142387ba9 +--- + .../NotificationManagerService.java | 21 ++++++ + .../NotificationManagerServiceTest.java | 67 +++++++++++++++++++ + 2 files changed, 88 insertions(+) + +diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java +index 7b1c0ac27ab3..ca957e4d16e3 100755 +--- a/services/core/java/com/android/server/notification/NotificationManagerService.java ++++ b/services/core/java/com/android/server/notification/NotificationManagerService.java +@@ -4333,6 +4333,9 @@ public class NotificationManagerService extends SystemService { + Preconditions.checkNotNull(user); + + verifyPrivilegedListener(token, user, false); ++ final NotificationChannel originalChannel = mPreferencesHelper.getNotificationChannel( ++ pkg, getUidForPackageAndUser(pkg, user), channel.getId(), true); ++ verifyPrivilegedListenerUriPermission(Binder.getCallingUid(), channel, originalChannel); + updateNotificationChannelInt(pkg, getUidForPackageAndUser(pkg, user), channel, true); + } + +@@ -4412,6 +4415,24 @@ public class NotificationManagerService extends SystemService { + } + } + ++ private void verifyPrivilegedListenerUriPermission(int sourceUid, ++ @NonNull NotificationChannel updateChannel, ++ @Nullable NotificationChannel originalChannel) { ++ // Check that the NLS has the required permissions to access the channel ++ final Uri soundUri = updateChannel.getSound(); ++ final Uri originalSoundUri = ++ (originalChannel != null) ? originalChannel.getSound() : null; ++ if (soundUri != null && !Objects.equals(originalSoundUri, soundUri)) { ++ Binder.withCleanCallingIdentity(() -> { ++ mUgmInternal.checkGrantUriPermission(sourceUid, null, ++ ContentProvider.getUriWithoutUserId(soundUri), ++ Intent.FLAG_GRANT_READ_URI_PERMISSION, ++ ContentProvider.getUserIdFromUri(soundUri, ++ UserHandle.getUserId(sourceUid))); ++ }); ++ } ++ } ++ + private int getUidForPackageAndUser(String pkg, UserHandle user) throws RemoteException { + int uid = 0; + long identity = Binder.clearCallingIdentity(); +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 0e8cea43063b..403772d0f875 100755 +--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java ++++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +@@ -2037,6 +2037,73 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { + eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); + } + ++ @Test ++ public void testUpdateNotificationChannelFromPrivilegedListener_noSoundUriPermission() ++ throws Exception { ++ mService.setPreferencesHelper(mPreferencesHelper); ++ List associations = new ArrayList<>(); ++ associations.add("a"); ++ when(mCompanionMgr.getAssociations(PKG, UserHandle.getUserId(mUid))) ++ .thenReturn(associations); ++ when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(), ++ eq(mTestNotificationChannel.getId()), anyBoolean())) ++ .thenReturn(mTestNotificationChannel); ++ ++ final Uri soundUri = Uri.parse("content://media/test/sound/uri"); ++ final NotificationChannel updatedNotificationChannel = new NotificationChannel( ++ TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); ++ updatedNotificationChannel.setSound(soundUri, ++ updatedNotificationChannel.getAudioAttributes()); ++ ++ doThrow(new SecurityException("no access")).when(mUgmInternal) ++ .checkGrantUriPermission(eq(Process.myUid()), any(), eq(soundUri), ++ anyInt(), eq(Process.myUserHandle().getIdentifier())); ++ ++ assertThrows(SecurityException.class, ++ () -> mBinderService.updateNotificationChannelFromPrivilegedListener(null, PKG, ++ Process.myUserHandle(), updatedNotificationChannel)); ++ ++ verify(mPreferencesHelper, never()).updateNotificationChannel( ++ anyString(), anyInt(), any(), anyBoolean()); ++ ++ verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG), ++ eq(Process.myUserHandle()), eq(mTestNotificationChannel), ++ eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); ++ } ++ ++ @Test ++ public void testUpdateNotificationChannelFromPrivilegedListener_noSoundUriPermission_sameSound() ++ throws Exception { ++ mService.setPreferencesHelper(mPreferencesHelper); ++ List associations = new ArrayList<>(); ++ associations.add("a"); ++ when(mCompanionMgr.getAssociations(PKG, UserHandle.getUserId(mUid))) ++ .thenReturn(associations); ++ when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(), ++ eq(mTestNotificationChannel.getId()), anyBoolean())) ++ .thenReturn(mTestNotificationChannel); ++ ++ final Uri soundUri = Settings.System.DEFAULT_NOTIFICATION_URI; ++ final NotificationChannel updatedNotificationChannel = new NotificationChannel( ++ TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); ++ updatedNotificationChannel.setSound(soundUri, ++ updatedNotificationChannel.getAudioAttributes()); ++ ++ doThrow(new SecurityException("no access")).when(mUgmInternal) ++ .checkGrantUriPermission(eq(Process.myUid()), any(), eq(soundUri), ++ anyInt(), eq(Process.myUserHandle().getIdentifier())); ++ ++ mBinderService.updateNotificationChannelFromPrivilegedListener( ++ null, PKG, Process.myUserHandle(), updatedNotificationChannel); ++ ++ verify(mPreferencesHelper, times(1)).updateNotificationChannel( ++ anyString(), anyInt(), any(), anyBoolean()); ++ ++ verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG), ++ eq(Process.myUserHandle()), eq(mTestNotificationChannel), ++ eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); ++ } ++ + @Test + public void testGetNotificationChannelFromPrivilegedListener_cdm_success() throws Exception { + mService.setPreferencesHelper(mPreferencesHelper); diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394556-backport.patch b/Patches/LineageOS-17.1/android_frameworks_base/394556-backport.patch new file mode 100644 index 00000000..14830cef --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394556-backport.patch @@ -0,0 +1,270 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Valentin Iftime +Date: Thu, 22 Feb 2024 10:51:58 +0100 +Subject: [PATCH] Check for NLS bind permission when rebinding services + + Also, after updating packages with NLS components, check + the approved services and remove from approved list if missing permissions. + +Test: atest ManagedServicesTest +Bug: 321707289 + +(cherry picked from commit 24b13a64f9f5e5aa7f45a2132806d6c74e2c62dc) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0c15cdfdd4720efb72c3244a044bb27e2c286c4b) +Merged-In: I11901755ec430c6e3145def9d67e4e63cda00806 +Change-Id: I11901755ec430c6e3145def9d67e4e63cda00806 +--- + .../server/notification/ManagedServices.java | 108 ++++++++++++++---- + .../notification/ManagedServicesTest.java | 54 +++++++++ + 2 files changed, 139 insertions(+), 23 deletions(-) + +diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java +index 4828bbfff676..f57cddafdc2a 100644 +--- a/services/core/java/com/android/server/notification/ManagedServices.java ++++ b/services/core/java/com/android/server/notification/ManagedServices.java +@@ -141,7 +141,9 @@ abstract public class ManagedServices { + // List of approved packages or components (by user, then by primary/secondary) that are + // allowed to be bound as managed services. A package or component appearing in this list does + // not mean that we are currently bound to said package/component. +- private ArrayMap>> mApproved = new ArrayMap<>(); ++ ++ @GuardedBy("mApproved") ++ private final ArrayMap>> mApproved = new ArrayMap<>(); + + // True if approved services are stored in xml, not settings. + private boolean mUseXml; +@@ -573,6 +575,23 @@ abstract public class ManagedServices { + return false; + } + ++ protected boolean isPackageOrComponentAllowedWithPermission(ComponentName component, ++ int userId) { ++ if (!(isPackageOrComponentAllowed(component.flattenToString(), userId) ++ || isPackageOrComponentAllowed(component.getPackageName(), userId))) { ++ return false; ++ } ++ return componentHasBindPermission(component, userId); ++ } ++ ++ private boolean componentHasBindPermission(ComponentName component, int userId) { ++ ServiceInfo info = getServiceInfo(component, userId); ++ if (info == null) { ++ return false; ++ } ++ return mConfig.bindPermission.equals(info.permission); ++ } ++ + protected boolean isPackageAllowed(String pkg, int userId) { + if (pkg == null) { + return false; +@@ -623,6 +642,7 @@ abstract public class ManagedServices { + for (int uid : uidList) { + if (isPackageAllowed(pkgName, UserHandle.getUserId(uid))) { + anyServicesInvolved = true; ++ trimApprovedListsForInvalidServices(pkgName, UserHandle.getUserId(uid)); + } + } + } +@@ -749,8 +769,7 @@ abstract public class ManagedServices { + for (int i = 0; i < userIds.size(); i++) { + final int userId = userIds.get(i); + if (enabled) { +- if (isPackageOrComponentAllowed(component.flattenToString(), userId) +- || isPackageOrComponentAllowed(component.getPackageName(), userId)) { ++ if (isPackageOrComponentAllowedWithPermission(component, userId)) { + registerServiceLocked(component, userId); + } else { + Slog.d(TAG, component + " no longer has permission to be bound"); +@@ -889,6 +908,33 @@ abstract public class ManagedServices { + return removed; + } + ++ private void trimApprovedListsForInvalidServices(String packageName, int userId) { ++ synchronized (mApproved) { ++ final ArrayMap> approvedByType = mApproved.get(userId); ++ if (approvedByType == null) { ++ return; ++ } ++ for (int i = 0; i < approvedByType.size(); i++) { ++ final ArraySet approved = approvedByType.valueAt(i); ++ for (int j = approved.size() - 1; j >= 0; j--) { ++ final String approvedPackageOrComponent = approved.valueAt(j); ++ if (TextUtils.equals(getPackageName(approvedPackageOrComponent), packageName)) { ++ final ComponentName component = ComponentName.unflattenFromString( ++ approvedPackageOrComponent); ++ if (component != null && !componentHasBindPermission(component, userId)) { ++ approved.removeAt(j); ++ if (DEBUG) { ++ Slog.v(TAG, "Removing " + approvedPackageOrComponent ++ + " from approved list; no bind permission found " ++ + mConfig.bindPermission); ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ + protected String getPackageName(String packageOrComponent) { + final ComponentName component = ComponentName.unflattenFromString(packageOrComponent); + if (component != null) { +@@ -1048,26 +1094,20 @@ abstract public class ManagedServices { + final int userId = componentsToBind.keyAt(i); + final Set add = componentsToBind.get(userId); + for (ComponentName component : add) { +- try { +- ServiceInfo info = mPm.getServiceInfo(component, +- PackageManager.MATCH_DIRECT_BOOT_AWARE +- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); +- if (info == null) { +- Slog.w(TAG, "Not binding " + getCaption() + " service " + component +- + ": service not found"); +- continue; +- } +- if (!mConfig.bindPermission.equals(info.permission)) { +- Slog.w(TAG, "Not binding " + getCaption() + " service " + component +- + ": it does not require the permission " + mConfig.bindPermission); +- continue; +- } +- Slog.v(TAG, +- "enabling " + getCaption() + " for " + userId + ": " + component); +- registerService(component, userId); +- } catch (RemoteException e) { +- e.rethrowFromSystemServer(); ++ ServiceInfo info = getServiceInfo(component, userId); ++ if (info == null) { ++ Slog.w(TAG, "Not binding " + getCaption() + " service " + component ++ + ": service not found"); ++ continue; + } ++ if (!mConfig.bindPermission.equals(info.permission)) { ++ Slog.w(TAG, "Not binding " + getCaption() + " service " + component ++ + ": it does not require the permission " + mConfig.bindPermission); ++ continue; ++ } ++ Slog.v(TAG, ++ "enabling " + getCaption() + " for " + userId + ": " + component); ++ registerService(component, userId); + } + } + } +@@ -1081,6 +1121,15 @@ abstract public class ManagedServices { + } + } + ++ @VisibleForTesting ++ void reregisterService(final ComponentName cn, final int userId) { ++ // If rebinding a package that died, ensure it still has permission ++ // after the rebind delay ++ if (isPackageOrComponentAllowedWithPermission(cn, userId)) { ++ registerService(cn, userId); ++ } ++ } ++ + /** + * Inject a system service into the management list. + */ +@@ -1181,7 +1230,7 @@ abstract public class ManagedServices { + mHandler.postDelayed(new Runnable() { + @Override + public void run() { +- registerService(name, userid); ++ reregisterService(name, userid); + } + }, ON_BINDING_DIED_REBIND_DELAY_MS); + } else { +@@ -1313,6 +1362,19 @@ abstract public class ManagedServices { + } + } + ++ private ServiceInfo getServiceInfo(ComponentName component, int userId) { ++ try { ++ return mPm.getServiceInfo(component, ++ PackageManager.GET_META_DATA ++ | PackageManager.MATCH_DIRECT_BOOT_AWARE ++ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, ++ userId); ++ } catch (RemoteException e) { ++ e.rethrowFromSystemServer(); ++ } ++ return null; ++ } ++ + public class ManagedServiceInfo implements IBinder.DeathRecipient { + public IInterface service; + public ComponentName component; +diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +index 8aaf29a11033..cac620f409f3 100644 +--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java ++++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +@@ -28,8 +28,10 @@ import static org.mockito.Matchers.any; + import static org.mockito.Matchers.anyInt; + import static org.mockito.Matchers.eq; + import static org.mockito.Mockito.doAnswer; ++import static org.mockito.Mockito.doReturn; + import static org.mockito.Mockito.mock; + import static org.mockito.Mockito.never; ++import static org.mockito.Mockito.spy; + import static org.mockito.Mockito.times; + import static org.mockito.Mockito.verify; + import static org.mockito.Mockito.when; +@@ -624,6 +626,58 @@ public class ManagedServicesTest extends UiServiceTestCase { + } + } + ++ @Test ++ public void testUpgradeAppNoPermissionNoRebind() throws Exception { ++ Context context = spy(getContext()); ++ doReturn(true).when(context).bindServiceAsUser(any(), any(), anyInt(), any()); ++ ++ ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, ++ mIpm, ++ APPROVAL_BY_COMPONENT); ++ ++ List packages = new ArrayList<>(); ++ packages.add("package"); ++ addExpectedServices(service, packages, 0); ++ ++ final ComponentName unapprovedComponent = ComponentName.unflattenFromString("package/C1"); ++ final ComponentName approvedComponent = ComponentName.unflattenFromString("package/C2"); ++ ++ // Both components are approved initially ++ mExpectedPrimaryComponentNames.clear(); ++ mExpectedPrimaryPackages.clear(); ++ mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2"); ++ mExpectedSecondaryComponentNames.clear(); ++ mExpectedSecondaryPackages.clear(); ++ ++ loadXml(service); ++ ++ //Component package/C1 loses bind permission ++ when(mIpm.getServiceInfo(any(), anyInt(), anyInt())).thenAnswer( ++ (Answer) invocation -> { ++ ComponentName invocationCn = invocation.getArgument(0); ++ if (invocationCn != null) { ++ ServiceInfo serviceInfo = new ServiceInfo(); ++ serviceInfo.packageName = invocationCn.getPackageName(); ++ serviceInfo.name = invocationCn.getClassName(); ++ if (invocationCn.equals(unapprovedComponent)) { ++ serviceInfo.permission = "none"; ++ } else { ++ serviceInfo.permission = service.getConfig().bindPermission; ++ } ++ serviceInfo.metaData = null; ++ return serviceInfo; ++ } ++ return null; ++ } ++ ); ++ ++ // Trigger package update ++ service.onPackagesChanged(false, new String[]{"package"}, new int[]{0}); ++ ++ assertFalse(service.isComponentEnabledForCurrentProfiles(unapprovedComponent)); ++ assertTrue(service.isComponentEnabledForCurrentProfiles(approvedComponent)); ++ } ++ + @Test + public void testSetPackageOrComponentEnabled() throws Exception { + for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394557-backport.patch b/Patches/LineageOS-17.1/android_frameworks_base/394557-backport.patch new file mode 100644 index 00000000..b6554734 --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394557-backport.patch @@ -0,0 +1,70 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Riddle Hsu +Date: Tue, 6 Feb 2024 17:19:37 +0800 +Subject: [PATCH] Hide window immediately if itself doesn't run hide animation + +The condition was overextended in commit 9bca6b4 which checks if the +parent container of the window is animating. That causes the window to +wait for animation finish to update visibility, but the animation +finish callback won't happen because itself is not animating. Then the +window that should be hidden remains on screen. + +Bug: 302431573 +Test: atest WindowStateTests#testIsOnScreen_hiddenByPolicy +(cherry picked from commit 9add9281ffc120c81a7d125892803f1beb5ddcb3) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:10a7f0914c87f4af521b5cbb13e84a83dacebf82) +Merged-In: Iafc2b2c2a24d8fc8d147354ef2f0b4afeeb510c5 +Change-Id: Iafc2b2c2a24d8fc8d147354ef2f0b4afeeb510c5 +--- + .../com/android/server/wm/WindowState.java | 6 ++++-- + .../android/server/wm/WindowStateTests.java | 20 +++++++++++++++++++ + 2 files changed, 24 insertions(+), 2 deletions(-) + +diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java +index 18cdc943b8c8..cca14d884cdd 100644 +--- a/services/core/java/com/android/server/wm/WindowState.java ++++ b/services/core/java/com/android/server/wm/WindowState.java +@@ -2698,8 +2698,10 @@ class WindowState extends WindowContainer implements WindowManagerP + return false; + } + if (doAnimation) { +- mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false); +- if (!isAnimating()) { ++ // If a hide animation is applied, then let onAnimationFinished ++ // -> checkPolicyVisibilityChange hide the window. Otherwise make doAnimation false ++ // to commit invisible immediately. ++ if (!mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false /* isEntrance */)) { + doAnimation = false; + } + } +diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +index 3a8d3b74c08f..15d0fd90ef77 100644 +--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java ++++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +@@ -213,6 +213,26 @@ public class WindowStateTests extends WindowTestsBase { + assertTrue(window.isOnScreen()); + window.hideLw(false /* doAnimation */); + assertFalse(window.isOnScreen()); ++ ++ // Verifies that a window without animation can be hidden even if its parent is animating. ++ window.show(false /* doAnimation */, false /* requestAnim */); ++ assertTrue(window.isVisibleByPolicy()); ++ window.getParent().startAnimation(mTransaction, mock(AnimationAdapter.class), ++ false /* hidden */, SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION); ++ window.mAttrs.windowAnimations = 0; ++ window.hide(true /* doAnimation */, true /* requestAnim */); ++ assertFalse(window.isSelfAnimating(0, SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION)); ++ assertFalse(window.isVisibleByPolicy()); ++ assertFalse(window.isOnScreen()); ++ ++ // Verifies that a window with animation can be hidden after the hide animation is finished. ++ window.show(false /* doAnimation */, false /* requestAnim */); ++ window.mAttrs.windowAnimations = android.R.style.Animation_Dialog; ++ window.hide(true /* doAnimation */, true /* requestAnim */); ++ assertTrue(window.isSelfAnimating(0, SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION)); ++ assertTrue(window.isVisibleByPolicy()); ++ window.cancelAnimation(); ++ assertFalse(window.isVisibleByPolicy()); + } + + @Test diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394558-backport.patch b/Patches/LineageOS-17.1/android_frameworks_base/394558-backport.patch new file mode 100644 index 00000000..630bf1b5 --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394558-backport.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Yi-an Chen +Date: Tue, 20 Feb 2024 04:34:57 +0000 +Subject: [PATCH] Fix error handling for non-dynamic permissions + +We only allow removing dynamic permissions. When removePermission() is +called for a non-dynamic permission, in addition to logging it, we +should also return early to avoid the removePermission() call. + +Test: manual +Bug: 321555066 +Fixes: 321711213 +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2b5d63b64b2b8208ccc4f62eac3d8962f981dbf8) +Merged-In: I7336f2fc78804f26e4b2a329870ecdea776595d8 +Change-Id: I7336f2fc78804f26e4b2a329870ecdea776595d8 +--- + .../android/server/pm/permission/PermissionManagerService.java | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +index 2fcdec7c92d6..ed551795aad5 100644 +--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java ++++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +@@ -1015,6 +1015,7 @@ public class PermissionManagerService { + // TODO: switch this back to SecurityException + Slog.wtf(TAG, "Not allowed to modify non-dynamic permission " + + permName); ++ return; + } + mSettings.removePermissionLocked(permName); + if (callback != null) { diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394559.patch b/Patches/LineageOS-17.1/android_frameworks_base/394559.patch new file mode 100644 index 00000000..724fb031 --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394559.patch @@ -0,0 +1,43 @@ +From 18d1359a28cee22491dbe2f8b814ab999348ebfa Mon Sep 17 00:00:00 2001 +From: Dmitry Dementyev +Date: Tue, 26 Mar 2024 10:31:44 -0700 +Subject: [PATCH] Add more checkKeyIntent checks to AccountManagerService. + +Another verification is needed after Bundle modification. +Bug: 321941232 +Test: manual +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:36db8a1d61a881f89fdd3911886adcda6e1f0d7f) +Merged-In: I9e45d758a2320328da5664b6341eafe6f285f297 +Change-Id: I9e45d758a2320328da5664b6341eafe6f285f297 +--- + .../android/server/accounts/AccountManagerService.java | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java +index 8a9ddda50d63b..37a68d3eec76c 100644 +--- a/services/core/java/com/android/server/accounts/AccountManagerService.java ++++ b/services/core/java/com/android/server/accounts/AccountManagerService.java +@@ -3475,6 +3475,11 @@ public void onResult(Bundle result) { + + // Strip auth token from result. + result.remove(AccountManager.KEY_AUTHTOKEN); ++ if (!checkKeyIntent(Binder.getCallingUid(), result)) { ++ onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, ++ "invalid intent in bundle returned"); ++ return; ++ } + + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, +@@ -5052,6 +5057,11 @@ public void onResult(Bundle result) { + } else { + if (mStripAuthTokenFromResult) { + result.remove(AccountManager.KEY_AUTHTOKEN); ++ if (!checkKeyIntent(Binder.getCallingUid(), result)) { ++ onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, ++ "invalid intent in bundle returned"); ++ return; ++ } + } + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, getClass().getSimpleName() diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394560.patch b/Patches/LineageOS-17.1/android_frameworks_base/394560.patch new file mode 100644 index 00000000..6ed7b5be --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394560.patch @@ -0,0 +1,68 @@ +From a0059406f6fa6fa600bd6d5fc488de1d3aa956af Mon Sep 17 00:00:00 2001 +From: Haoran Zhang +Date: Wed, 13 Mar 2024 17:08:00 +0000 +Subject: [PATCH] Add in check for intent filter when setting/updating service + +For test, I registered two tests around on ABTD. CtsAutoFillServiceTestCases module is passing except three known failures: + +Test run link: +- https://android-build.corp.google.com/builds/abtd/run/L33300030002610600 +- https://android-build.corp.google.com/builds/abtd/run/L58100030002616607 + +Bug: b/324874908 +Test: atest CtsAutoFillServiceTestCases +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:141d9d050346bfc4673c429382deb1b3d210f6ad) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:51d64705ab70788a536c26d4df5e63f0952ec98f) +Merged-In: I51c2e3788ac29ff4d6b86aa2a735ff2ea1463a77 +Change-Id: I51c2e3788ac29ff4d6b86aa2a735ff2ea1463a77 +--- + .../autofill/AutofillManagerServiceImpl.java | 27 +++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +index 57ffe0498a88e..309f78006d4b6 100644 +--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java ++++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +@@ -32,8 +32,10 @@ + import android.app.ActivityTaskManager; + import android.app.IActivityTaskManager; + import android.content.ComponentName; ++import android.content.Intent; + import android.content.pm.PackageManager; + import android.content.pm.PackageManager.NameNotFoundException; ++import android.content.pm.ResolveInfo; + import android.content.pm.ServiceInfo; + import android.graphics.Rect; + import android.metrics.LogMaker; +@@ -235,6 +237,31 @@ protected boolean updateLocked(boolean disabled) { + @Override // from PerUserSystemService + protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent) + throws NameNotFoundException { ++ final List resolveInfos = ++ getContext().getPackageManager().queryIntentServicesAsUser( ++ new Intent(AutofillService.SERVICE_INTERFACE), ++ // The MATCH_INSTANT flag is added because curret autofill CTS module is ++ // defined in one apk, which makes the test autofill service installed in a ++ // instant app when the CTS tests are running in instant app mode. ++ // TODO: Remove MATCH_INSTANT flag after completing refactoring the CTS module ++ // to make the test autofill service a separate apk. ++ PackageManager.GET_META_DATA | PackageManager.MATCH_INSTANT, ++ mUserId); ++ boolean serviceHasAutofillIntentFilter = false; ++ for (ResolveInfo resolveInfo : resolveInfos) { ++ final ServiceInfo serviceInfo = resolveInfo.serviceInfo; ++ if (serviceInfo.getComponentName().equals(serviceComponent)) { ++ serviceHasAutofillIntentFilter = true; ++ break; ++ } ++ } ++ if (!serviceHasAutofillIntentFilter) { ++ Slog.w(TAG, ++ "Autofill service from '" + serviceComponent.getPackageName() + "' does" ++ + "not have intent filter " + AutofillService.SERVICE_INTERFACE); ++ throw new SecurityException("Service does not declare intent filter " ++ + AutofillService.SERVICE_INTERFACE); ++ } + mInfo = new AutofillServiceInfo(getContext(), serviceComponent, mUserId); + return mInfo.getServiceInfo(); + } diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394561.patch b/Patches/LineageOS-17.1/android_frameworks_base/394561.patch new file mode 100644 index 00000000..4e8eeb59 --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394561.patch @@ -0,0 +1,47 @@ +From a0d6c266c99cdcdba0ef4674cf6995619f13efa7 Mon Sep 17 00:00:00 2001 +From: Hans Boehm +Date: Tue, 2 Jan 2024 16:53:13 -0800 +Subject: [PATCH] Check hidden API exemptions + +Refuse to deal with newlines and null characters in +HiddenApiSettings.update(). Also disallow nulls in process start +arguments. + +Bug: 316153291 +Test: Treehugger for now +(cherry picked from commit 7ba059e2cf0a2c20f9a849719cdc32b12c933a44) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:60669aa49aba34c0950d6246bd95b54f91a3c8e8) +Merged-In: I83cd60e46407a4a082f9f3c80e937dbd522dbac4 +Change-Id: I83cd60e46407a4a082f9f3c80e937dbd522dbac4 +--- + core/java/android/os/ZygoteProcess.java | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java +index 39038f555044e..4d69f217c5e6a 100644 +--- a/core/java/android/os/ZygoteProcess.java ++++ b/core/java/android/os/ZygoteProcess.java +@@ -431,6 +431,8 @@ private Process.ProcessStartResult zygoteSendArgsAndGetResult( + throw new ZygoteStartFailedEx("Embedded newlines not allowed"); + } else if (arg.indexOf('\r') >= 0) { + throw new ZygoteStartFailedEx("Embedded carriage returns not allowed"); ++ } else if (arg.indexOf('\u0000') >= 0) { ++ throw new ZygoteStartFailedEx("Embedded nulls not allowed"); + } + } + +@@ -980,6 +982,14 @@ private boolean maybeSetApiBlacklistExemptions(ZygoteState state, boolean sendIf + return true; + } + ++ for (/* NonNull */ String s : mApiBlacklistExemptions) { ++ // indexOf() is intrinsified and faster than contains(). ++ if (s.indexOf('\n') >= 0 || s.indexOf('\r') >= 0 || s.indexOf('\u0000') >= 0) { ++ Slog.e(LOG_TAG, "Failed to set API denylist exemptions: Bad character"); ++ mApiBlacklistExemptions = Collections.emptyList(); ++ return false; ++ } ++ } + try { + state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1)); + state.mZygoteOutputWriter.newLine(); diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394562-backport.patch b/Patches/LineageOS-17.1/android_frameworks_base/394562-backport.patch new file mode 100644 index 00000000..d7520247 --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394562-backport.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ameer Armaly +Date: Fri, 8 Mar 2024 19:41:06 +0000 +Subject: [PATCH] AccessibilityManagerService: remove uninstalled services from + enabled list after service update. + +Bug: 326485767 +Test: atest AccessibilityEndToEndTest#testUpdateServiceWithoutIntent_disablesService +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5405514a23edcba0cf30e6ec78189e3f4e7d95cf) +Merged-In: I5e59296fcad68e62b34c74ee5fd80b6ad6b46fa1 +Change-Id: I5e59296fcad68e62b34c74ee5fd80b6ad6b46fa1 +--- + .../AccessibilityManagerService.java | 22 +++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +index 194c90e125f9..dbc9d42a4adc 100644 +--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java ++++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +@@ -1623,10 +1623,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub + boolean isUnlockingOrUnlocked = LocalServices.getService(UserManagerInternal.class) + .isUserUnlockingOrUnlocked(userState.mUserId); + ++ // Store the list of installed services. ++ mTempComponentNameSet.clear(); + for (int i = 0, count = userState.mInstalledServices.size(); i < count; i++) { + AccessibilityServiceInfo installedService = userState.mInstalledServices.get(i); + ComponentName componentName = ComponentName.unflattenFromString( + installedService.getId()); ++ mTempComponentNameSet.add(componentName); + + AccessibilityServiceConnection service = componentNameToServiceMap.get(componentName); + +@@ -1673,6 +1676,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub + if (audioManager != null) { + audioManager.setAccessibilityServiceUids(mTempIntArray); + } ++ // If any services have been removed, remove them from the enabled list and the touch ++ // exploration granted list. ++ boolean anyServiceRemoved = ++ userState.mEnabledServices.removeIf((comp) -> !mTempComponentNameSet.contains(comp)) ++ || userState.mTouchExplorationGrantedServices.removeIf( ++ (comp) -> !mTempComponentNameSet.contains(comp)); ++ if (anyServiceRemoved) { ++ // Update the enabled services setting. ++ persistComponentNamesToSettingLocked( ++ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, ++ userState.mEnabledServices, ++ userState.mUserId); ++ // Update the touch exploration granted services setting. ++ persistComponentNamesToSettingLocked( ++ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, ++ userState.mTouchExplorationGrantedServices, ++ userState.mUserId); ++ } ++ mTempComponentNameSet.clear(); + updateAccessibilityEnabledSetting(userState); + } + diff --git a/Patches/LineageOS-17.1/android_frameworks_base/394563-backport.patch b/Patches/LineageOS-17.1/android_frameworks_base/394563-backport.patch new file mode 100644 index 00000000..b1fb4ae4 --- /dev/null +++ b/Patches/LineageOS-17.1/android_frameworks_base/394563-backport.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Guojing Yuan +Date: Thu, 14 Dec 2023 19:30:04 +0000 +Subject: [PATCH] Check permissions for CDM shell commands + +Override handleShellCommand instead of onShellCommand because +Binder.onShellCommand checks the necessary permissions of the caller. + +Bug: 313428840 + +Test: manually tested CDM shell commands +(cherry picked from commit 1761a0fee9c2cd9787bbb7fbdbe30b4c2b03396e) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8d008c61451dba86aa9f14c6bcd661db2cea4856) +Merged-In: I5539b3594feb5544c458c0fd1061b51a0a808900 +Change-Id: I5539b3594feb5544c458c0fd1061b51a0a808900 +--- + .../companion/CompanionDeviceManagerService.java | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +index 73b8ff7067ef..e78ddaad3e88 100644 +--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java ++++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +@@ -24,6 +24,7 @@ import static com.android.internal.util.Preconditions.checkState; + import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable; + + import android.annotation.CheckResult; ++import android.annotation.NonNull; + import android.annotation.Nullable; + import android.app.AppOpsManager; + import android.app.PendingIntent; +@@ -48,11 +49,10 @@ import android.os.IBinder; + import android.os.IDeviceIdleController; + import android.os.IInterface; + import android.os.Parcel; ++import android.os.ParcelFileDescriptor; + import android.os.Process; + import android.os.RemoteException; +-import android.os.ResultReceiver; + import android.os.ServiceManager; +-import android.os.ShellCallback; + import android.os.ShellCommand; + import android.os.UserHandle; + import android.provider.Settings; +@@ -363,10 +363,12 @@ public class CompanionDeviceManagerService extends SystemService implements Bind + } + + @Override +- public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, +- String[] args, ShellCallback callback, ResultReceiver resultReceiver) +- throws RemoteException { +- new ShellCmd().exec(this, in, out, err, args, callback, resultReceiver); ++ public int handleShellCommand(@NonNull ParcelFileDescriptor in, ++ @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, ++ @NonNull String[] args) { ++ return new ShellCmd() ++ .exec(this, in.getFileDescriptor(), out.getFileDescriptor(), ++ err.getFileDescriptor(), args); + } + } + diff --git a/Scripts/LineageOS-17.1/Patch.sh b/Scripts/LineageOS-17.1/Patch.sh index d05fe1da..d7e5bc57 100644 --- a/Scripts/LineageOS-17.1/Patch.sh +++ b/Scripts/LineageOS-17.1/Patch.sh @@ -95,7 +95,7 @@ applyPatch "$DOS_PATCHES_COMMON/android_build/0001-verity-openssl3.patch"; #Fix sed -i '75i$(my_res_package): PRIVATE_AAPT_FLAGS += --auto-add-overlay' core/aapt2.mk; #Enable auto-add-overlay for packages, this allows the vendor overlay to easily work across all branches. awk -i inplace '!/updatable_apex.mk/' target/product/mainline_system.mk; #Disable APEX sed -i 's/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 23/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 28/' core/version_defaults.mk; #Set the minimum supported target SDK to Pie (GrapheneOS) -sed -i 's/2023-02-05/2024-05-05/' core/version_defaults.mk; #Bump Security String #x_asb_2024-05 +sed -i 's/2023-02-05/2024-06-05/' core/version_defaults.mk; #Bump Security String #x_asb_2024-06 fi; if enterAndClear "build/soong"; then @@ -294,6 +294,17 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/392204.patch"; #Q_asb_2024-04 i applyPatch "$DOS_PATCHES/android_frameworks_base/392205.patch"; #Q_asb_2024-04 Fix security vulnerability that creates user with no restrictions when accountOptions are too long. applyPatch "$DOS_PATCHES/android_frameworks_base/393587.patch"; #Q_asb_2024-05 Prioritize system toasts applyPatch "$DOS_PATCHES/android_frameworks_base/393588.patch"; #Q_asb_2024-05 Don't try to show the current toast again while it's showing. +applyPatch "$DOS_PATCHES/android_frameworks_base/394553.patch"; #R_asb_2024-06 DO NOT MERGE: ActivityManager#killBackgroundProcesses can kill caller's own app only +applyPatch "$DOS_PATCHES/android_frameworks_base/394554.patch"; #R_asb_2024-06 DO NOT MERGE: Fix ActivityManager#killBackgroundProcesses permissions +applyPatch "$DOS_PATCHES/android_frameworks_base/394555-backport.patch"; #R_asb_2024-06 Verify URI permission for channel sound update from NotificationListenerService +applyPatch "$DOS_PATCHES/android_frameworks_base/394556-backport.patch"; #R_asb_2024-06 Check for NLS bind permission when rebinding services +applyPatch "$DOS_PATCHES/android_frameworks_base/394557-backport.patch"; #R_asb_2024-06 Hide window immediately if itself doesn't run hide animation #XXX +applyPatch "$DOS_PATCHES/android_frameworks_base/394558-backport.patch"; #R_asb_2024-06 Fix error handling for non-dynamic permissions #XXX +applyPatch "$DOS_PATCHES/android_frameworks_base/394559.patch"; #R_asb_2024-06 Add more checkKeyIntent checks to AccountManagerService. +applyPatch "$DOS_PATCHES/android_frameworks_base/394560.patch"; #R_asb_2024-06 Add in check for intent filter when setting/updating service +applyPatch "$DOS_PATCHES/android_frameworks_base/394561.patch"; #R_asb_2024-06 Check hidden API exemptions +applyPatch "$DOS_PATCHES/android_frameworks_base/394562-backport.patch"; #R_asb_2024-06 AccessibilityManagerService: remove uninstalled services from enabled list after service update. +applyPatch "$DOS_PATCHES/android_frameworks_base/394563-backport.patch"; #R_asb_2024-06 Check permissions for CDM shell commands #applyPatch "$DOS_PATCHES/android_frameworks_base/272645.patch"; #ten-bt-sbc-hd-dualchannel: Add CHANNEL_MODE_DUAL_CHANNEL constant (ValdikSS) #applyPatch "$DOS_PATCHES/android_frameworks_base/272646-forwardport.patch"; #ten-bt-sbc-hd-dualchannel: Add Dual Channel into Bluetooth Audio Channel Mode developer options menu (ValdikSS) #applyPatch "$DOS_PATCHES/android_frameworks_base/272647.patch"; #ten-bt-sbc-hd-dualchannel: Allow SBC as HD audio codec in Bluetooth device configuration (ValdikSS)