Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3617744d authored by Julia Reynolds's avatar Julia Reynolds Committed by Automerger Merge Worker
Browse files

Merge "Allow filtering of services" into udc-dev am: 46e1caeb

parents 39bff3ef 46e1caeb
Loading
Loading
Loading
Loading
+14 −3
Original line number Original line Diff line number Diff line
@@ -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);
        }
        }
    }
    }
}
}
+97 −1
Original line number Original line Diff line number Diff line
@@ -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);