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 #define LOG_TAG "RadioTest"
17 
18 #include <vts_test_util.h>
19 #include <iostream>
20 #include "VtsCoreUtil.h"
21 
22 #define WAIT_TIMEOUT_PERIOD 75
23 
GetRandomSerialNumber()24 int GetRandomSerialNumber() {
25     return rand();
26 }
27 
CheckAnyOfErrors(RadioError err,std::vector<RadioError> errors,CheckFlag flag)28 ::testing::AssertionResult CheckAnyOfErrors(RadioError err, std::vector<RadioError> errors,
29                                             CheckFlag flag) {
30     const static vector<RadioError> generalErrors = {
31         RadioError::RADIO_NOT_AVAILABLE,   RadioError::NO_MEMORY,
32         RadioError::INTERNAL_ERR,          RadioError::SYSTEM_ERR,
33         RadioError::REQUEST_NOT_SUPPORTED, RadioError::CANCELLED};
34     if (flag == CHECK_GENERAL_ERROR || flag == CHECK_OEM_AND_GENERAL_ERROR) {
35         for (size_t i = 0; i < generalErrors.size(); i++) {
36             if (err == generalErrors[i]) {
37                 return testing::AssertionSuccess();
38             }
39         }
40     }
41     if (flag == CHECK_OEM_ERROR || flag == CHECK_OEM_AND_GENERAL_ERROR) {
42         if (err >= RadioError::OEM_ERROR_1 && err <= RadioError::OEM_ERROR_25) {
43             return testing::AssertionSuccess();
44         }
45     }
46     for (size_t i = 0; i < errors.size(); i++) {
47         if (err == errors[i]) {
48             return testing::AssertionSuccess();
49         }
50     }
51     return testing::AssertionFailure() << "RadioError:" + toString(err) + " is returned";
52 }
53 
CheckAnyOfErrors(SapResultCode err,std::vector<SapResultCode> errors)54 ::testing::AssertionResult CheckAnyOfErrors(SapResultCode err, std::vector<SapResultCode> errors) {
55     for (size_t i = 0; i < errors.size(); i++) {
56         if (err == errors[i]) {
57             return testing::AssertionSuccess();
58         }
59     }
60     return testing::AssertionFailure() << "SapError:" + toString(err) + " is returned";
61 }
62 
63 // Runs "pm list features" and attempts to find the specified feature in its output.
deviceSupportsFeature(const char * feature)64 bool deviceSupportsFeature(const char* feature) {
65     bool hasFeature = false;
66     FILE* p = popen("/system/bin/pm list features", "re");
67     if (p) {
68         char* line = NULL;
69         size_t len = 0;
70         while (getline(&line, &len, p) > 0) {
71             if (strstr(line, feature)) {
72                 hasFeature = true;
73                 break;
74             }
75         }
76         pclose(p);
77     } else {
78         __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "popen failed: %d", errno);
79         _exit(EXIT_FAILURE);
80     }
81     __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Feature %s: %ssupported", feature,
82                         hasFeature ? "" : "not ");
83     return hasFeature;
84 }
85 
isSsSsEnabled()86 bool isSsSsEnabled() {
87     // Do not use checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "")
88     // until b/148904287 is fixed. We need exact matching instead of partial matching. (i.e.
89     // by definition the empty string "" is a substring of any string).
90     return !isDsDsEnabled() && !isTsTsEnabled();
91 }
92 
isDsDsEnabled()93 bool isDsDsEnabled() {
94     return testing::checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "dsds");
95 }
96 
isTsTsEnabled()97 bool isTsTsEnabled() {
98     return testing::checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "tsts");
99 }
100 
isVoiceInService(RegState state)101 bool isVoiceInService(RegState state) {
102     return ::android::hardware::radio::V1_0::RegState::REG_HOME == state ||
103            ::android::hardware::radio::V1_0::RegState::REG_ROAMING == state;
104 }
105 
isVoiceEmergencyOnly(RegState state)106 bool isVoiceEmergencyOnly(RegState state) {
107     return ::android::hardware::radio::V1_0::RegState::NOT_REG_MT_NOT_SEARCHING_OP_EM == state ||
108            ::android::hardware::radio::V1_0::RegState::NOT_REG_MT_SEARCHING_OP_EM == state ||
109            ::android::hardware::radio::V1_0::RegState::REG_DENIED_EM == state ||
110            ::android::hardware::radio::V1_0::RegState::UNKNOWN_EM == state;
111 }
112 
113 /*
114  * Notify that the response message is received.
115  */
notify(int receivedSerial)116 void RadioResponseWaiter::notify(int receivedSerial) {
117     std::unique_lock<std::mutex> lock(mtx_);
118     if (serial == receivedSerial) {
119         count_++;
120         cv_.notify_one();
121     }
122 }
123 
124 /*
125  * Wait till the response message is notified or till WAIT_TIMEOUT_PERIOD.
126  */
wait()127 std::cv_status RadioResponseWaiter::wait() {
128     std::unique_lock<std::mutex> lock(mtx_);
129 
130     std::cv_status status = std::cv_status::no_timeout;
131     auto now = std::chrono::system_clock::now();
132     while (count_ == 0) {
133         status = cv_.wait_until(lock, now + std::chrono::seconds(WAIT_TIMEOUT_PERIOD));
134         if (status == std::cv_status::timeout) {
135             return status;
136         }
137     }
138     count_--;
139     return status;
140 }
141