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 android.telecom.cts;
18 
19 import static android.telecom.DisconnectCauseEnum.LOCAL;
20 import static android.telecom.DisconnectCauseEnum.UNKNOWN;
21 
22 import static com.google.common.truth.Truth.assertThat;
23 
24 import static org.junit.Assert.assertEquals;
25 
26 import android.cts.statsdatom.lib.AtomTestUtils;
27 import android.cts.statsdatom.lib.ConfigUtils;
28 import android.cts.statsdatom.lib.DeviceUtils;
29 import android.cts.statsdatom.lib.ReportUtils;
30 
31 import com.android.compatibility.common.util.NonApiTest;
32 import com.android.os.AtomsProto;
33 import com.android.os.StatsLog.EventMetricData;
34 import com.android.os.telecom.EmergencyNumberDialed;
35 import com.android.os.telecom.TelecomExtensionAtom;
36 import com.android.tradefed.log.LogUtil.CLog;
37 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
38 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
39 import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
40 import com.android.tradefed.util.RunUtil;
41 
42 import com.google.protobuf.ExtensionRegistry;
43 
44 import org.junit.After;
45 import org.junit.Before;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 
49 import java.util.List;
50 
51 /** Tests for Telecom metrics atom logging to statsd */
52 @NonApiTest(
53         exemptionReasons = {},
54         justification = "METRIC")
55 @RunWith(DeviceJUnit4ClassRunner.class)
56 public class TelecomHostStatsTest extends BaseHostJUnit4Test {
57 
58     private static final String TELECOM_CTS_TEST_PKG = "android.telecom.cts";
59     private static final String FEATURE_TELECOM = "android.software.telecom";
60     private static final String FEATURE_TELEPHONY = "android.hardware.telephony";
61     private static final String FEATURE_TELEPHONY_CALLING = "android.hardware.telephony.calling";
62 
63     @Before
setUp()64     public void setUp() throws Exception {
65         ConfigUtils.removeConfig(getDevice());
66         ReportUtils.clearReports(getDevice());
67         RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG);
68     }
69 
70     @After
tearDown()71     public void tearDown() throws Exception {
72         ConfigUtils.removeConfig(getDevice());
73         ReportUtils.clearReports(getDevice());
74     }
75 
76     // basic verification of CallStateChanged atom
77     // being logged to statsd when a call is made
78     @Test
testCallStateChangedAtom_basicTest()79     public void testCallStateChangedAtom_basicTest() throws Exception {
80         if (!DeviceUtils.hasFeature(getDevice(), FEATURE_TELECOM) || !DeviceUtils.hasFeature(
81                 getDevice(), FEATURE_TELEPHONY) || !DeviceUtils.hasFeature(getDevice(),
82                 FEATURE_TELEPHONY_CALLING)) {
83             return;
84         }
85 
86         ConfigUtils.uploadConfigForPushedAtom(
87                 getDevice(), TELECOM_CTS_TEST_PKG, AtomsProto.Atom.CALL_STATE_CHANGED_FIELD_NUMBER);
88 
89         // run CTS test case for outgoing call
90         runDeviceTests(new DeviceTestRunOptions(TELECOM_CTS_TEST_PKG)
91                 .setDevice(getDevice())
92                 .setDisableHiddenApiCheck(true)
93                 .setTestClassName("android.telecom.cts.OutgoingCallTest")
94                 .setTestMethodName("testStartCallWithSpeakerphoneTrue_SpeakerphoneOnInCall"));
95 
96         RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG);
97         // Verify that we have three atoma for  callstatechange
98         List<EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
99         AtomsProto.CallStateChanged callStateChangedAtom = null;
100         CLog.d("metrics list size: " + data.size());
101 
102         assertEquals(data.size(), 3); // DIALING, CONNECTING, DISCONNECTED
103 
104         boolean state_dialing = false, state_connecting = false, state_disconnected = false;
105         for (EventMetricData d : data) {
106             callStateChangedAtom = d.getAtom().getCallStateChanged();
107 
108             // common checks
109             assertThat(callStateChangedAtom.getEmergencyCall()).isFalse();
110             assertThat(callStateChangedAtom.getSelfManaged()).isFalse();
111             assertThat(callStateChangedAtom.getExternalCall()).isFalse();
112             assertThat(callStateChangedAtom.getExistingCallCount()).isEqualTo(0);
113             assertThat(callStateChangedAtom.getHeldCallCount()).isEqualTo(0);
114 
115             switch (callStateChangedAtom.getCallState()) {
116                 case CONNECTING:
117                     assertThat(state_connecting).isFalse();
118                     state_connecting = true;
119                     assertThat(callStateChangedAtom.getDisconnectCause()).isEqualTo(UNKNOWN);
120                     break;
121                 case DIALING:
122                     assertThat(state_dialing).isFalse();
123                     state_dialing = true;
124                     assertThat(callStateChangedAtom.getDisconnectCause()).isEqualTo(UNKNOWN);
125                     break;
126                 case DISCONNECTED:
127                     assertThat(state_disconnected).isFalse();
128                     state_disconnected = true;
129                     assertThat(callStateChangedAtom.getDisconnectCause()).isEqualTo(LOCAL);
130                     break;
131                 default:
132             }
133         }
134         assertThat(state_connecting).isTrue();
135         assertThat(state_dialing).isTrue();
136         assertThat(state_disconnected).isTrue();
137     }
138 
139     // Verification for EmergencyNumberDialed atom
140     // being logged to statsd when a sos call is made
141     @Test
testEmergencyNumberDialedAtom()142     public void testEmergencyNumberDialedAtom() throws Exception {
143         if (!DeviceUtils.hasFeature(getDevice(), FEATURE_TELECOM) || !DeviceUtils.hasFeature(
144                 getDevice(), FEATURE_TELEPHONY) || !DeviceUtils.hasFeature(getDevice(),
145                 FEATURE_TELEPHONY_CALLING)) {
146             return;
147         }
148 
149         ConfigUtils.uploadConfigForPushedAtom(
150                 getDevice(),
151                 TELECOM_CTS_TEST_PKG,
152                 TelecomExtensionAtom.EMERGENCY_NUMBER_DIALED_FIELD_NUMBER);
153 
154         runDeviceTests(new DeviceTestRunOptions(TELECOM_CTS_TEST_PKG)
155                 .setDevice(getDevice())
156                 .setDisableHiddenApiCheck(true)
157                 .setTestClassName("android.telecom.cts.EmergencyCallTests")
158                 .setTestMethodName("testStartEmergencyCall"));
159 
160         RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG);
161         ExtensionRegistry registry = ExtensionRegistry.newInstance();
162         TelecomExtensionAtom.registerAllExtensions(registry);
163         List<EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice(), registry);
164         CLog.d("metrics list size: " + data.size());
165         assertEquals(data.size(), 1);
166         EmergencyNumberDialed emergencyNumberDialedAtom =
167                 data.get(0).getAtom().getExtension(TelecomExtensionAtom.emergencyNumberDialed);
168         assertThat(emergencyNumberDialedAtom.getNumber())
169                 .isEqualTo("5553637"); // Test emergency number
170         assertThat(emergencyNumberDialedAtom.getSystemDialerPackage())
171                 .isEqualTo(TELECOM_CTS_TEST_PKG);
172     }
173 }
174