Merge "Allow filtering of services" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
9fa258770e
@@ -35,6 +35,7 @@ import android.util.Slog;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for managing services matching a given intent and requesting a given permission.
|
* Class for managing services matching a given intent and requesting a given permission.
|
||||||
@@ -51,12 +52,13 @@ public class ServiceListing {
|
|||||||
private final HashSet<ComponentName> mEnabledServices = new HashSet<>();
|
private final HashSet<ComponentName> mEnabledServices = new HashSet<>();
|
||||||
private final List<ServiceInfo> mServices = new ArrayList<>();
|
private final List<ServiceInfo> mServices = new ArrayList<>();
|
||||||
private final List<Callback> mCallbacks = new ArrayList<>();
|
private final List<Callback> mCallbacks = new ArrayList<>();
|
||||||
|
private final Predicate mValidator;
|
||||||
|
|
||||||
private boolean mListening;
|
private boolean mListening;
|
||||||
|
|
||||||
private ServiceListing(Context context, String tag,
|
private ServiceListing(Context context, String tag,
|
||||||
String setting, String intentAction, String permission, String noun,
|
String setting, String intentAction, String permission, String noun,
|
||||||
boolean addDeviceLockedFlags) {
|
boolean addDeviceLockedFlags, Predicate validator) {
|
||||||
mContentResolver = context.getContentResolver();
|
mContentResolver = context.getContentResolver();
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mTag = tag;
|
mTag = tag;
|
||||||
@@ -65,6 +67,7 @@ public class ServiceListing {
|
|||||||
mPermission = permission;
|
mPermission = permission;
|
||||||
mNoun = noun;
|
mNoun = noun;
|
||||||
mAddDeviceLockedFlags = addDeviceLockedFlags;
|
mAddDeviceLockedFlags = addDeviceLockedFlags;
|
||||||
|
mValidator = validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCallback(Callback callback) {
|
public void addCallback(Callback callback) {
|
||||||
@@ -137,7 +140,6 @@ public class ServiceListing {
|
|||||||
final PackageManager pmWrapper = mContext.getPackageManager();
|
final PackageManager pmWrapper = mContext.getPackageManager();
|
||||||
List<ResolveInfo> installedServices = pmWrapper.queryIntentServicesAsUser(
|
List<ResolveInfo> installedServices = pmWrapper.queryIntentServicesAsUser(
|
||||||
new Intent(mIntentAction), flags, user);
|
new Intent(mIntentAction), flags, user);
|
||||||
|
|
||||||
for (ResolveInfo resolveInfo : installedServices) {
|
for (ResolveInfo resolveInfo : installedServices) {
|
||||||
ServiceInfo info = resolveInfo.serviceInfo;
|
ServiceInfo info = resolveInfo.serviceInfo;
|
||||||
|
|
||||||
@@ -148,6 +150,9 @@ public class ServiceListing {
|
|||||||
+ mPermission);
|
+ mPermission);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (mValidator != null && !mValidator.test(info)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
mServices.add(info);
|
mServices.add(info);
|
||||||
}
|
}
|
||||||
for (Callback callback : mCallbacks) {
|
for (Callback callback : mCallbacks) {
|
||||||
@@ -194,6 +199,7 @@ public class ServiceListing {
|
|||||||
private String mPermission;
|
private String mPermission;
|
||||||
private String mNoun;
|
private String mNoun;
|
||||||
private boolean mAddDeviceLockedFlags = false;
|
private boolean mAddDeviceLockedFlags = false;
|
||||||
|
private Predicate mValidator;
|
||||||
|
|
||||||
public Builder(Context context) {
|
public Builder(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@@ -224,6 +230,11 @@ public class ServiceListing {
|
|||||||
return this;
|
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
|
* 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
|
* MATCH_DIRECT_BOOT_UNAWARE flags when querying PackageManager. Required to get results
|
||||||
@@ -236,7 +247,7 @@ public class ServiceListing {
|
|||||||
|
|
||||||
public ServiceListing build() {
|
public ServiceListing build() {
|
||||||
return new ServiceListing(mContext, mTag, mSetting, mIntentAction, mPermission, mNoun,
|
return new ServiceListing(mContext, mTag, mSetting, mIntentAction, mPermission, mNoun,
|
||||||
mAddDeviceLockedFlags);
|
mAddDeviceLockedFlags, mValidator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ android_robolectric_test {
|
|||||||
srcs: ["src/**/*.java"],
|
srcs: ["src/**/*.java"],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"SettingsLib-robo-testutils",
|
"SettingsLib-robo-testutils",
|
||||||
|
"androidx.test.core",
|
||||||
],
|
],
|
||||||
java_resource_dirs: ["config"],
|
java_resource_dirs: ["config"],
|
||||||
instrumentation_for: "SettingsLibShell",
|
instrumentation_for: "SettingsLibShell",
|
||||||
|
|||||||
@@ -18,20 +18,35 @@ package com.android.settingslib.applications;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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.ArgumentMatchers.anyList;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.ComponentName;
|
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 android.provider.Settings;
|
||||||
|
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class ServiceListingTest {
|
public class ServiceListingTest {
|
||||||
|
|
||||||
@@ -39,10 +54,16 @@ public class ServiceListingTest {
|
|||||||
private static final String TEST_INTENT = "com.example.intent";
|
private static final String TEST_INTENT = "com.example.intent";
|
||||||
|
|
||||||
private ServiceListing mServiceListing;
|
private ServiceListing mServiceListing;
|
||||||
|
private Context mContext;
|
||||||
|
private PackageManager mPm;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
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")
|
.setTag("testTag")
|
||||||
.setSetting(TEST_SETTING)
|
.setSetting(TEST_SETTING)
|
||||||
.setNoun("testNoun")
|
.setNoun("testNoun")
|
||||||
@@ -51,6 +72,81 @@ public class ServiceListingTest {
|
|||||||
.build();
|
.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
|
@Test
|
||||||
public void testCallback() {
|
public void testCallback() {
|
||||||
ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
|
ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
|
||||||
|
|||||||
Reference in New Issue
Block a user