1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settingslib.applications;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyInt;
23 import static org.mockito.ArgumentMatchers.anyList;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.spy;
26 import static org.mockito.Mockito.times;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.content.ComponentName;
31 import android.content.Context;
32 import android.content.pm.PackageManager;
33 import android.content.pm.ResolveInfo;
34 import android.content.pm.ServiceInfo;
35 import android.provider.Settings;
36 
37 import androidx.test.core.app.ApplicationProvider;
38 
39 import com.google.common.collect.ImmutableList;
40 
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44 import org.mockito.ArgumentCaptor;
45 import org.robolectric.RobolectricTestRunner;
46 import org.robolectric.RuntimeEnvironment;
47 
48 import java.util.List;
49 
50 @RunWith(RobolectricTestRunner.class)
51 public class ServiceListingTest {
52 
53     private static final String TEST_SETTING = "testSetting";
54     private static final String TEST_INTENT = "com.example.intent";
55 
56     private ServiceListing mServiceListing;
57     private Context mContext;
58     private PackageManager mPm;
59 
60     @Before
setUp()61     public void setUp() {
62         mPm = mock(PackageManager.class);
63         mContext = spy(ApplicationProvider.getApplicationContext());
64         when(mContext.getPackageManager()).thenReturn(mPm);
65 
66         mServiceListing = new ServiceListing.Builder(mContext)
67                 .setTag("testTag")
68                 .setSetting(TEST_SETTING)
69                 .setNoun("testNoun")
70                 .setIntentAction(TEST_INTENT)
71                 .setPermission("testPermission")
72                 .build();
73     }
74 
75     @Test
testValidator()76     public void testValidator() {
77         ServiceInfo s1 = new ServiceInfo();
78         s1.permission = "testPermission";
79         s1.packageName = "pkg";
80         ServiceInfo s2 = new ServiceInfo();
81         s2.permission = "testPermission";
82         s2.packageName = "pkg2";
83         ResolveInfo r1 = new ResolveInfo();
84         r1.serviceInfo = s1;
85         ResolveInfo r2 = new ResolveInfo();
86         r2.serviceInfo = s2;
87 
88         when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(
89                 ImmutableList.of(r1, r2));
90 
91         mServiceListing = new ServiceListing.Builder(mContext)
92                 .setTag("testTag")
93                 .setSetting(TEST_SETTING)
94                 .setNoun("testNoun")
95                 .setIntentAction(TEST_INTENT)
96                 .setValidator(info -> {
97                     if (info.packageName.equals("pkg")) {
98                         return true;
99                     }
100                     return false;
101                 })
102                 .setPermission("testPermission")
103                 .build();
104         ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
105         mServiceListing.addCallback(callback);
106         mServiceListing.reload();
107 
108         verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt());
109         ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class);
110         verify(callback, times(1)).onServicesReloaded(captor.capture());
111 
112         assertThat(captor.getValue().size()).isEqualTo(1);
113         assertThat(captor.getValue().get(0)).isEqualTo(s1);
114     }
115 
116     @Test
testNoValidator()117     public void testNoValidator() {
118         ServiceInfo s1 = new ServiceInfo();
119         s1.permission = "testPermission";
120         s1.packageName = "pkg";
121         ServiceInfo s2 = new ServiceInfo();
122         s2.permission = "testPermission";
123         s2.packageName = "pkg2";
124         ResolveInfo r1 = new ResolveInfo();
125         r1.serviceInfo = s1;
126         ResolveInfo r2 = new ResolveInfo();
127         r2.serviceInfo = s2;
128 
129         when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(
130                 ImmutableList.of(r1, r2));
131 
132         mServiceListing = new ServiceListing.Builder(mContext)
133                 .setTag("testTag")
134                 .setSetting(TEST_SETTING)
135                 .setNoun("testNoun")
136                 .setIntentAction(TEST_INTENT)
137                 .setPermission("testPermission")
138                 .build();
139         ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
140         mServiceListing.addCallback(callback);
141         mServiceListing.reload();
142 
143         verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt());
144         ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class);
145         verify(callback, times(1)).onServicesReloaded(captor.capture());
146 
147         assertThat(captor.getValue().size()).isEqualTo(2);
148     }
149 
150     @Test
testCallback()151     public void testCallback() {
152         ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
153         mServiceListing.addCallback(callback);
154         mServiceListing.reload();
155         verify(callback, times(1)).onServicesReloaded(anyList());
156         mServiceListing.removeCallback(callback);
157         mServiceListing.reload();
158         verify(callback, times(1)).onServicesReloaded(anyList());
159     }
160 
161     @Test
testSaveLoad()162     public void testSaveLoad() {
163         ComponentName testComponent1 = new ComponentName("testPackage1", "testClass1");
164         ComponentName testComponent2 = new ComponentName("testPackage2", "testClass2");
165         Settings.Secure.putString(RuntimeEnvironment.application.getContentResolver(),
166                 TEST_SETTING,
167                 testComponent1.flattenToString() + ":" + testComponent2.flattenToString());
168 
169         mServiceListing.reload();
170 
171         assertThat(mServiceListing.isEnabled(testComponent1)).isTrue();
172         assertThat(mServiceListing.isEnabled(testComponent2)).isTrue();
173         assertThat(Settings.Secure.getString(RuntimeEnvironment.application.getContentResolver(),
174                 TEST_SETTING)).contains(testComponent1.flattenToString());
175         assertThat(Settings.Secure.getString(RuntimeEnvironment.application.getContentResolver(),
176                 TEST_SETTING)).contains(testComponent2.flattenToString());
177 
178         mServiceListing.setEnabled(testComponent1, false);
179 
180         assertThat(mServiceListing.isEnabled(testComponent1)).isFalse();
181         assertThat(mServiceListing.isEnabled(testComponent2)).isTrue();
182         assertThat(Settings.Secure.getString(RuntimeEnvironment.application.getContentResolver(),
183                 TEST_SETTING)).doesNotContain(testComponent1.flattenToString());
184         assertThat(Settings.Secure.getString(RuntimeEnvironment.application.getContentResolver(),
185                 TEST_SETTING)).contains(testComponent2.flattenToString());
186 
187         mServiceListing.setEnabled(testComponent1, true);
188 
189         assertThat(mServiceListing.isEnabled(testComponent1)).isTrue();
190         assertThat(mServiceListing.isEnabled(testComponent2)).isTrue();
191         assertThat(Settings.Secure.getString(RuntimeEnvironment.application.getContentResolver(),
192                 TEST_SETTING)).contains(testComponent1.flattenToString());
193         assertThat(Settings.Secure.getString(RuntimeEnvironment.application.getContentResolver(),
194                 TEST_SETTING)).contains(testComponent2.flattenToString());
195     }
196 }
197