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.settings.notification;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertTrue;
23 import static org.mockito.ArgumentMatchers.anyString;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.when;
26 
27 import android.app.role.RoleManager;
28 import android.app.usage.UsageEvents;
29 import android.bluetooth.BluetoothAdapter;
30 import android.companion.ICompanionDeviceManager;
31 import android.content.ComponentName;
32 import android.content.pm.ApplicationInfo;
33 import android.content.pm.PackageInfo;
34 import android.content.pm.PackageManager;
35 import android.os.Parcel;
36 
37 import com.android.settings.notification.NotificationBackend.AppRow;
38 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
39 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
40 import com.android.settingslib.bluetooth.LocalBluetoothManager;
41 
42 import com.google.common.collect.ImmutableList;
43 
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 import org.mockito.Mock;
48 import org.mockito.MockitoAnnotations;
49 import org.robolectric.RobolectricTestRunner;
50 import org.robolectric.RuntimeEnvironment;
51 
52 import java.util.ArrayList;
53 import java.util.Collection;
54 import java.util.List;
55 
56 @RunWith(RobolectricTestRunner.class)
57 public class NotificationBackendTest {
58 
59     @Mock
60     LocalBluetoothManager mBm;
61     @Mock
62     ICompanionDeviceManager mCdm;
63     @Mock
64     CachedBluetoothDeviceManager mCbm;
65     ComponentName mCn = new ComponentName("a", "b");
66 
67     @Before
setUp()68     public void setUp() {
69         MockitoAnnotations.initMocks(this);
70         when(mBm.getCachedDeviceManager()).thenReturn(mCbm);
71     }
72 
73     @Test
testMarkAppRow_unblockablePackage()74     public void testMarkAppRow_unblockablePackage() {
75         AppRow appRow = new AppRow();
76         String packageName = "foo.bar.unblockable";
77         appRow.pkg = packageName;
78         String[] nonBlockablePkgs = new String[2];
79         nonBlockablePkgs[0] = packageName;
80         nonBlockablePkgs[1] = "some.other.package";
81         NotificationBackend.markAppRowWithBlockables(nonBlockablePkgs, appRow, packageName);
82 
83         // This package has a package lock but no locked channels
84         assertTrue(appRow.lockedImportance);
85     }
86 
87     @Test
testMarkAppRow_defaultPackage()88     public void testMarkAppRow_defaultPackage() {
89         PackageInfo pi = new PackageInfo();
90         pi.packageName = "test";
91         pi.applicationInfo = new ApplicationInfo();
92         pi.applicationInfo.packageName = "test";
93         List<String> roles = new ArrayList<>();
94         roles.add(RoleManager.ROLE_DIALER);
95         RoleManager rm = mock(RoleManager.class);
96         when(rm.getHeldRolesFromController(anyString())).thenReturn(roles);
97 
98         AppRow appRow = new NotificationBackend().loadAppRow(RuntimeEnvironment.application,
99                 mock(PackageManager.class), rm, pi);
100 
101         assertTrue(appRow.systemApp);
102     }
103 
104     @Test
testMarkAppRow_notDefaultPackage()105     public void testMarkAppRow_notDefaultPackage() {
106         PackageInfo pi = new PackageInfo();
107         pi.packageName = "test";
108         pi.applicationInfo = new ApplicationInfo();
109         pi.applicationInfo.packageName = "test";
110         List<String> roles = new ArrayList<>();
111         roles.add(RoleManager.ROLE_HOME);
112         RoleManager rm = mock(RoleManager.class);
113         when(rm.getHeldRolesFromController(anyString())).thenReturn(roles);
114 
115         AppRow appRow = new NotificationBackend().loadAppRow(RuntimeEnvironment.application,
116                 mock(PackageManager.class), rm, pi);
117 
118         assertFalse(appRow.systemApp);
119     }
120 
121     @Test
testGetAggregatedUsageEvents_multipleEventsAgg()122     public void testGetAggregatedUsageEvents_multipleEventsAgg() {
123         List<UsageEvents.Event> events = new ArrayList<>();
124         UsageEvents.Event good = new UsageEvents.Event();
125         good.mEventType = UsageEvents.Event.NOTIFICATION_INTERRUPTION;
126         good.mPackage = "pkg";
127         good.mNotificationChannelId = "channel1";
128         good.mTimeStamp = 2;
129         events.add(good);
130         UsageEvents.Event good2 = new UsageEvents.Event();
131         good2.mEventType = UsageEvents.Event.NOTIFICATION_INTERRUPTION;
132         good2.mPackage = "pkg";
133         good2.mNotificationChannelId = "channel2";
134         good2.mTimeStamp = 3;
135         events.add(good2);
136         UsageEvents.Event good1 = new UsageEvents.Event();
137         good1.mEventType = UsageEvents.Event.NOTIFICATION_INTERRUPTION;
138         good1.mPackage = "pkg";
139         good1.mNotificationChannelId = "channel1";
140         good1.mTimeStamp = 6;
141         events.add(good1);
142         NotificationBackend backend = new NotificationBackend();
143 
144         AppRow appRow = new AppRow();
145         appRow.pkg = "pkg";
146         backend.recordAggregatedUsageEvents(getUsageEvents(events), appRow);
147 
148         assertThat(appRow.sentByChannel.get("channel1").sentCount).isEqualTo(2);
149         assertThat(appRow.sentByChannel.get("channel1").lastSent).isEqualTo(6);
150         assertThat(appRow.sentByChannel.get("channel1").avgSentWeekly).isEqualTo(2);
151         assertThat(appRow.sentByChannel.get("channel2").sentCount).isEqualTo(1);
152         assertThat(appRow.sentByChannel.get("channel2").lastSent).isEqualTo(3);
153         assertThat(appRow.sentByChannel.get("channel2").avgSentWeekly).isEqualTo(1);
154         assertThat(appRow.sentByApp.sentCount).isEqualTo(3);
155         assertThat(appRow.sentByApp.lastSent).isEqualTo(6);
156         assertThat(appRow.sentByApp.avgSentWeekly).isEqualTo(3);
157     }
158 
getUsageEvents(List<UsageEvents.Event> events)159     private UsageEvents getUsageEvents(List<UsageEvents.Event> events) {
160         UsageEvents usageEvents = new UsageEvents(events, new String[] {"pkg"});
161         Parcel parcel = Parcel.obtain();
162         parcel.setDataPosition(0);
163         usageEvents.writeToParcel(parcel, 0);
164         parcel.setDataPosition(0);
165         return UsageEvents.CREATOR.createFromParcel(parcel);
166     }
167 
168     @Test
getDeviceList_noAssociations()169     public void getDeviceList_noAssociations() throws Exception {
170         when(mCdm.getAssociations(mCn.getPackageName(), 0)).thenReturn(null);
171 
172         Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
173         CachedBluetoothDevice cbd1 = mock(CachedBluetoothDevice.class);
174         when(cbd1.getAddress()).thenReturn("00:00:00:00:00:10");
175         when(cbd1.getName()).thenReturn("Device 1");
176         cachedDevices.add(cbd1);
177         when(mCbm.getCachedDevicesCopy()).thenReturn(cachedDevices);
178 
179         BluetoothAdapter.getDefaultAdapter().enable();
180 
181         assertThat(new NotificationBackend().getDeviceList(
182                 mCdm, mBm, mCn.getPackageName(), 0).toString()).isEmpty();
183     }
184 
185     @Test
getDeviceList_associationsButNoDevice()186     public void getDeviceList_associationsButNoDevice() throws Exception {
187         List<String> macs = ImmutableList.of("00:00:00:00:00:10", "00:00:00:00:00:20");
188         when(mCdm.getAssociations(mCn.getPackageName(), 0)).thenReturn(macs);
189 
190         when(mCbm.getCachedDevicesCopy()).thenReturn(new ArrayList<>());
191 
192         assertThat(new NotificationBackend().getDeviceList(
193                 mCdm, mBm, mCn.getPackageName(), 0).toString()).isEmpty();
194     }
195 
196     @Test
getDeviceList_singleDevice()197     public void getDeviceList_singleDevice() throws Exception {
198         List<String> macs = ImmutableList.of("00:00:00:00:00:10", "00:00:00:00:00:20");
199         when(mCdm.getAssociations(mCn.getPackageName(), 0)).thenReturn(macs);
200 
201         Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
202         CachedBluetoothDevice cbd1 = mock(CachedBluetoothDevice.class);
203         when(cbd1.getAddress()).thenReturn(macs.get(0));
204         when(cbd1.getName()).thenReturn("Device 1");
205         cachedDevices.add(cbd1);
206         when(mCbm.getCachedDevicesCopy()).thenReturn(cachedDevices);
207 
208         assertThat(new NotificationBackend().getDeviceList(
209                 mCdm, mBm, mCn.getPackageName(), 0).toString()).isEqualTo("Device 1");
210     }
211 
212     @Test
getDeviceList_multipleDevices()213     public void getDeviceList_multipleDevices() throws Exception {
214         List<String> macs = ImmutableList.of("00:00:00:00:00:10", "00:00:00:00:00:20");
215         when(mCdm.getAssociations(mCn.getPackageName(), 0)).thenReturn(macs);
216 
217         Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
218         CachedBluetoothDevice cbd1 = mock(CachedBluetoothDevice.class);
219         when(cbd1.getAddress()).thenReturn(macs.get(0));
220         when(cbd1.getName()).thenReturn("Device 1");
221         cachedDevices.add(cbd1);
222 
223         CachedBluetoothDevice cbd2 = mock(CachedBluetoothDevice.class);
224         when(cbd2.getAddress()).thenReturn(macs.get(1));
225         when(cbd2.getName()).thenReturn("Device 2");
226         cachedDevices.add(cbd2);
227         when(mCbm.getCachedDevicesCopy()).thenReturn(cachedDevices);
228 
229         assertThat(new NotificationBackend().getDeviceList(
230                 mCdm, mBm, mCn.getPackageName(), 0).toString()).isEqualTo("Device 1, Device 2");
231     }
232 }
233