xref: /aosp_15_r20/system/chre/apps/test/common/permission_test/src/permission_test.cc (revision 84e339476a462649f82315436d70fd732297a399)
1 /*
2  * Copyright (C) 2021 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 #include <pb_decode.h>
18 #include <cinttypes>
19 
20 #include "chre/util/nanoapp/log.h"
21 #include "chre/util/time.h"
22 #include "chre_api/chre.h"
23 #include "permission_test.nanopb.h"
24 #include "send_message.h"
25 
26 #define LOG_TAG "[PermissionTest]"
27 
28 /**
29  * This nanoapp is compiled with the ability to refer to permission gated APIs
30  * but doesn't actually declare permissions to use them. Its purpose is to
31  * validate the permission gated APIs always return false for any of its
32  * requests to ensure CHRE implementations are validating nanoapp permissions
33  * prior to accepting a nanoapp request.
34  */
35 
36 namespace chre {
37 namespace {
38 
39 constexpr Nanoseconds kGnssMinInterval = Seconds(1);
40 
checkAudioApis(uint32_t hostEndpointId)41 void checkAudioApis(uint32_t hostEndpointId) {
42   struct chreAudioSource audioSource;
43   for (uint32_t i = 0; chreAudioGetSource(i, &audioSource); i++) {
44     if (chreAudioConfigureSource(i, true /* enable */,
45                                  audioSource.minBufferDuration,
46                                  audioSource.minBufferDuration)) {
47       test_shared::sendTestResultWithMsgToHost(
48           hostEndpointId, permission_test_MessageType_TEST_RESULT,
49           false /* success */, "Configured audio without audio permission");
50     }
51 
52     // TODO(b/174590023): Check chreAudioGetStatus once it's supported by our
53     // CHRE versions.
54   }
55 }
56 
checkGnssApis(uint32_t hostEndpointId)57 void checkGnssApis(uint32_t hostEndpointId) {
58   if (chreGnssLocationSessionStartAsync(kGnssMinInterval.toRawNanoseconds(),
59                                         kGnssMinInterval.toRawNanoseconds(),
60                                         nullptr /* cookie */)) {
61     test_shared::sendTestResultWithMsgToHost(
62         hostEndpointId, permission_test_MessageType_TEST_RESULT,
63         false /* success */,
64         "Requested GNSS location without the GNSS permission");
65   }
66 
67   if (chreGnssMeasurementSessionStartAsync(kGnssMinInterval.toRawNanoseconds(),
68                                            nullptr /* cookie */)) {
69     test_shared::sendTestResultWithMsgToHost(
70         hostEndpointId, permission_test_MessageType_TEST_RESULT,
71         false /* success */,
72         "Requested GNSS measurements without the GNSS permission");
73   }
74 
75   if (chreGnssConfigurePassiveLocationListener(true /* enable */)) {
76     test_shared::sendTestResultWithMsgToHost(
77         hostEndpointId, permission_test_MessageType_TEST_RESULT,
78         false /* success */,
79         "Requested GNSS passive locations without the GNSS permission");
80   }
81 }
82 
checkWifiApis(uint32_t hostEndpointId)83 void checkWifiApis(uint32_t hostEndpointId) {
84   if (chreWifiConfigureScanMonitorAsync(true /* enable */,
85                                         nullptr /* cookie */)) {
86     test_shared::sendTestResultWithMsgToHost(
87         hostEndpointId, permission_test_MessageType_TEST_RESULT,
88         false /* success */,
89         "Requested WiFi scan monitor without WiFi permission");
90   }
91 
92   if (chreWifiRequestScanAsyncDefault(nullptr /* cookie */)) {
93     test_shared::sendTestResultWithMsgToHost(
94         hostEndpointId, permission_test_MessageType_TEST_RESULT,
95         false /* success */, "Requested WiFi scan without WiFi permission");
96   }
97 
98   // RTT ranging not included in WiFi test because it requires a valid AP to
99   // request which can't be obtained due to invalid permissions.
100 }
101 
checkWwanApis(uint32_t hostEndpointId)102 void checkWwanApis(uint32_t hostEndpointId) {
103   if (chreWwanGetCellInfoAsync(nullptr /* cookie */)) {
104     test_shared::sendTestResultWithMsgToHost(
105         hostEndpointId, permission_test_MessageType_TEST_RESULT,
106         false /* success */, "Requested cell info without WWAN permission");
107   }
108 }
109 
110 // Call APIs that require permissions and verify that they all refuse requests
111 // from this nanoapp since it has no permissions.
checkPermissionGatedApis(uint32_t hostEndpointId)112 void checkPermissionGatedApis(uint32_t hostEndpointId) {
113   checkAudioApis(hostEndpointId);
114   checkGnssApis(hostEndpointId);
115   checkWifiApis(hostEndpointId);
116   checkWwanApis(hostEndpointId);
117 }
118 
handleMessageFromHost(uint32_t senderInstanceId,const chreMessageFromHostData * hostData)119 void handleMessageFromHost(uint32_t senderInstanceId,
120                            const chreMessageFromHostData *hostData) {
121   bool success = false;
122   uint32_t messageType = hostData->messageType;
123   if (senderInstanceId != CHRE_INSTANCE_ID) {
124     LOGE("Incorrect sender instance id: %" PRIu32, senderInstanceId);
125   } else if (messageType != permission_test_MessageType_TEST_COMMAND) {
126     LOGE("Invalid message type %" PRIu32, messageType);
127   } else {
128     // Method will abort if any failures are encountered.
129     checkPermissionGatedApis(hostData->hostEndpoint);
130     success = true;
131   }
132 
133   test_shared::sendTestResultWithMsgToHost(
134       hostData->hostEndpoint,
135       permission_test_MessageType_TEST_RESULT /* messageType */, success,
136       nullptr /* errMessage */);
137 }
138 
139 }  // anonymous namespace
140 
nanoappHandleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)141 extern "C" void nanoappHandleEvent(uint32_t senderInstanceId,
142                                    uint16_t eventType, const void *eventData) {
143   if (eventType == CHRE_EVENT_MESSAGE_FROM_HOST) {
144     handleMessageFromHost(
145         senderInstanceId,
146         static_cast<const chreMessageFromHostData *>(eventData));
147   } else {
148     LOGW("Got unknown event type from senderInstanceId %" PRIu32
149          " and with eventType %" PRIu16,
150          senderInstanceId, eventType);
151   }
152 }
153 
nanoappStart(void)154 extern "C" bool nanoappStart(void) {
155   return true;
156 }
157 
nanoappEnd(void)158 extern "C" void nanoappEnd(void) {}
159 
160 }  // namespace chre
161