Loading packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java +14 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.util.Slog; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.function.Predicate; /** * Class for managing services matching a given intent and requesting a given permission. Loading @@ -51,12 +52,13 @@ public class ServiceListing { private final HashSet<ComponentName> mEnabledServices = new HashSet<>(); private final List<ServiceInfo> mServices = new ArrayList<>(); private final List<Callback> mCallbacks = new ArrayList<>(); private final Predicate mValidator; private boolean mListening; private ServiceListing(Context context, String tag, String setting, String intentAction, String permission, String noun, boolean addDeviceLockedFlags) { boolean addDeviceLockedFlags, Predicate validator) { mContentResolver = context.getContentResolver(); mContext = context; mTag = tag; Loading @@ -65,6 +67,7 @@ public class ServiceListing { mPermission = permission; mNoun = noun; mAddDeviceLockedFlags = addDeviceLockedFlags; mValidator = validator; } public void addCallback(Callback callback) { Loading Loading @@ -137,7 +140,6 @@ public class ServiceListing { final PackageManager pmWrapper = mContext.getPackageManager(); List<ResolveInfo> installedServices = pmWrapper.queryIntentServicesAsUser( new Intent(mIntentAction), flags, user); for (ResolveInfo resolveInfo : installedServices) { ServiceInfo info = resolveInfo.serviceInfo; Loading @@ -148,6 +150,9 @@ public class ServiceListing { + mPermission); continue; } if (mValidator != null && !mValidator.test(info)) { continue; } mServices.add(info); } for (Callback callback : mCallbacks) { Loading Loading @@ -194,6 +199,7 @@ public class ServiceListing { private String mPermission; private String mNoun; private boolean mAddDeviceLockedFlags = false; private Predicate mValidator; public Builder(Context context) { mContext = context; Loading Loading @@ -224,6 +230,11 @@ public class ServiceListing { return this; } public Builder setValidator(Predicate<ServiceInfo> validator) { mValidator = validator; return this; } /** * Set to true to add support for both MATCH_DIRECT_BOOT_AWARE and * MATCH_DIRECT_BOOT_UNAWARE flags when querying PackageManager. Required to get results Loading @@ -236,7 +247,7 @@ public class ServiceListing { public ServiceListing build() { return new ServiceListing(mContext, mTag, mSetting, mIntentAction, mPermission, mNoun, mAddDeviceLockedFlags); mAddDeviceLockedFlags, mValidator); } } } packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java +97 −1 Original line number Diff line number Diff line Loading @@ -18,20 +18,35 @@ package com.android.settingslib.applications; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; import com.google.common.collect.ImmutableList; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import java.util.List; @RunWith(RobolectricTestRunner.class) public class ServiceListingTest { Loading @@ -39,10 +54,16 @@ public class ServiceListingTest { private static final String TEST_INTENT = "com.example.intent"; private ServiceListing mServiceListing; private Context mContext; private PackageManager mPm; @Before public void setUp() { mServiceListing = new ServiceListing.Builder(RuntimeEnvironment.application) mPm = mock(PackageManager.class); mContext = spy(ApplicationProvider.getApplicationContext()); when(mContext.getPackageManager()).thenReturn(mPm); mServiceListing = new ServiceListing.Builder(mContext) .setTag("testTag") .setSetting(TEST_SETTING) .setNoun("testNoun") Loading @@ -51,6 +72,81 @@ public class ServiceListingTest { .build(); } @Test public void testValidator() { ServiceInfo s1 = new ServiceInfo(); s1.permission = "testPermission"; s1.packageName = "pkg"; ServiceInfo s2 = new ServiceInfo(); s2.permission = "testPermission"; s2.packageName = "pkg2"; ResolveInfo r1 = new ResolveInfo(); r1.serviceInfo = s1; ResolveInfo r2 = new ResolveInfo(); r2.serviceInfo = s2; when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn( ImmutableList.of(r1, r2)); mServiceListing = new ServiceListing.Builder(mContext) .setTag("testTag") .setSetting(TEST_SETTING) .setNoun("testNoun") .setIntentAction(TEST_INTENT) .setValidator(info -> { if (info.packageName.equals("pkg")) { return true; } return false; }) .setPermission("testPermission") .build(); ServiceListing.Callback callback = mock(ServiceListing.Callback.class); mServiceListing.addCallback(callback); mServiceListing.reload(); verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt()); ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class); verify(callback, times(1)).onServicesReloaded(captor.capture()); assertThat(captor.getValue().size()).isEqualTo(1); assertThat(captor.getValue().get(0)).isEqualTo(s1); } @Test public void testNoValidator() { ServiceInfo s1 = new ServiceInfo(); s1.permission = "testPermission"; s1.packageName = "pkg"; ServiceInfo s2 = new ServiceInfo(); s2.permission = "testPermission"; s2.packageName = "pkg2"; ResolveInfo r1 = new ResolveInfo(); r1.serviceInfo = s1; ResolveInfo r2 = new ResolveInfo(); r2.serviceInfo = s2; when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn( ImmutableList.of(r1, r2)); mServiceListing = new ServiceListing.Builder(mContext) .setTag("testTag") .setSetting(TEST_SETTING) .setNoun("testNoun") .setIntentAction(TEST_INTENT) .setPermission("testPermission") .build(); ServiceListing.Callback callback = mock(ServiceListing.Callback.class); mServiceListing.addCallback(callback); mServiceListing.reload(); verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt()); ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class); verify(callback, times(1)).onServicesReloaded(captor.capture()); assertThat(captor.getValue().size()).isEqualTo(2); } @Test public void testCallback() { ServiceListing.Callback callback = mock(ServiceListing.Callback.class); Loading Loading
packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java +14 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.util.Slog; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.function.Predicate; /** * Class for managing services matching a given intent and requesting a given permission. Loading @@ -51,12 +52,13 @@ public class ServiceListing { private final HashSet<ComponentName> mEnabledServices = new HashSet<>(); private final List<ServiceInfo> mServices = new ArrayList<>(); private final List<Callback> mCallbacks = new ArrayList<>(); private final Predicate mValidator; private boolean mListening; private ServiceListing(Context context, String tag, String setting, String intentAction, String permission, String noun, boolean addDeviceLockedFlags) { boolean addDeviceLockedFlags, Predicate validator) { mContentResolver = context.getContentResolver(); mContext = context; mTag = tag; Loading @@ -65,6 +67,7 @@ public class ServiceListing { mPermission = permission; mNoun = noun; mAddDeviceLockedFlags = addDeviceLockedFlags; mValidator = validator; } public void addCallback(Callback callback) { Loading Loading @@ -137,7 +140,6 @@ public class ServiceListing { final PackageManager pmWrapper = mContext.getPackageManager(); List<ResolveInfo> installedServices = pmWrapper.queryIntentServicesAsUser( new Intent(mIntentAction), flags, user); for (ResolveInfo resolveInfo : installedServices) { ServiceInfo info = resolveInfo.serviceInfo; Loading @@ -148,6 +150,9 @@ public class ServiceListing { + mPermission); continue; } if (mValidator != null && !mValidator.test(info)) { continue; } mServices.add(info); } for (Callback callback : mCallbacks) { Loading Loading @@ -194,6 +199,7 @@ public class ServiceListing { private String mPermission; private String mNoun; private boolean mAddDeviceLockedFlags = false; private Predicate mValidator; public Builder(Context context) { mContext = context; Loading Loading @@ -224,6 +230,11 @@ public class ServiceListing { return this; } public Builder setValidator(Predicate<ServiceInfo> validator) { mValidator = validator; return this; } /** * Set to true to add support for both MATCH_DIRECT_BOOT_AWARE and * MATCH_DIRECT_BOOT_UNAWARE flags when querying PackageManager. Required to get results Loading @@ -236,7 +247,7 @@ public class ServiceListing { public ServiceListing build() { return new ServiceListing(mContext, mTag, mSetting, mIntentAction, mPermission, mNoun, mAddDeviceLockedFlags); mAddDeviceLockedFlags, mValidator); } } }
packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java +97 −1 Original line number Diff line number Diff line Loading @@ -18,20 +18,35 @@ package com.android.settingslib.applications; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; import com.google.common.collect.ImmutableList; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import java.util.List; @RunWith(RobolectricTestRunner.class) public class ServiceListingTest { Loading @@ -39,10 +54,16 @@ public class ServiceListingTest { private static final String TEST_INTENT = "com.example.intent"; private ServiceListing mServiceListing; private Context mContext; private PackageManager mPm; @Before public void setUp() { mServiceListing = new ServiceListing.Builder(RuntimeEnvironment.application) mPm = mock(PackageManager.class); mContext = spy(ApplicationProvider.getApplicationContext()); when(mContext.getPackageManager()).thenReturn(mPm); mServiceListing = new ServiceListing.Builder(mContext) .setTag("testTag") .setSetting(TEST_SETTING) .setNoun("testNoun") Loading @@ -51,6 +72,81 @@ public class ServiceListingTest { .build(); } @Test public void testValidator() { ServiceInfo s1 = new ServiceInfo(); s1.permission = "testPermission"; s1.packageName = "pkg"; ServiceInfo s2 = new ServiceInfo(); s2.permission = "testPermission"; s2.packageName = "pkg2"; ResolveInfo r1 = new ResolveInfo(); r1.serviceInfo = s1; ResolveInfo r2 = new ResolveInfo(); r2.serviceInfo = s2; when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn( ImmutableList.of(r1, r2)); mServiceListing = new ServiceListing.Builder(mContext) .setTag("testTag") .setSetting(TEST_SETTING) .setNoun("testNoun") .setIntentAction(TEST_INTENT) .setValidator(info -> { if (info.packageName.equals("pkg")) { return true; } return false; }) .setPermission("testPermission") .build(); ServiceListing.Callback callback = mock(ServiceListing.Callback.class); mServiceListing.addCallback(callback); mServiceListing.reload(); verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt()); ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class); verify(callback, times(1)).onServicesReloaded(captor.capture()); assertThat(captor.getValue().size()).isEqualTo(1); assertThat(captor.getValue().get(0)).isEqualTo(s1); } @Test public void testNoValidator() { ServiceInfo s1 = new ServiceInfo(); s1.permission = "testPermission"; s1.packageName = "pkg"; ServiceInfo s2 = new ServiceInfo(); s2.permission = "testPermission"; s2.packageName = "pkg2"; ResolveInfo r1 = new ResolveInfo(); r1.serviceInfo = s1; ResolveInfo r2 = new ResolveInfo(); r2.serviceInfo = s2; when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn( ImmutableList.of(r1, r2)); mServiceListing = new ServiceListing.Builder(mContext) .setTag("testTag") .setSetting(TEST_SETTING) .setNoun("testNoun") .setIntentAction(TEST_INTENT) .setPermission("testPermission") .build(); ServiceListing.Callback callback = mock(ServiceListing.Callback.class); mServiceListing.addCallback(callback); mServiceListing.reload(); verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt()); ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class); verify(callback, times(1)).onServicesReloaded(captor.capture()); assertThat(captor.getValue().size()).isEqualTo(2); } @Test public void testCallback() { ServiceListing.Callback callback = mock(ServiceListing.Callback.class); Loading