• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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 "ServiceUtilities"
18 
19 #include <audio_utils/clock.h>
20 #include <binder/AppOpsManager.h>
21 #include <binder/IPCThreadState.h>
22 #include <binder/IServiceManager.h>
23 #include <binder/PermissionCache.h>
24 #include "mediautils/ServiceUtilities.h"
25 #include <system/audio-hal-enums.h>
26 #include <media/AidlConversion.h>
27 #include <media/AidlConversionUtil.h>
28 #include <android/content/AttributionSourceState.h>
29 
30 #include <iterator>
31 #include <algorithm>
32 #include <pwd.h>
33 
34 /* When performing permission checks we do not use permission cache for
35  * runtime permissions (protection level dangerous) as they may change at
36  * runtime. All other permissions (protection level normal and dangerous)
37  * can be cached as they never change. Of course all permission checked
38  * here are platform defined.
39  */
40 
41 namespace android {
42 
43 using content::AttributionSourceState;
44 
45 static const String16 sAndroidPermissionRecordAudio("android.permission.RECORD_AUDIO");
46 static const String16 sModifyPhoneState("android.permission.MODIFY_PHONE_STATE");
47 static const String16 sModifyAudioRouting("android.permission.MODIFY_AUDIO_ROUTING");
48 static const String16 sCallAudioInterception("android.permission.CALL_AUDIO_INTERCEPTION");
49 
resolveCallingPackage(PermissionController & permissionController,const std::optional<String16> opPackageName,uid_t uid)50 static String16 resolveCallingPackage(PermissionController& permissionController,
51         const std::optional<String16> opPackageName, uid_t uid) {
52     if (opPackageName.has_value() && opPackageName.value().size() > 0) {
53         return opPackageName.value();
54     }
55     // In some cases the calling code has no access to the package it runs under.
56     // For example, code using the wilhelm framework's OpenSL-ES APIs. In this
57     // case we will get the packages for the calling UID and pick the first one
58     // for attributing the app op. This will work correctly for runtime permissions
59     // as for legacy apps we will toggle the app op for all packages in the UID.
60     // The caveat is that the operation may be attributed to the wrong package and
61     // stats based on app ops may be slightly off.
62     Vector<String16> packages;
63     permissionController.getPackagesForUid(uid, packages);
64     if (packages.isEmpty()) {
65         ALOGE("No packages for uid %d", uid);
66         return String16();
67     }
68     return packages[0];
69 }
70 
getOpForSource(audio_source_t source)71 int32_t getOpForSource(audio_source_t source) {
72   switch (source) {
73     case AUDIO_SOURCE_HOTWORD:
74       return AppOpsManager::OP_RECORD_AUDIO_HOTWORD;
75     case AUDIO_SOURCE_ECHO_REFERENCE: // fallthrough
76     case AUDIO_SOURCE_REMOTE_SUBMIX:
77       return AppOpsManager::OP_RECORD_AUDIO_OUTPUT;
78     case AUDIO_SOURCE_VOICE_DOWNLINK:
79       return AppOpsManager::OP_RECORD_INCOMING_PHONE_AUDIO;
80     case AUDIO_SOURCE_DEFAULT:
81     default:
82       return AppOpsManager::OP_RECORD_AUDIO;
83   }
84 }
85 
resolveAttributionSource(const AttributionSourceState & callerAttributionSource)86 std::optional<AttributionSourceState> resolveAttributionSource(
87         const AttributionSourceState& callerAttributionSource) {
88     AttributionSourceState nextAttributionSource = callerAttributionSource;
89 
90     if (!nextAttributionSource.packageName.has_value()) {
91         nextAttributionSource = AttributionSourceState(nextAttributionSource);
92         PermissionController permissionController;
93         const uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(nextAttributionSource.uid));
94         nextAttributionSource.packageName = VALUE_OR_FATAL(legacy2aidl_String16_string(
95                 resolveCallingPackage(permissionController, VALUE_OR_FATAL(
96                 aidl2legacy_string_view_String16(nextAttributionSource.packageName.value_or(""))),
97                 uid)));
98         if (!nextAttributionSource.packageName.has_value()) {
99             return std::nullopt;
100         }
101     }
102 
103     AttributionSourceState myAttributionSource;
104     myAttributionSource.uid = VALUE_OR_FATAL(android::legacy2aidl_uid_t_int32_t(getuid()));
105     myAttributionSource.pid = VALUE_OR_FATAL(android::legacy2aidl_pid_t_int32_t(getpid()));
106     // Create a static token for audioserver requests, which identifies the
107     // audioserver to the app ops system
108     static sp<BBinder> appOpsToken = sp<BBinder>::make();
109     myAttributionSource.token = appOpsToken;
110     myAttributionSource.next.push_back(nextAttributionSource);
111 
112     return std::optional<AttributionSourceState>{myAttributionSource};
113 }
114 
checkRecordingInternal(const AttributionSourceState & attributionSource,const String16 & msg,bool start,audio_source_t source)115 static bool checkRecordingInternal(const AttributionSourceState& attributionSource,
116         const String16& msg, bool start, audio_source_t source) {
117     // Okay to not track in app ops as audio server or media server is us and if
118     // device is rooted security model is considered compromised.
119     // system_server loses its RECORD_AUDIO permission when a secondary
120     // user is active, but it is a core system service so let it through.
121     // TODO(b/141210120): UserManager.DISALLOW_RECORD_AUDIO should not affect system user 0
122     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
123     if (isAudioServerOrMediaServerOrSystemServerOrRootUid(uid)) return true;
124 
125     // We specify a pid and uid here as mediaserver (aka MediaRecorder or StageFrightRecorder)
126     // may open a record track on behalf of a client. Note that pid may be a tid.
127     // IMPORTANT: DON'T USE PermissionCache - RUNTIME PERMISSIONS CHANGE.
128     const std::optional<AttributionSourceState> resolvedAttributionSource =
129             resolveAttributionSource(attributionSource);
130     if (!resolvedAttributionSource.has_value()) {
131         return false;
132     }
133 
134     const int32_t attributedOpCode = getOpForSource(source);
135 
136     permission::PermissionChecker permissionChecker;
137     bool permitted = false;
138     if (start) {
139         permitted = (permissionChecker.checkPermissionForStartDataDeliveryFromDatasource(
140                 sAndroidPermissionRecordAudio, resolvedAttributionSource.value(), msg,
141                 attributedOpCode) != permission::PermissionChecker::PERMISSION_HARD_DENIED);
142     } else {
143         permitted = (permissionChecker.checkPermissionForPreflightFromDatasource(
144                 sAndroidPermissionRecordAudio, resolvedAttributionSource.value(), msg,
145                 attributedOpCode) != permission::PermissionChecker::PERMISSION_HARD_DENIED);
146     }
147 
148     return permitted;
149 }
150 
recordingAllowed(const AttributionSourceState & attributionSource,audio_source_t source)151 bool recordingAllowed(const AttributionSourceState& attributionSource, audio_source_t source) {
152     return checkRecordingInternal(attributionSource, String16(), /*start*/ false, source);
153 }
154 
startRecording(const AttributionSourceState & attributionSource,const String16 & msg,audio_source_t source)155 bool startRecording(const AttributionSourceState& attributionSource, const String16& msg,
156         audio_source_t source) {
157     return checkRecordingInternal(attributionSource, msg, /*start*/ true, source);
158 }
159 
finishRecording(const AttributionSourceState & attributionSource,audio_source_t source)160 void finishRecording(const AttributionSourceState& attributionSource, audio_source_t source) {
161     // Okay to not track in app ops as audio server is us and if
162     // device is rooted security model is considered compromised.
163     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
164     if (isAudioServerOrMediaServerOrSystemServerOrRootUid(uid)) return;
165 
166     // We specify a pid and uid here as mediaserver (aka MediaRecorder or StageFrightRecorder)
167     // may open a record track on behalf of a client. Note that pid may be a tid.
168     // IMPORTANT: DON'T USE PermissionCache - RUNTIME PERMISSIONS CHANGE.
169     const std::optional<AttributionSourceState> resolvedAttributionSource =
170             resolveAttributionSource(attributionSource);
171     if (!resolvedAttributionSource.has_value()) {
172         return;
173     }
174 
175     const int32_t attributedOpCode = getOpForSource(source);
176     permission::PermissionChecker permissionChecker;
177     permissionChecker.finishDataDeliveryFromDatasource(attributedOpCode,
178             resolvedAttributionSource.value());
179 }
180 
captureAudioOutputAllowed(const AttributionSourceState & attributionSource)181 bool captureAudioOutputAllowed(const AttributionSourceState& attributionSource) {
182     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
183     if (isAudioServerOrRootUid(uid)) return true;
184     static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
185     // Use PermissionChecker, which includes some logic for allowing the isolated
186     // HotwordDetectionService to hold certain permissions.
187     permission::PermissionChecker permissionChecker;
188     bool ok = (permissionChecker.checkPermissionForPreflight(
189             sCaptureAudioOutput, attributionSource, String16(),
190             AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED);
191     if (!ok) ALOGV("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
192     return ok;
193 }
194 
captureMediaOutputAllowed(const AttributionSourceState & attributionSource)195 bool captureMediaOutputAllowed(const AttributionSourceState& attributionSource) {
196     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
197     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
198     if (isAudioServerOrRootUid(uid)) return true;
199     static const String16 sCaptureMediaOutput("android.permission.CAPTURE_MEDIA_OUTPUT");
200     bool ok = PermissionCache::checkPermission(sCaptureMediaOutput, pid, uid);
201     if (!ok) ALOGE("Request requires android.permission.CAPTURE_MEDIA_OUTPUT");
202     return ok;
203 }
204 
captureTunerAudioInputAllowed(const AttributionSourceState & attributionSource)205 bool captureTunerAudioInputAllowed(const AttributionSourceState& attributionSource) {
206     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
207     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
208     if (isAudioServerOrRootUid(uid)) return true;
209     static const String16 sCaptureTunerAudioInput("android.permission.CAPTURE_TUNER_AUDIO_INPUT");
210     bool ok = PermissionCache::checkPermission(sCaptureTunerAudioInput, pid, uid);
211     if (!ok) ALOGV("Request requires android.permission.CAPTURE_TUNER_AUDIO_INPUT");
212     return ok;
213 }
214 
captureVoiceCommunicationOutputAllowed(const AttributionSourceState & attributionSource)215 bool captureVoiceCommunicationOutputAllowed(const AttributionSourceState& attributionSource) {
216     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
217     uid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
218     if (isAudioServerOrRootUid(uid)) return true;
219     static const String16 sCaptureVoiceCommOutput(
220         "android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT");
221     bool ok = PermissionCache::checkPermission(sCaptureVoiceCommOutput, pid, uid);
222     if (!ok) ALOGE("Request requires android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT");
223     return ok;
224 }
225 
accessUltrasoundAllowed(const AttributionSourceState & attributionSource)226 bool accessUltrasoundAllowed(const AttributionSourceState& attributionSource) {
227     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
228     uid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
229     if (isAudioServerOrRootUid(uid)) return true;
230     static const String16 sAccessUltrasound(
231         "android.permission.ACCESS_ULTRASOUND");
232     bool ok = PermissionCache::checkPermission(sAccessUltrasound, pid, uid);
233     if (!ok) ALOGE("Request requires android.permission.ACCESS_ULTRASOUND");
234     return ok;
235 }
236 
captureHotwordAllowed(const AttributionSourceState & attributionSource)237 bool captureHotwordAllowed(const AttributionSourceState& attributionSource) {
238     // CAPTURE_AUDIO_HOTWORD permission implies RECORD_AUDIO permission
239     bool ok = recordingAllowed(attributionSource);
240 
241     if (ok) {
242         static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD");
243         // Use PermissionChecker, which includes some logic for allowing the isolated
244         // HotwordDetectionService to hold certain permissions.
245         permission::PermissionChecker permissionChecker;
246         ok = (permissionChecker.checkPermissionForPreflight(
247                 sCaptureHotwordAllowed, attributionSource, String16(),
248                 AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED);
249     }
250     if (!ok) ALOGV("android.permission.CAPTURE_AUDIO_HOTWORD");
251     return ok;
252 }
253 
settingsAllowed()254 bool settingsAllowed() {
255     // given this is a permission check, could this be isAudioServerOrRootUid()?
256     if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
257     static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS");
258     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
259     bool ok = PermissionCache::checkCallingPermission(sAudioSettings);
260     if (!ok) ALOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
261     return ok;
262 }
263 
modifyAudioRoutingAllowed()264 bool modifyAudioRoutingAllowed() {
265     return modifyAudioRoutingAllowed(getCallingAttributionSource());
266 }
267 
modifyAudioRoutingAllowed(const AttributionSourceState & attributionSource)268 bool modifyAudioRoutingAllowed(const AttributionSourceState& attributionSource) {
269     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
270     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
271     if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
272     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
273     bool ok = PermissionCache::checkPermission(sModifyAudioRouting, pid, uid);
274     if (!ok) ALOGE("%s(): android.permission.MODIFY_AUDIO_ROUTING denied for uid %d",
275         __func__, uid);
276     return ok;
277 }
278 
modifyDefaultAudioEffectsAllowed()279 bool modifyDefaultAudioEffectsAllowed() {
280     return modifyDefaultAudioEffectsAllowed(getCallingAttributionSource());
281 }
282 
modifyDefaultAudioEffectsAllowed(const AttributionSourceState & attributionSource)283 bool modifyDefaultAudioEffectsAllowed(const AttributionSourceState& attributionSource) {
284     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
285     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
286     if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
287 
288     static const String16 sModifyDefaultAudioEffectsAllowed(
289             "android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
290     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
291     bool ok = PermissionCache::checkPermission(sModifyDefaultAudioEffectsAllowed, pid, uid);
292     ALOGE_IF(!ok, "%s(): android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS denied for uid %d",
293             __func__, uid);
294     return ok;
295 }
296 
dumpAllowed()297 bool dumpAllowed() {
298     static const String16 sDump("android.permission.DUMP");
299     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
300     bool ok = PermissionCache::checkCallingPermission(sDump);
301     // convention is for caller to dump an error message to fd instead of logging here
302     //if (!ok) ALOGE("Request requires android.permission.DUMP");
303     return ok;
304 }
305 
modifyPhoneStateAllowed(const AttributionSourceState & attributionSource)306 bool modifyPhoneStateAllowed(const AttributionSourceState& attributionSource) {
307     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
308     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
309     bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid);
310     ALOGE_IF(!ok, "Request requires %s", String8(sModifyPhoneState).c_str());
311     return ok;
312 }
313 
314 // privileged behavior needed by Dialer, Settings, SetupWizard and CellBroadcastReceiver
bypassInterruptionPolicyAllowed(const AttributionSourceState & attributionSource)315 bool bypassInterruptionPolicyAllowed(const AttributionSourceState& attributionSource) {
316     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
317     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
318     static const String16 sWriteSecureSettings("android.permission.WRITE_SECURE_SETTINGS");
319     bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid)
320         || PermissionCache::checkPermission(sWriteSecureSettings, pid, uid)
321         || PermissionCache::checkPermission(sModifyAudioRouting, pid, uid);
322     ALOGE_IF(!ok, "Request requires %s or %s",
323              String8(sModifyPhoneState).c_str(), String8(sWriteSecureSettings).c_str());
324     return ok;
325 }
326 
callAudioInterceptionAllowed(const AttributionSourceState & attributionSource)327 bool callAudioInterceptionAllowed(const AttributionSourceState& attributionSource) {
328     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
329     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
330 
331     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
332     bool ok = PermissionCache::checkPermission(sCallAudioInterception, pid, uid);
333     if (!ok) ALOGV("%s(): android.permission.CALL_AUDIO_INTERCEPTION denied for uid %d",
334         __func__, uid);
335     return ok;
336 }
337 
getCallingAttributionSource()338 AttributionSourceState getCallingAttributionSource() {
339     AttributionSourceState attributionSource = AttributionSourceState();
340     attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(
341             IPCThreadState::self()->getCallingPid()));
342     attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(
343             IPCThreadState::self()->getCallingUid()));
344     attributionSource.token = sp<BBinder>::make();
345   return attributionSource;
346 }
347 
purgePermissionCache()348 void purgePermissionCache() {
349     PermissionCache::purgeCache();
350 }
351 
checkIMemory(const sp<IMemory> & iMemory)352 status_t checkIMemory(const sp<IMemory>& iMemory)
353 {
354     if (iMemory == 0) {
355         ALOGE("%s check failed: NULL IMemory pointer", __FUNCTION__);
356         return BAD_VALUE;
357     }
358 
359     sp<IMemoryHeap> heap = iMemory->getMemory();
360     if (heap == 0) {
361         ALOGE("%s check failed: NULL heap pointer", __FUNCTION__);
362         return BAD_VALUE;
363     }
364 
365     off_t size = lseek(heap->getHeapID(), 0, SEEK_END);
366     lseek(heap->getHeapID(), 0, SEEK_SET);
367 
368     if (iMemory->unsecurePointer() == NULL || size < (off_t)iMemory->size()) {
369         ALOGE("%s check failed: pointer %p size %zu fd size %u",
370               __FUNCTION__, iMemory->unsecurePointer(), iMemory->size(), (uint32_t)size);
371         return BAD_VALUE;
372     }
373 
374     return NO_ERROR;
375 }
376 
retrievePackageManager()377 sp<content::pm::IPackageManagerNative> MediaPackageManager::retrievePackageManager() {
378     const sp<IServiceManager> sm = defaultServiceManager();
379     if (sm == nullptr) {
380         ALOGW("%s: failed to retrieve defaultServiceManager", __func__);
381         return nullptr;
382     }
383     sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName));
384     if (packageManager == nullptr) {
385         ALOGW("%s: failed to retrieve native package manager", __func__);
386         return nullptr;
387     }
388     return interface_cast<content::pm::IPackageManagerNative>(packageManager);
389 }
390 
doIsAllowed(uid_t uid)391 std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) {
392     if (mPackageManager == nullptr) {
393         /** Can not fetch package manager at construction it may not yet be registered. */
394         mPackageManager = retrievePackageManager();
395         if (mPackageManager == nullptr) {
396             ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
397             return std::nullopt;
398         }
399     }
400 
401     // Retrieve package names for the UID and transform to a std::vector<std::string>.
402     Vector<String16> str16PackageNames;
403     PermissionController{}.getPackagesForUid(uid, str16PackageNames);
404     std::vector<std::string> packageNames;
405     for (const auto& str16PackageName : str16PackageNames) {
406         packageNames.emplace_back(String8(str16PackageName).string());
407     }
408     if (packageNames.empty()) {
409         ALOGW("%s: Playback capture for uid %u is denied as no package name could be retrieved "
410               "from the package manager.", __func__, uid);
411         return std::nullopt;
412     }
413     std::vector<bool> isAllowed;
414     auto status = mPackageManager->isAudioPlaybackCaptureAllowed(packageNames, &isAllowed);
415     if (!status.isOk()) {
416         ALOGW("%s: Playback capture is denied for uid %u as the manifest property could not be "
417               "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str());
418         return std::nullopt;
419     }
420     if (packageNames.size() != isAllowed.size()) {
421         ALOGW("%s: Playback capture is denied for uid %u as the package manager returned incoherent"
422               " response size: %zu != %zu", __func__, uid, packageNames.size(), isAllowed.size());
423         return std::nullopt;
424     }
425 
426     // Zip together packageNames and isAllowed for debug logs
427     Packages& packages = mDebugLog[uid];
428     packages.resize(packageNames.size()); // Reuse all objects
429     std::transform(begin(packageNames), end(packageNames), begin(isAllowed),
430                    begin(packages), [] (auto& name, bool isAllowed) -> Package {
431                        return {std::move(name), isAllowed};
432                    });
433 
434     // Only allow playback record if all packages in this UID allow it
435     bool playbackCaptureAllowed = std::all_of(begin(isAllowed), end(isAllowed),
436                                                   [](bool b) { return b; });
437 
438     return playbackCaptureAllowed;
439 }
440 
dump(int fd,int spaces) const441 void MediaPackageManager::dump(int fd, int spaces) const {
442     dprintf(fd, "%*sAllow playback capture log:\n", spaces, "");
443     if (mPackageManager == nullptr) {
444         dprintf(fd, "%*sNo package manager\n", spaces + 2, "");
445     }
446     dprintf(fd, "%*sPackage manager errors: %u\n", spaces + 2, "", mPackageManagerErrors);
447 
448     for (const auto& uidCache : mDebugLog) {
449         for (const auto& package : std::get<Packages>(uidCache)) {
450             dprintf(fd, "%*s- uid=%5u, allowPlaybackCapture=%s, packageName=%s\n", spaces + 2, "",
451                     std::get<const uid_t>(uidCache),
452                     package.playbackCaptureAllowed ? "true " : "false",
453                     package.name.c_str());
454         }
455     }
456 }
457 
458 // How long we hold info before we re-fetch it (24 hours) if we found it previously.
459 static constexpr nsecs_t INFO_EXPIRATION_NS = 24 * 60 * 60 * NANOS_PER_SECOND;
460 // Maximum info records we retain before clearing everything.
461 static constexpr size_t INFO_CACHE_MAX = 1000;
462 
463 // The original code is from MediaMetricsService.cpp.
getInfo(uid_t uid)464 mediautils::UidInfo::Info mediautils::UidInfo::getInfo(uid_t uid)
465 {
466     const nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
467     struct mediautils::UidInfo::Info info;
468     {
469         std::lock_guard _l(mLock);
470         auto it = mInfoMap.find(uid);
471         if (it != mInfoMap.end()) {
472             info = it->second;
473             ALOGV("%s: uid %d expiration %lld now %lld",
474                     __func__, uid, (long long)info.expirationNs, (long long)now);
475             if (info.expirationNs <= now) {
476                 // purge the stale entry and fall into re-fetching
477                 ALOGV("%s: entry for uid %d expired, now %lld",
478                         __func__, uid, (long long)now);
479                 mInfoMap.erase(it);
480                 info.uid = (uid_t)-1;  // this is always fully overwritten
481             }
482         }
483     }
484 
485     // if we did not find it in our map, look it up
486     if (info.uid == (uid_t)(-1)) {
487         sp<IServiceManager> sm = defaultServiceManager();
488         sp<content::pm::IPackageManagerNative> package_mgr;
489         if (sm.get() == nullptr) {
490             ALOGE("%s: Cannot find service manager", __func__);
491         } else {
492             sp<IBinder> binder = sm->getService(String16("package_native"));
493             if (binder.get() == nullptr) {
494                 ALOGE("%s: Cannot find package_native", __func__);
495             } else {
496                 package_mgr = interface_cast<content::pm::IPackageManagerNative>(binder);
497             }
498         }
499 
500         // find package name
501         std::string pkg;
502         if (package_mgr != nullptr) {
503             std::vector<std::string> names;
504             binder::Status status = package_mgr->getNamesForUids({(int)uid}, &names);
505             if (!status.isOk()) {
506                 ALOGE("%s: getNamesForUids failed: %s",
507                         __func__, status.exceptionMessage().c_str());
508             } else {
509                 if (!names[0].empty()) {
510                     pkg = names[0].c_str();
511                 }
512             }
513         }
514 
515         if (pkg.empty()) {
516             struct passwd pw{}, *result;
517             char buf[8192]; // extra buffer space - should exceed what is
518                             // required in struct passwd_pw (tested),
519                             // and even then this is only used in backup
520                             // when the package manager is unavailable.
521             if (getpwuid_r(uid, &pw, buf, sizeof(buf), &result) == 0
522                     && result != nullptr
523                     && result->pw_name != nullptr) {
524                 pkg = result->pw_name;
525             }
526         }
527 
528         // strip any leading "shared:" strings that came back
529         if (pkg.compare(0, 7, "shared:") == 0) {
530             pkg.erase(0, 7);
531         }
532 
533         // determine how pkg was installed and the versionCode
534         std::string installer;
535         int64_t versionCode = 0;
536         bool notFound = false;
537         if (pkg.empty()) {
538             pkg = std::to_string(uid); // not found
539             notFound = true;
540         } else if (strchr(pkg.c_str(), '.') == nullptr) {
541             // not of form 'com.whatever...'; assume internal
542             // so we don't need to look it up in package manager.
543         } else if (strncmp(pkg.c_str(), "android.", 8) == 0) {
544             // android.* packages are assumed fine
545         } else if (package_mgr.get() != nullptr) {
546             String16 pkgName16(pkg.c_str());
547             binder::Status status = package_mgr->getInstallerForPackage(pkgName16, &installer);
548             if (!status.isOk()) {
549                 ALOGE("%s: getInstallerForPackage failed: %s",
550                         __func__, status.exceptionMessage().c_str());
551             }
552 
553             // skip if we didn't get an installer
554             if (status.isOk()) {
555                 status = package_mgr->getVersionCodeForPackage(pkgName16, &versionCode);
556                 if (!status.isOk()) {
557                     ALOGE("%s: getVersionCodeForPackage failed: %s",
558                             __func__, status.exceptionMessage().c_str());
559                 }
560             }
561 
562             ALOGV("%s: package '%s' installed by '%s' versioncode %lld",
563                     __func__, pkg.c_str(), installer.c_str(), (long long)versionCode);
564         }
565 
566         // add it to the map, to save a subsequent lookup
567         std::lock_guard _l(mLock);
568         // first clear if we have too many cached elements.  This would be rare.
569         if (mInfoMap.size() >= INFO_CACHE_MAX) mInfoMap.clear();
570 
571         // always overwrite
572         info.uid = uid;
573         info.package = std::move(pkg);
574         info.installer = std::move(installer);
575         info.versionCode = versionCode;
576         info.expirationNs = now + (notFound ? 0 : INFO_EXPIRATION_NS);
577         ALOGV("%s: adding uid %d package '%s' expirationNs: %lld",
578                 __func__, uid, info.package.c_str(), (long long)info.expirationNs);
579         mInfoMap[uid] = info;
580     }
581     return info;
582 }
583 
584 } // namespace android
585