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 com.android.phone.security;
18 
19 import static android.safetycenter.SafetyCenterManager.ACTION_REFRESH_SAFETY_SOURCES;
20 import static android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID;
21 
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.never;
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.Context;
31 import android.content.Intent;
32 import android.content.pm.PackageManager;
33 import android.platform.test.flag.junit.SetFlagsRule;
34 
35 import androidx.test.ext.junit.runners.AndroidJUnit4;
36 
37 import com.android.internal.telephony.Phone;
38 import com.android.internal.telephony.flags.Flags;
39 
40 import org.junit.Before;
41 import org.junit.Rule;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44 import org.mockito.Answers;
45 import org.mockito.Mock;
46 import org.mockito.MockitoAnnotations;
47 
48 @RunWith(AndroidJUnit4.class)
49 public class SafetySourceReceiverTest {
50     @Rule
51     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
52 
53     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
54     Context mContext;
55 
56     SafetySourceReceiver mSafetySourceReceiver;
57 
58     @Before
setUp()59     public void setUp() throws Exception {
60         MockitoAnnotations.initMocks(this);
61         SafetySourceReceiver receiver = new SafetySourceReceiver();
62         mSafetySourceReceiver = spy(receiver);
63 
64         when(mContext.getPackageManager().hasSystemFeature(
65                 PackageManager.FEATURE_TELEPHONY)).thenReturn(true);
66     }
67 
68     @Test
testOnReceive()69     public void testOnReceive() {
70         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS,
71                 Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS,
72                 Flags.FLAG_ENFORCE_TELEPHONY_FEATURE_MAPPING_FOR_PUBLIC_APIS);
73         Phone mockPhone = mock(Phone.class);
74         when(mSafetySourceReceiver.getDefaultPhone()).thenReturn(mockPhone);
75 
76         Intent intent = new Intent(ACTION_REFRESH_SAFETY_SOURCES);
77         intent.putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, "aBroadcastId");
78         mSafetySourceReceiver.onReceive(mContext, intent);
79 
80         verify(mockPhone, times(1)).refreshSafetySources("aBroadcastId");
81     }
82 
83     @Test
testOnReceive_featureFlagsOff()84     public void testOnReceive_featureFlagsOff() {
85         mSetFlagsRule.disableFlags(
86                 Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS,
87                 Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS,
88                 Flags.FLAG_ENFORCE_TELEPHONY_FEATURE_MAPPING_FOR_PUBLIC_APIS);
89 
90         Intent intent = new Intent(ACTION_REFRESH_SAFETY_SOURCES);
91         intent.putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, "aBroadcastId");
92         mSafetySourceReceiver.onReceive(mContext, intent);
93 
94         verify(mSafetySourceReceiver, never()).getDefaultPhone();
95     }
96 
97     @Test
testOnReceive_phoneNotReadyYet()98     public void testOnReceive_phoneNotReadyYet() {
99         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS,
100                 Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS,
101                 Flags.FLAG_ENFORCE_TELEPHONY_FEATURE_MAPPING_FOR_PUBLIC_APIS);
102         when(mSafetySourceReceiver.getDefaultPhone()).thenReturn(null);
103 
104         Intent intent = new Intent(ACTION_REFRESH_SAFETY_SOURCES);
105         intent.putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, "aBroadcastId");
106 
107         // this call succeeding without a NPE means this test has passed. There are no observable
108         // side effects to a null Phone, because all side effects happen on the Phone instance.
109         mSafetySourceReceiver.onReceive(mContext, intent);
110     }
111 
112     @Test
testOnReceive_noTelephonyFeature()113     public void testOnReceive_noTelephonyFeature() {
114         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS,
115                 Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS,
116                 Flags.FLAG_ENFORCE_TELEPHONY_FEATURE_MAPPING_FOR_PUBLIC_APIS);
117 
118         when(mContext.getPackageManager().hasSystemFeature(
119                 PackageManager.FEATURE_TELEPHONY)).thenReturn(false);
120 
121         Phone mockPhone = mock(Phone.class);
122         when(mSafetySourceReceiver.getDefaultPhone()).thenReturn(mockPhone);
123 
124         Intent intent = new Intent(ACTION_REFRESH_SAFETY_SOURCES);
125         intent.putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, "aBroadcastId");
126         mSafetySourceReceiver.onReceive(mContext, intent);
127 
128         verify(mockPhone, never()).refreshSafetySources(any());
129     }
130 }
131