• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 android.app;
18 
19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
20 
21 import static junit.framework.Assert.assertEquals;
22 import static junit.framework.Assert.assertNotNull;
23 import static junit.framework.Assert.assertNull;
24 
25 import static org.junit.Assert.assertFalse;
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.anyInt;
28 import static org.mockito.ArgumentMatchers.anyString;
29 import static org.mockito.ArgumentMatchers.eq;
30 import static org.mockito.Mockito.times;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
33 
34 import android.content.Intent;
35 import android.content.IntentFilter;
36 import android.media.AudioManager;
37 import android.os.IpcDataCache;
38 import android.os.RemoteException;
39 import android.platform.test.annotations.DisableFlags;
40 import android.platform.test.annotations.EnableFlags;
41 import android.platform.test.flag.junit.SetFlagsRule;
42 
43 import com.android.dx.mockito.inline.extended.ExtendedMockito;
44 import com.android.internal.annotations.Keep;
45 import com.android.modules.utils.testing.ExtendedMockitoRule;
46 
47 import junitparams.JUnitParamsRunner;
48 import junitparams.Parameters;
49 
50 import org.junit.Before;
51 import org.junit.Rule;
52 import org.junit.Test;
53 import org.junit.runner.RunWith;
54 import org.mockito.Mock;
55 
56 @RunWith(JUnitParamsRunner.class)
57 public class BroadcastStickyCacheTest {
58 
59     @Rule
60     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
61     @Rule
62     public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
63             .mockStatic(IpcDataCache.class)
64             .mockStatic(ActivityManager.class)
65             .build();
66 
67     @Mock
68     private IActivityManager mActivityManagerMock;
69 
70     @Mock
71     private IApplicationThread mIApplicationThreadMock;
72 
73     @Keep
stickyBroadcastList()74     private static Object stickyBroadcastList() {
75         return BroadcastStickyCache.STICKY_BROADCAST_ACTIONS;
76     }
77 
78     @Before
setUp()79     public void setUp() {
80         BroadcastStickyCache.clearCacheForTest();
81 
82         doNothing().when(() -> IpcDataCache.invalidateCache(anyString(), anyString()));
83     }
84 
85     @Test
86     @DisableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
useCache_flagDisabled_returnsFalse()87     public void useCache_flagDisabled_returnsFalse() {
88         assertFalse(BroadcastStickyCache.useCache(new IntentFilter(Intent.ACTION_BATTERY_CHANGED)));
89     }
90 
91     @Test
92     @EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
useCache_nullFilter_returnsFalse()93     public void useCache_nullFilter_returnsFalse() {
94         assertFalse(BroadcastStickyCache.useCache(null));
95     }
96 
97     @Test
98     @EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
useCache_filterWithoutAction_returnsFalse()99     public void useCache_filterWithoutAction_returnsFalse() {
100         assertFalse(BroadcastStickyCache.useCache(new IntentFilter()));
101     }
102 
103     @Test
104     @EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
useCache_filterWithoutStickyBroadcastAction_returnsFalse()105     public void useCache_filterWithoutStickyBroadcastAction_returnsFalse() {
106         assertFalse(BroadcastStickyCache.useCache(new IntentFilter(Intent.ACTION_BOOT_COMPLETED)));
107     }
108 
109     @Test
110     @DisableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
invalidateCache_flagDisabled_cacheNotInvalidated()111     public void invalidateCache_flagDisabled_cacheNotInvalidated() {
112         final String apiName = BroadcastStickyCache.sActionApiNameMap.get(
113                 AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
114 
115         BroadcastStickyCache.invalidateCache(
116                 AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
117 
118         ExtendedMockito.verify(
119                 () -> IpcDataCache.invalidateCache(eq(IpcDataCache.MODULE_SYSTEM), eq(apiName)),
120                 times(0));
121     }
122 
123     @Test
124     @EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
invalidateCache_broadcastNotSticky_cacheNotInvalidated()125     public void invalidateCache_broadcastNotSticky_cacheNotInvalidated() {
126         BroadcastStickyCache.invalidateCache(Intent.ACTION_AIRPLANE_MODE_CHANGED);
127 
128         ExtendedMockito.verify(
129                 () -> IpcDataCache.invalidateCache(eq(IpcDataCache.MODULE_SYSTEM), anyString()),
130                 times(0));
131     }
132 
133     @Test
134     @EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
invalidateCache_withStickyBroadcast_cacheInvalidated()135     public void invalidateCache_withStickyBroadcast_cacheInvalidated() {
136         final String apiName = BroadcastStickyCache.sActionApiNameMap.get(
137                 Intent.ACTION_BATTERY_CHANGED);
138 
139         BroadcastStickyCache.invalidateCache(Intent.ACTION_BATTERY_CHANGED);
140 
141         ExtendedMockito.verify(
142                 () -> IpcDataCache.invalidateCache(eq(IpcDataCache.MODULE_SYSTEM), eq(apiName)),
143                 times(1));
144     }
145 
146     @Test
invalidateAllCaches_cacheInvalidated()147     public void invalidateAllCaches_cacheInvalidated() {
148         BroadcastStickyCache.invalidateAllCaches();
149 
150         for (int i = BroadcastStickyCache.sActionApiNameMap.size() - 1; i > -1; i--) {
151             final String apiName = BroadcastStickyCache.sActionApiNameMap.valueAt(i);
152             ExtendedMockito.verify(() -> IpcDataCache.invalidateCache(anyString(),
153                     eq(apiName)), times(1));
154         }
155     }
156 
157     @Test
158     @Parameters(method = "stickyBroadcastList")
getIntent_createNewCache_verifyRegisterReceiverIsCalled(String action)159     public void getIntent_createNewCache_verifyRegisterReceiverIsCalled(String action)
160             throws RemoteException {
161         setActivityManagerMock(action);
162         final IntentFilter filter = new IntentFilter(action);
163         final Intent intent = queryIntent(filter);
164 
165         assertNotNull(intent);
166         assertEquals(intent.getAction(), action);
167         verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
168                 eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
169                 eq(filter), anyString(), anyInt(), anyInt());
170     }
171 
172     @Test
getIntent_querySameValueTwice_verifyRegisterReceiverIsCalledOnce()173     public void getIntent_querySameValueTwice_verifyRegisterReceiverIsCalledOnce()
174             throws RemoteException {
175         setActivityManagerMock(Intent.ACTION_DEVICE_STORAGE_LOW);
176         final Intent intent = queryIntent(new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW));
177         final Intent cachedIntent = queryIntent(new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW));
178 
179         assertNotNull(intent);
180         assertEquals(intent.getAction(), Intent.ACTION_DEVICE_STORAGE_LOW);
181         assertNotNull(cachedIntent);
182         assertEquals(cachedIntent.getAction(), Intent.ACTION_DEVICE_STORAGE_LOW);
183 
184         verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
185                 eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
186                 any(), anyString(), anyInt(), anyInt());
187     }
188 
189     @Test
getIntent_queryActionTwiceWithNullResult_verifyRegisterReceiverIsCalledOnce()190     public void getIntent_queryActionTwiceWithNullResult_verifyRegisterReceiverIsCalledOnce()
191             throws RemoteException {
192         setActivityManagerMock(null);
193         final Intent intent = queryIntent(new IntentFilter(Intent.ACTION_DEVICE_STORAGE_FULL));
194         final Intent cachedIntent = queryIntent(
195                 new IntentFilter(Intent.ACTION_DEVICE_STORAGE_FULL));
196 
197         assertNull(intent);
198         assertNull(cachedIntent);
199 
200         verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
201                 eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
202                 any(), anyString(), anyInt(), anyInt());
203     }
204 
205     @Test
getIntent_querySameActionWithDifferentFilter_verifyRegisterReceiverCalledTwice()206     public void getIntent_querySameActionWithDifferentFilter_verifyRegisterReceiverCalledTwice()
207             throws RemoteException {
208         setActivityManagerMock(Intent.ACTION_DEVICE_STORAGE_LOW);
209         final IntentFilter filter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
210         final Intent intent = queryIntent(filter);
211 
212         final IntentFilter newFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
213         newFilter.addDataScheme("file");
214         final Intent newIntent = queryIntent(newFilter);
215 
216         assertNotNull(intent);
217         assertEquals(intent.getAction(), Intent.ACTION_DEVICE_STORAGE_LOW);
218         assertNotNull(newIntent);
219         assertEquals(newIntent.getAction(), Intent.ACTION_DEVICE_STORAGE_LOW);
220 
221         verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
222                 eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
223                 eq(filter), anyString(), anyInt(), anyInt());
224 
225         verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
226                 eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
227                 eq(newFilter), anyString(), anyInt(), anyInt());
228     }
229 
queryIntent(IntentFilter filter)230     private Intent queryIntent(IntentFilter filter) {
231         return BroadcastStickyCache.getIntent(
232                 mIApplicationThreadMock,
233                 "android",
234                 "android",
235                 filter,
236                 "system",
237                 0,
238                 0
239         );
240     }
241 
setActivityManagerMock(String action)242     private void setActivityManagerMock(String action) throws RemoteException {
243         when(ActivityManager.getService()).thenReturn(mActivityManagerMock);
244         when(mActivityManagerMock.registerReceiverWithFeature(any(), anyString(),
245                 anyString(), anyString(), any(), any(), anyString(), anyInt(),
246                 anyInt())).thenReturn(action != null ? new Intent(action) : null);
247     }
248 }
249