| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2016 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 | #define LOG_TAG "AAudioService" | 
 | 18 | //#define LOG_NDEBUG 0 | 
 | 19 | #include <utils/Log.h> | 
 | 20 |  | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 21 | #include <iomanip> | 
 | 22 | #include <iostream> | 
| Andy Hung | 47c5e53 | 2017-06-26 18:28:00 -0700 | [diff] [blame] | 23 | #include <sstream> | 
| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 24 |  | 
| Svet Ganov | 3e5f14f | 2021-05-13 22:51:08 +0000 | [diff] [blame] | 25 | #include <android/content/AttributionSourceState.h> | 
| Phil Burk | a4eb0d8 | 2017-04-12 15:44:06 -0700 | [diff] [blame] | 26 | #include <aaudio/AAudio.h> | 
| Philip P. Moltmann | bda4575 | 2020-07-17 16:41:18 -0700 | [diff] [blame] | 27 | #include <media/AidlConversion.h> | 
| Andy Hung | ab7ef30 | 2018-05-15 19:35:29 -0700 | [diff] [blame] | 28 | #include <mediautils/ServiceUtilities.h> | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 29 | #include <utils/String16.h> | 
| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 30 |  | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 31 | #include "binding/AAudioServiceMessage.h" | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 32 | #include "AAudioClientTracker.h" | 
| Andy Hung | 47c5e53 | 2017-06-26 18:28:00 -0700 | [diff] [blame] | 33 | #include "AAudioEndpointManager.h" | 
| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 34 | #include "AAudioService.h" | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 35 | #include "AAudioServiceStreamMMAP.h" | 
 | 36 | #include "AAudioServiceStreamShared.h" | 
| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 37 |  | 
 | 38 | using namespace android; | 
 | 39 | using namespace aaudio; | 
 | 40 |  | 
| Phil Burk | 9169294 | 2017-06-30 12:23:05 -0700 | [diff] [blame] | 41 | #define MAX_STREAMS_PER_PROCESS   8 | 
| Nate Myren | ae7d9e6 | 2021-03-15 14:21:43 -0700 | [diff] [blame] | 42 | #define AIDL_RETURN(x) { *_aidl_return = (x); return Status::ok(); } | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 43 |  | 
| Philip P. Moltmann | bda4575 | 2020-07-17 16:41:18 -0700 | [diff] [blame] | 44 | #define VALUE_OR_RETURN_ILLEGAL_ARG_STATUS(x) \ | 
 | 45 |     ({ auto _tmp = (x); \ | 
 | 46 |        if (!_tmp.ok()) AIDL_RETURN(AAUDIO_ERROR_ILLEGAL_ARGUMENT); \ | 
 | 47 |        std::move(_tmp.value()); }) | 
| Phil Burk | 9169294 | 2017-06-30 12:23:05 -0700 | [diff] [blame] | 48 |  | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 49 | using android::AAudioService; | 
| Svet Ganov | 3e5f14f | 2021-05-13 22:51:08 +0000 | [diff] [blame] | 50 | using android::content::AttributionSourceState; | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 51 | using binder::Status; | 
| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 52 |  | 
 | 53 | android::AAudioService::AAudioService() | 
| Ytai Ben-Tsvi | 734e350 | 2020-08-24 14:57:36 -0700 | [diff] [blame] | 54 |     : BnAAudioService(), | 
 | 55 |       mAdapter(this) { | 
| Philip P. Moltmann | bda4575 | 2020-07-17 16:41:18 -0700 | [diff] [blame] | 56 |     // TODO consider using geteuid() | 
| Svet Ganov | 3e5f14f | 2021-05-13 22:51:08 +0000 | [diff] [blame] | 57 |     // TODO b/182392769: use attribution source util | 
 | 58 |     mAudioClient.attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid())); | 
 | 59 |     mAudioClient.attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid())); | 
 | 60 |     mAudioClient.attributionSource.packageName = std::nullopt; | 
 | 61 |     mAudioClient.attributionSource.attributionTag = std::nullopt; | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 62 |     AAudioClientTracker::getInstance().setAAudioService(this); | 
| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 63 | } | 
 | 64 |  | 
| Andy Hung | 47c5e53 | 2017-06-26 18:28:00 -0700 | [diff] [blame] | 65 | status_t AAudioService::dump(int fd, const Vector<String16>& args) { | 
 | 66 |     std::string result; | 
 | 67 |  | 
 | 68 |     if (!dumpAllowed()) { | 
 | 69 |         std::stringstream ss; | 
| Andy Hung | 6357b5f | 2018-10-22 19:47:04 -0700 | [diff] [blame] | 70 |         ss << "Permission Denial: can't dump AAudioService from pid=" | 
| Andy Hung | 47c5e53 | 2017-06-26 18:28:00 -0700 | [diff] [blame] | 71 |                 << IPCThreadState::self()->getCallingPid() << ", uid=" | 
 | 72 |                 << IPCThreadState::self()->getCallingUid() << "\n"; | 
 | 73 |         result = ss.str(); | 
 | 74 |         ALOGW("%s", result.c_str()); | 
 | 75 |     } else { | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 76 |         result = "------------ AAudio Service ------------\n" | 
 | 77 |                  + mStreamTracker.dump() | 
| Phil Burk | 4501b35 | 2017-06-29 18:12:36 -0700 | [diff] [blame] | 78 |                  + AAudioClientTracker::getInstance().dump() | 
 | 79 |                  + AAudioEndpointManager::getInstance().dump(); | 
| Andy Hung | 47c5e53 | 2017-06-26 18:28:00 -0700 | [diff] [blame] | 80 |     } | 
 | 81 |     (void)write(fd, result.c_str(), result.size()); | 
 | 82 |     return NO_ERROR; | 
 | 83 | } | 
 | 84 |  | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 85 | Status AAudioService::registerClient(const sp<IAAudioClient> &client) { | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 86 |     pid_t pid = IPCThreadState::self()->getCallingPid(); | 
 | 87 |     AAudioClientTracker::getInstance().registerClient(pid, client); | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 88 |     return Status::ok(); | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 89 | } | 
 | 90 |  | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 91 | Status | 
 | 92 | AAudioService::openStream(const StreamRequest &_request, StreamParameters* _paramsOut, | 
 | 93 |                           int32_t *_aidl_return) { | 
 | 94 |     static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>); | 
| Phil Burk | 2ebf662 | 2019-04-17 11:10:25 -0700 | [diff] [blame] | 95 |  | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 96 |     // Create wrapper objects for simple usage of the parcelables. | 
 | 97 |     const AAudioStreamRequest request(_request); | 
 | 98 |     AAudioStreamConfiguration paramsOut; | 
 | 99 |  | 
| Phil Burk | 6e463ce | 2020-04-13 10:20:20 -0700 | [diff] [blame] | 100 |     // A lock in is used to order the opening of endpoints when an | 
 | 101 |     // EXCLUSIVE endpoint is stolen. We want the order to be: | 
 | 102 |     // 1) Thread A opens exclusive MMAP endpoint | 
 | 103 |     // 2) Thread B wants to open an exclusive MMAP endpoint so it steals the one from A | 
 | 104 |     //    under this lock. | 
 | 105 |     // 3) Thread B opens a shared MMAP endpoint. | 
 | 106 |     // 4) Thread A can then get the lock and also open a shared stream. | 
 | 107 |     // Without the lock. Thread A might sneak in and reallocate an exclusive stream | 
 | 108 |     // before B can open the shared stream. | 
 | 109 |     std::unique_lock<std::recursive_mutex> lock(mOpenLock); | 
 | 110 |  | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 111 |     aaudio_result_t result = AAUDIO_OK; | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 112 |     sp<AAudioServiceStreamBase> serviceStream; | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 113 |     const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration(); | 
| Phil Burk | 71f35bb | 2017-04-13 16:05:07 -0700 | [diff] [blame] | 114 |     bool sharingModeMatchRequired = request.isSharingModeMatchRequired(); | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 115 |     aaudio_sharing_mode_t sharingMode = configurationInput.getSharingMode(); | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 116 |  | 
| Phil Burk | 9169294 | 2017-06-30 12:23:05 -0700 | [diff] [blame] | 117 |     // Enforce limit on client processes. | 
| Svet Ganov | 3e5f14f | 2021-05-13 22:51:08 +0000 | [diff] [blame] | 118 |     AttributionSourceState attributionSource = request.getAttributionSource(); | 
| Nate Myren | ae7d9e6 | 2021-03-15 14:21:43 -0700 | [diff] [blame] | 119 |     pid_t pid = IPCThreadState::self()->getCallingPid(); | 
| Svet Ganov | 3e5f14f | 2021-05-13 22:51:08 +0000 | [diff] [blame] | 120 |     attributionSource.pid = VALUE_OR_RETURN_ILLEGAL_ARG_STATUS( | 
| Nate Myren | ae7d9e6 | 2021-03-15 14:21:43 -0700 | [diff] [blame] | 121 |         legacy2aidl_pid_t_int32_t(pid)); | 
| Svet Ganov | 3e5f14f | 2021-05-13 22:51:08 +0000 | [diff] [blame] | 122 |     attributionSource.uid = VALUE_OR_RETURN_ILLEGAL_ARG_STATUS( | 
| Philip P. Moltmann | bda4575 | 2020-07-17 16:41:18 -0700 | [diff] [blame] | 123 |         legacy2aidl_uid_t_int32_t(IPCThreadState::self()->getCallingUid())); | 
| Svet Ganov | 3e5f14f | 2021-05-13 22:51:08 +0000 | [diff] [blame] | 124 |     attributionSource.token = sp<BBinder>::make(); | 
 | 125 |     if (attributionSource.pid != mAudioClient.attributionSource.pid) { | 
| Phil Burk | 9169294 | 2017-06-30 12:23:05 -0700 | [diff] [blame] | 126 |         int32_t count = AAudioClientTracker::getInstance().getStreamCount(pid); | 
 | 127 |         if (count >= MAX_STREAMS_PER_PROCESS) { | 
| Phil Burk | fbf031e | 2017-10-12 15:58:31 -0700 | [diff] [blame] | 128 |             ALOGE("openStream(): exceeded max streams per process %d >= %d", | 
| Phil Burk | 9169294 | 2017-06-30 12:23:05 -0700 | [diff] [blame] | 129 |                   count,  MAX_STREAMS_PER_PROCESS); | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 130 |             AIDL_RETURN(AAUDIO_ERROR_UNAVAILABLE); | 
| Phil Burk | 9169294 | 2017-06-30 12:23:05 -0700 | [diff] [blame] | 131 |         } | 
 | 132 |     } | 
 | 133 |  | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 134 |     if (sharingMode != AAUDIO_SHARING_MODE_EXCLUSIVE && sharingMode != AAUDIO_SHARING_MODE_SHARED) { | 
| Phil Burk | fbf031e | 2017-10-12 15:58:31 -0700 | [diff] [blame] | 135 |         ALOGE("openStream(): unrecognized sharing mode = %d", sharingMode); | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 136 |         AIDL_RETURN(AAUDIO_ERROR_ILLEGAL_ARGUMENT); | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 137 |     } | 
 | 138 |  | 
| Phil Burk | 836f9df | 2020-05-29 13:20:28 -0700 | [diff] [blame] | 139 |     if (sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE | 
| Philip P. Moltmann | bda4575 | 2020-07-17 16:41:18 -0700 | [diff] [blame] | 140 |         && AAudioClientTracker::getInstance().isExclusiveEnabled(pid)) { | 
| Eric Laurent | a54f128 | 2017-07-01 19:39:32 -0700 | [diff] [blame] | 141 |         // only trust audioserver for in service indication | 
 | 142 |         bool inService = false; | 
| Phil Burk | 2ebf662 | 2019-04-17 11:10:25 -0700 | [diff] [blame] | 143 |         if (isCallerInService()) { | 
| Eric Laurent | a54f128 | 2017-07-01 19:39:32 -0700 | [diff] [blame] | 144 |             inService = request.isInService(); | 
 | 145 |         } | 
| Phil Burk | 39f02dd | 2017-08-04 09:13:31 -0700 | [diff] [blame] | 146 |         serviceStream = new AAudioServiceStreamMMAP(*this, inService); | 
 | 147 |         result = serviceStream->open(request); | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 148 |         if (result != AAUDIO_OK) { | 
| Phil Burk | 39f02dd | 2017-08-04 09:13:31 -0700 | [diff] [blame] | 149 |             // Clear it so we can possibly fall back to using a shared stream. | 
| Phil Burk | fbf031e | 2017-10-12 15:58:31 -0700 | [diff] [blame] | 150 |             ALOGW("openStream(), could not open in EXCLUSIVE mode"); | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 151 |             serviceStream.clear(); | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 152 |         } | 
 | 153 |     } | 
 | 154 |  | 
| Phil Burk | a3901e9 | 2018-10-08 13:54:38 -0700 | [diff] [blame] | 155 |     // Try SHARED if SHARED requested or if EXCLUSIVE failed. | 
| Phil Burk | 15f97c9 | 2018-09-04 14:06:27 -0700 | [diff] [blame] | 156 |     if (sharingMode == AAUDIO_SHARING_MODE_SHARED) { | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 157 |         serviceStream =  new AAudioServiceStreamShared(*this); | 
| Phil Burk | 39f02dd | 2017-08-04 09:13:31 -0700 | [diff] [blame] | 158 |         result = serviceStream->open(request); | 
| Phil Burk | 15f97c9 | 2018-09-04 14:06:27 -0700 | [diff] [blame] | 159 |     } else if (serviceStream.get() == nullptr && !sharingModeMatchRequired) { | 
 | 160 |         aaudio::AAudioStreamRequest modifiedRequest = request; | 
 | 161 |         // Overwrite the original EXCLUSIVE mode with SHARED. | 
 | 162 |         modifiedRequest.getConfiguration().setSharingMode(AAUDIO_SHARING_MODE_SHARED); | 
 | 163 |         serviceStream =  new AAudioServiceStreamShared(*this); | 
 | 164 |         result = serviceStream->open(modifiedRequest); | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 165 |     } | 
 | 166 |  | 
 | 167 |     if (result != AAUDIO_OK) { | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 168 |         serviceStream.clear(); | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 169 |         AIDL_RETURN(result); | 
| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 170 |     } else { | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 171 |         aaudio_handle_t handle = mStreamTracker.addStreamForHandle(serviceStream.get()); | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 172 |         serviceStream->setHandle(handle); | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 173 |         AAudioClientTracker::getInstance().registerClientStream(pid, serviceStream); | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 174 |         paramsOut.copyFrom(*serviceStream); | 
 | 175 |         *_paramsOut = std::move(paramsOut).parcelable(); | 
| Phil Burk | a987670 | 2020-04-20 18:16:15 -0700 | [diff] [blame] | 176 |         // Log open in MediaMetrics after we have the handle because we need the handle to | 
 | 177 |         // create the metrics ID. | 
 | 178 |         serviceStream->logOpen(handle); | 
| Phil Burk | 6e463ce | 2020-04-13 10:20:20 -0700 | [diff] [blame] | 179 |         ALOGV("%s(): return handle = 0x%08X", __func__, handle); | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 180 |         AIDL_RETURN(handle); | 
| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 181 |     } | 
 | 182 | } | 
 | 183 |  | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 184 | Status AAudioService::closeStream(int32_t streamHandle, int32_t *_aidl_return) { | 
 | 185 |     static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>); | 
 | 186 |  | 
| Phil Burk | 98d6d92 | 2017-07-06 11:52:45 -0700 | [diff] [blame] | 187 |     // Check permission and ownership first. | 
 | 188 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 189 |     if (serviceStream.get() == nullptr) { | 
| Phil Burk | fbf031e | 2017-10-12 15:58:31 -0700 | [diff] [blame] | 190 |         ALOGE("closeStream(0x%0x), illegal stream handle", streamHandle); | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 191 |         AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE); | 
| Phil Burk | 9169294 | 2017-06-30 12:23:05 -0700 | [diff] [blame] | 192 |     } | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 193 |     AIDL_RETURN(closeStream(serviceStream)); | 
 | 194 | } | 
 | 195 |  | 
 | 196 | Status AAudioService::getStreamDescription(int32_t streamHandle, Endpoint* endpoint, | 
 | 197 |                                            int32_t *_aidl_return) { | 
 | 198 |     static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>); | 
 | 199 |  | 
 | 200 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
 | 201 |     if (serviceStream.get() == nullptr) { | 
 | 202 |         ALOGE("getStreamDescription(), illegal stream handle = 0x%0x", streamHandle); | 
 | 203 |         AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE); | 
 | 204 |     } | 
 | 205 |     AudioEndpointParcelable endpointParcelable; | 
 | 206 |     aaudio_result_t result = serviceStream->getDescription(endpointParcelable); | 
 | 207 |     if (result == AAUDIO_OK) { | 
 | 208 |         *endpoint = std::move(endpointParcelable).parcelable(); | 
 | 209 |     } | 
 | 210 |     AIDL_RETURN(result); | 
 | 211 | } | 
 | 212 |  | 
 | 213 | Status AAudioService::startStream(int32_t streamHandle, int32_t *_aidl_return) { | 
 | 214 |     static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>); | 
 | 215 |  | 
 | 216 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
 | 217 |     if (serviceStream.get() == nullptr) { | 
 | 218 |         ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); | 
 | 219 |         AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE); | 
 | 220 |     } | 
 | 221 |     AIDL_RETURN(serviceStream->start()); | 
 | 222 | } | 
 | 223 |  | 
 | 224 | Status AAudioService::pauseStream(int32_t streamHandle, int32_t *_aidl_return) { | 
 | 225 |     static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>); | 
 | 226 |  | 
 | 227 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
 | 228 |     if (serviceStream.get() == nullptr) { | 
 | 229 |         ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); | 
 | 230 |         AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE); | 
 | 231 |     } | 
 | 232 |     AIDL_RETURN(serviceStream->pause()); | 
 | 233 | } | 
 | 234 |  | 
 | 235 | Status AAudioService::stopStream(int32_t streamHandle, int32_t *_aidl_return) { | 
 | 236 |     static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>); | 
 | 237 |  | 
 | 238 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
 | 239 |     if (serviceStream.get() == nullptr) { | 
 | 240 |         ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); | 
 | 241 |         AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE); | 
 | 242 |     } | 
 | 243 |     AIDL_RETURN(serviceStream->stop()); | 
 | 244 | } | 
 | 245 |  | 
 | 246 | Status AAudioService::flushStream(int32_t streamHandle, int32_t *_aidl_return) { | 
 | 247 |     static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>); | 
 | 248 |  | 
 | 249 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
 | 250 |     if (serviceStream.get() == nullptr) { | 
 | 251 |         ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); | 
 | 252 |         AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE); | 
 | 253 |     } | 
 | 254 |     AIDL_RETURN(serviceStream->flush()); | 
 | 255 | } | 
 | 256 |  | 
 | 257 | Status AAudioService::registerAudioThread(int32_t streamHandle, int32_t clientThreadId, int64_t periodNanoseconds, | 
 | 258 |                                           int32_t *_aidl_return) { | 
 | 259 |     static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>); | 
 | 260 |  | 
 | 261 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
 | 262 |     if (serviceStream.get() == nullptr) { | 
 | 263 |         ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); | 
 | 264 |         AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE); | 
 | 265 |     } | 
 | 266 |     int32_t priority = isCallerInService() | 
 | 267 |         ? kRealTimeAudioPriorityService : kRealTimeAudioPriorityClient; | 
 | 268 |     AIDL_RETURN(serviceStream->registerAudioThread(clientThreadId, priority)); | 
 | 269 | } | 
 | 270 |  | 
 | 271 | Status AAudioService::unregisterAudioThread(int32_t streamHandle, int32_t clientThreadId, | 
 | 272 |                                             int32_t *_aidl_return) { | 
 | 273 |     static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>); | 
 | 274 |  | 
 | 275 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
 | 276 |     if (serviceStream.get() == nullptr) { | 
 | 277 |         ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); | 
 | 278 |         AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE); | 
 | 279 |     } | 
 | 280 |     AIDL_RETURN(serviceStream->unregisterAudioThread(clientThreadId)); | 
 | 281 | } | 
 | 282 |  | 
| jiabin | f7f0615 | 2021-11-22 18:10:14 +0000 | [diff] [blame] | 283 | Status AAudioService::exitStandby(int32_t streamHandle, Endpoint* endpoint, int32_t *_aidl_return) { | 
 | 284 |     static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>); | 
 | 285 |  | 
 | 286 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
 | 287 |     if (serviceStream.get() == nullptr) { | 
 | 288 |         ALOGE("getStreamDescription(), illegal stream handle = 0x%0x", streamHandle); | 
 | 289 |         AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE); | 
 | 290 |     } | 
 | 291 |     AudioEndpointParcelable endpointParcelable; | 
 | 292 |     aaudio_result_t result = serviceStream->exitStandby(&endpointParcelable); | 
 | 293 |     if (result == AAUDIO_OK) { | 
 | 294 |         *endpoint = std::move(endpointParcelable).parcelable(); | 
 | 295 |     } | 
 | 296 |     AIDL_RETURN(result); | 
 | 297 | } | 
 | 298 |  | 
| Ytai Ben-Tsvi | c5f4587 | 2020-08-18 10:39:44 -0700 | [diff] [blame] | 299 | bool AAudioService::isCallerInService() { | 
| Svet Ganov | 3e5f14f | 2021-05-13 22:51:08 +0000 | [diff] [blame] | 300 |     pid_t clientPid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mAudioClient.attributionSource.pid)); | 
 | 301 |     uid_t clientUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(mAudioClient.attributionSource.uid)); | 
| Philip P. Moltmann | bda4575 | 2020-07-17 16:41:18 -0700 | [diff] [blame] | 302 |     return clientPid == IPCThreadState::self()->getCallingPid() && | 
 | 303 |         clientUid == IPCThreadState::self()->getCallingUid(); | 
| Phil Burk | 6e463ce | 2020-04-13 10:20:20 -0700 | [diff] [blame] | 304 | } | 
| Phil Burk | 9169294 | 2017-06-30 12:23:05 -0700 | [diff] [blame] | 305 |  | 
| Phil Burk | 6e463ce | 2020-04-13 10:20:20 -0700 | [diff] [blame] | 306 | aaudio_result_t AAudioService::closeStream(sp<AAudioServiceStreamBase> serviceStream) { | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 307 |     // This is protected by a lock in AAudioClientTracker. | 
 | 308 |     // It is safe to unregister the same stream twice. | 
| Phil Burk | 9486252 | 2017-09-13 21:31:36 -0700 | [diff] [blame] | 309 |     pid_t pid = serviceStream->getOwnerProcessId(); | 
 | 310 |     AAudioClientTracker::getInstance().unregisterClientStream(pid, serviceStream); | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 311 |     // This is protected by a lock in mStreamTracker. | 
 | 312 |     // It is safe to remove the same stream twice. | 
 | 313 |     mStreamTracker.removeStreamByHandle(serviceStream->getHandle()); | 
| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 314 |  | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 315 |     return serviceStream->close(); | 
| Phil Burk | 9486252 | 2017-09-13 21:31:36 -0700 | [diff] [blame] | 316 | } | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 317 |  | 
 | 318 | sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( | 
 | 319 |         aaudio_handle_t streamHandle) { | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 320 |     sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandle( | 
| Phil Burk | 2fe718b | 2018-05-14 12:28:32 -0700 | [diff] [blame] | 321 |             streamHandle); | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 322 |     if (serviceStream.get() != nullptr) { | 
| Phil Burk | 2ac035f | 2017-06-23 14:51:14 -0700 | [diff] [blame] | 323 |         // Only allow owner or the aaudio service to access the stream. | 
 | 324 |         const uid_t callingUserId = IPCThreadState::self()->getCallingUid(); | 
 | 325 |         const uid_t ownerUserId = serviceStream->getOwnerUserId(); | 
| Philip P. Moltmann | bda4575 | 2020-07-17 16:41:18 -0700 | [diff] [blame] | 326 |         const uid_t clientUid = VALUE_OR_FATAL( | 
| Svet Ganov | 3e5f14f | 2021-05-13 22:51:08 +0000 | [diff] [blame] | 327 |             aidl2legacy_int32_t_uid_t(mAudioClient.attributionSource.uid)); | 
| Phil Burk | 2ac035f | 2017-06-23 14:51:14 -0700 | [diff] [blame] | 328 |         bool callerOwnsIt = callingUserId == ownerUserId; | 
| Philip P. Moltmann | bda4575 | 2020-07-17 16:41:18 -0700 | [diff] [blame] | 329 |         bool serverCalling = callingUserId == clientUid; | 
 | 330 |         bool serverOwnsIt = ownerUserId == clientUid; | 
| Phil Burk | 2ac035f | 2017-06-23 14:51:14 -0700 | [diff] [blame] | 331 |         bool allowed = callerOwnsIt || serverCalling || serverOwnsIt; | 
 | 332 |         if (!allowed) { | 
 | 333 |             ALOGE("AAudioService: calling uid %d cannot access stream 0x%08X owned by %d", | 
 | 334 |                   callingUserId, streamHandle, ownerUserId); | 
| Phil Burk | 9486252 | 2017-09-13 21:31:36 -0700 | [diff] [blame] | 335 |             serviceStream.clear(); | 
| Phil Burk | 2ac035f | 2017-06-23 14:51:14 -0700 | [diff] [blame] | 336 |         } | 
 | 337 |     } | 
 | 338 |     return serviceStream; | 
| Phil Burk | 5ed503c | 2017-02-01 09:38:15 -0800 | [diff] [blame] | 339 | } | 
 | 340 |  | 
| Eric Laurent | a54f128 | 2017-07-01 19:39:32 -0700 | [diff] [blame] | 341 | aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle, | 
| jiabin | d1f1cb6 | 2020-03-24 11:57:57 -0700 | [diff] [blame] | 342 |                                            const android::AudioClient& client, | 
 | 343 |                                            const audio_attributes_t *attr, | 
 | 344 |                                            audio_port_handle_t *clientHandle) { | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 345 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
 | 346 |     if (serviceStream.get() == nullptr) { | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 347 |         ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); | 
| Eric Laurent | a54f128 | 2017-07-01 19:39:32 -0700 | [diff] [blame] | 348 |         return AAUDIO_ERROR_INVALID_HANDLE; | 
 | 349 |     } | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 350 |     return serviceStream->startClient(client, attr, clientHandle); | 
| Eric Laurent | a54f128 | 2017-07-01 19:39:32 -0700 | [diff] [blame] | 351 | } | 
 | 352 |  | 
 | 353 | aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle, | 
| Phil Burk | bbd5286 | 2018-04-13 11:37:42 -0700 | [diff] [blame] | 354 |                                           audio_port_handle_t portHandle) { | 
| Phil Burk | 523b304 | 2017-09-13 13:03:08 -0700 | [diff] [blame] | 355 |     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); | 
 | 356 |     if (serviceStream.get() == nullptr) { | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 357 |         ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); | 
| Eric Laurent | a54f128 | 2017-07-01 19:39:32 -0700 | [diff] [blame] | 358 |         return AAUDIO_ERROR_INVALID_HANDLE; | 
 | 359 |     } | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 360 |     return serviceStream->stopClient(portHandle); | 
| Phil Burk | bbd5286 | 2018-04-13 11:37:42 -0700 | [diff] [blame] | 361 | } | 
 | 362 |  | 
 | 363 | // This is only called internally when AudioFlinger wants to tear down a stream. | 
 | 364 | // So we do not have to check permissions. | 
 | 365 | aaudio_result_t AAudioService::disconnectStreamByPortHandle(audio_port_handle_t portHandle) { | 
 | 366 |     ALOGD("%s(%d) called", __func__, portHandle); | 
 | 367 |     sp<AAudioServiceStreamBase> serviceStream = | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 368 |             mStreamTracker.findStreamByPortHandle(portHandle); | 
| Phil Burk | bbd5286 | 2018-04-13 11:37:42 -0700 | [diff] [blame] | 369 |     if (serviceStream.get() == nullptr) { | 
 | 370 |         ALOGE("%s(), could not find stream with portHandle = %d", __func__, portHandle); | 
 | 371 |         return AAUDIO_ERROR_INVALID_HANDLE; | 
 | 372 |     } | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 373 |     // This is protected by a lock and will just return if already stopped. | 
| Phil Burk | bbd5286 | 2018-04-13 11:37:42 -0700 | [diff] [blame] | 374 |     aaudio_result_t result = serviceStream->stop(); | 
 | 375 |     serviceStream->disconnect(); | 
| Phil Burk | 7ebbc11 | 2020-05-13 15:55:17 -0700 | [diff] [blame] | 376 |     return result; | 
| Eric Laurent | a54f128 | 2017-07-01 19:39:32 -0700 | [diff] [blame] | 377 | } |