1 /*
2  * Copyright (C) 2023 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.settings.notification;
18 
19 import static com.android.settings.notification.NotificationAccessSettings.ALLOWED_KEY;
20 import static com.android.settings.notification.NotificationAccessSettings.NOT_ALLOWED_KEY;
21 
22 import static com.google.common.base.Preconditions.checkNotNull;
23 import static com.google.common.truth.Truth.assertThat;
24 
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.anyInt;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.when;
29 
30 import android.app.NotificationManager;
31 import android.content.ComponentName;
32 import android.content.Context;
33 import android.content.pm.ApplicationInfo;
34 import android.content.pm.PackageManager;
35 import android.content.pm.ServiceInfo;
36 
37 import androidx.fragment.app.FragmentActivity;
38 import androidx.preference.PreferenceCategory;
39 import androidx.preference.PreferenceScreen;
40 
41 import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
42 import com.android.settingslib.bluetooth.LocalBluetoothManager;
43 
44 import com.google.common.base.Strings;
45 
46 import org.junit.Before;
47 import org.junit.Rule;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.mockito.Mock;
51 import org.mockito.junit.MockitoJUnit;
52 import org.mockito.junit.MockitoRule;
53 import org.mockito.stubbing.Answer;
54 import org.robolectric.Robolectric;
55 import org.robolectric.RobolectricTestRunner;
56 import org.robolectric.annotation.Config;
57 import org.robolectric.shadows.ShadowApplication;
58 import org.robolectric.shadows.ShadowLooper;
59 
60 import java.util.ArrayList;
61 
62 @RunWith(RobolectricTestRunner.class)
63 @Config(shadows = {ShadowBluetoothUtils.class})
64 public class NotificationAccessSettingsTest {
65     @Rule
66     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
67 
68     private NotificationAccessSettings mAccessSettings;
69     @Mock
70     private NotificationManager mNotificationManager;
71     @Mock
72     private PackageManager mPackageManager;
73 
74     @Before
setUp()75     public void setUp() throws Exception {
76         ShadowApplication shadowApp = ShadowApplication.getInstance();
77         shadowApp.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
78 
79         mAccessSettings = new NotificationAccessSettings();
80         FragmentActivity activity = Robolectric.buildActivity(FragmentActivity.class).setup().get();
81         activity.getSupportFragmentManager().beginTransaction().add(mAccessSettings, null).commit();
82 
83         when(mPackageManager.getApplicationInfoAsUser(any(), anyInt(), anyInt())).then(
84                 (Answer<ApplicationInfo>) invocation -> {
85                     ApplicationInfo appInfo = mock(ApplicationInfo.class);
86                     when(appInfo.loadLabel(any())).thenReturn(invocation.getArgument(0));
87                     return appInfo;
88                 });
89 
90         mAccessSettings.mNm = mNotificationManager;
91         mAccessSettings.mPm = mPackageManager;
92         ShadowBluetoothUtils.sLocalBluetoothManager = mock(LocalBluetoothManager.class);
93         ShadowLooper.idleMainLooper();
94     }
95 
96     @Test
updateList_enabledLongName_shown()97     public void updateList_enabledLongName_shown() {
98         ComponentName longCn = new ComponentName("test.pkg1",
99                 Strings.repeat("Blah", 200) + "Service");
100         ComponentName shortCn = new ComponentName("test.pkg2", "ReasonableService");
101         ArrayList<ServiceInfo> services = new ArrayList<>();
102         services.add(newServiceInfo(longCn.getPackageName(), longCn.getClassName(), 1));
103         services.add(newServiceInfo(shortCn.getPackageName(), shortCn.getClassName(), 2));
104         when(mNotificationManager.isNotificationListenerAccessGranted(any())).thenReturn(true);
105 
106         mAccessSettings.updateList(services);
107 
108         PreferenceScreen screen = mAccessSettings.getPreferenceScreen();
109         PreferenceCategory allowed = checkNotNull(screen.findPreference(ALLOWED_KEY));
110         PreferenceCategory notAllowed = checkNotNull(screen.findPreference(NOT_ALLOWED_KEY));
111         assertThat(allowed.getPreferenceCount()).isEqualTo(2);
112         assertThat(allowed.getPreference(0).getKey()).isEqualTo(longCn.flattenToString());
113         assertThat(allowed.getPreference(1).getKey()).isEqualTo(shortCn.flattenToString());
114         assertThat(notAllowed.getPreferenceCount()).isEqualTo(0);
115     }
116 
117     @Test
updateList_disabledLongName_notShown()118     public void updateList_disabledLongName_notShown() {
119         ComponentName longCn = new ComponentName("test.pkg1",
120                 Strings.repeat("Blah", 200) + "Service");
121         ComponentName shortCn = new ComponentName("test.pkg2", "ReasonableService");
122         ArrayList<ServiceInfo> services = new ArrayList<>();
123         services.add(newServiceInfo(longCn.getPackageName(), longCn.getClassName(), 1));
124         services.add(newServiceInfo(shortCn.getPackageName(), shortCn.getClassName(), 2));
125         when(mNotificationManager.isNotificationListenerAccessGranted(any())).thenReturn(false);
126 
127         mAccessSettings.updateList(services);
128 
129         PreferenceScreen screen = mAccessSettings.getPreferenceScreen();
130         PreferenceCategory allowed = checkNotNull(screen.findPreference(ALLOWED_KEY));
131         PreferenceCategory notAllowed = checkNotNull(screen.findPreference(NOT_ALLOWED_KEY));
132         assertThat(allowed.getPreferenceCount()).isEqualTo(0);
133         assertThat(notAllowed.getPreferenceCount()).isEqualTo(1);
134         assertThat(notAllowed.getPreference(0).getKey()).isEqualTo(shortCn.flattenToString());
135     }
136 
newServiceInfo(String packageName, String serviceName, int uid)137     private static ServiceInfo newServiceInfo(String packageName, String serviceName, int uid) {
138         ServiceInfo serviceInfo = new ServiceInfo();
139         serviceInfo.packageName = packageName;
140         serviceInfo.name = serviceName;
141         serviceInfo.applicationInfo = new ApplicationInfo();
142         serviceInfo.applicationInfo.uid = uid;
143         return serviceInfo;
144     }
145 }
146