diff options
| -rw-r--r-- | services/core/java/com/android/server/notification/ManagedServices.java | 12 | ||||
| -rw-r--r-- | services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java | 103 |
2 files changed, 106 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index 83a1df89754c..6539a373fdaf 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -924,7 +924,7 @@ abstract public class ManagedServices { || isPackageOrComponentAllowed(component.getPackageName(), userId))) { return false; } - return componentHasBindPermission(component, userId); + return isValidService(component, userId); } private boolean componentHasBindPermission(ComponentName component, int userId) { @@ -1276,11 +1276,12 @@ abstract public class ManagedServices { if (TextUtils.equals(getPackageName(approvedPackageOrComponent), packageName)) { final ComponentName component = ComponentName.unflattenFromString( approvedPackageOrComponent); - if (component != null && !componentHasBindPermission(component, userId)) { + if (component != null && !isValidService(component, userId)) { approved.removeAt(j); if (DEBUG) { Slog.v(TAG, "Removing " + approvedPackageOrComponent - + " from approved list; no bind permission found " + + " from approved list; no bind permission or " + + "service interface filter found " + mConfig.bindPermission); } } @@ -1299,6 +1300,11 @@ abstract public class ManagedServices { } } + protected boolean isValidService(ComponentName component, int userId) { + return componentHasBindPermission(component, userId) && queryPackageForServices( + component.getPackageName(), userId).contains(component); + } + protected boolean isValidEntry(String packageOrComponent, int userId) { return hasMatchingServices(packageOrComponent, userId); } 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 38ab53be4601..43f7ba26134b 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java @@ -875,7 +875,7 @@ public class ManagedServicesTest extends UiServiceTestCase { return true; }); - mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>()); + mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>()); service.addApprovedList("a", 0, true); service.reregisterService(cn, 0); @@ -906,7 +906,7 @@ public class ManagedServicesTest extends UiServiceTestCase { return true; }); - mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>()); + mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>()); service.addApprovedList("a", 0, false); service.reregisterService(cn, 0); @@ -937,7 +937,7 @@ public class ManagedServicesTest extends UiServiceTestCase { return true; }); - mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>()); + mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>()); service.addApprovedList("a/a", 0, true); service.reregisterService(cn, 0); @@ -968,7 +968,7 @@ public class ManagedServicesTest extends UiServiceTestCase { return true; }); - mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>()); + mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>()); service.addApprovedList("a/a", 0, false); service.reregisterService(cn, 0); @@ -1178,6 +1178,64 @@ public class ManagedServicesTest extends UiServiceTestCase { } @Test + public void testUpgradeAppNoIntentFilterNoRebind() 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<String> 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 serviceInterface intent filter + ManagedServices.Config config = service.getConfig(); + when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())). + thenAnswer(new Answer<List<ResolveInfo>>() { + @Override + public List<ResolveInfo> answer(InvocationOnMock invocationOnMock) + throws Throwable { + Object[] args = invocationOnMock.getArguments(); + Intent invocationIntent = (Intent) args[0]; + if (invocationIntent != null) { + if (invocationIntent.getAction().equals(config.serviceInterface) + && packages.contains(invocationIntent.getPackage())) { + List<ResolveInfo> dummyServices = new ArrayList<>(); + ResolveInfo resolveInfo = new ResolveInfo(); + ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.packageName = invocationIntent.getPackage(); + serviceInfo.name = approvedComponent.getClassName(); + serviceInfo.permission = service.getConfig().bindPermission; + resolveInfo.serviceInfo = serviceInfo; + dummyServices.add(resolveInfo); + return dummyServices; + } + } + return new ArrayList<>(); + } + }); + + // 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}) { ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, @@ -1881,8 +1939,8 @@ public class ManagedServicesTest extends UiServiceTestCase { } private void mockServiceInfoWithMetaData(List<ComponentName> componentNames, - ManagedServices service, ArrayMap<ComponentName, Bundle> metaDatas) - throws RemoteException { + ManagedServices service, PackageManager packageManager, + ArrayMap<ComponentName, Bundle> metaDatas) throws RemoteException { when(mIpm.getServiceInfo(any(), anyLong(), anyInt())).thenAnswer( (Answer<ServiceInfo>) invocation -> { ComponentName invocationCn = invocation.getArgument(0); @@ -1897,6 +1955,39 @@ public class ManagedServicesTest extends UiServiceTestCase { return null; } ); + + // add components to queryIntentServicesAsUser response + final List<String> packages = new ArrayList<>(); + for (ComponentName cn: componentNames) { + packages.add(cn.getPackageName()); + } + ManagedServices.Config config = service.getConfig(); + when(packageManager.queryIntentServicesAsUser(any(), anyInt(), anyInt())). + thenAnswer(new Answer<List<ResolveInfo>>() { + @Override + public List<ResolveInfo> answer(InvocationOnMock invocationOnMock) + throws Throwable { + Object[] args = invocationOnMock.getArguments(); + Intent invocationIntent = (Intent) args[0]; + if (invocationIntent != null) { + if (invocationIntent.getAction().equals(config.serviceInterface) + && packages.contains(invocationIntent.getPackage())) { + List<ResolveInfo> dummyServices = new ArrayList<>(); + for (ComponentName cn: componentNames) { + ResolveInfo resolveInfo = new ResolveInfo(); + ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.packageName = invocationIntent.getPackage(); + serviceInfo.name = cn.getClassName(); + serviceInfo.permission = service.getConfig().bindPermission; + resolveInfo.serviceInfo = serviceInfo; + dummyServices.add(resolveInfo); + } + return dummyServices; + } + } + return new ArrayList<>(); + } + }); } private void resetComponentsAndPackages() { |