frameworks/av
Revision | 6c94bb8058cddf934f4fbe209e796621edbbefec (tree) |
---|---|
Time | 2020-01-20 19:53:58 |
Author | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge tag 'android-9.0.0_r52' into pie-x86
Android 9.0.0 release 52
@@ -1723,7 +1723,8 @@ sp<media::IAudioRecord> AudioFlinger::createRecord(const CreateRecordInput& inpu | ||
1723 | 1723 | &output.notificationFrameCount, |
1724 | 1724 | clientUid, &output.flags, |
1725 | 1725 | input.clientInfo.clientTid, |
1726 | - &lStatus, portId); | |
1726 | + &lStatus, portId, | |
1727 | + input.opPackageName); | |
1727 | 1728 | LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0)); |
1728 | 1729 | |
1729 | 1730 | // lStatus == BAD_TYPE means FAST flag was rejected: request a new input from |
@@ -48,7 +48,9 @@ | ||
48 | 48 | #include <utils/TypeHelpers.h> |
49 | 49 | #include <utils/Vector.h> |
50 | 50 | |
51 | +#include <binder/AppOpsManager.h> | |
51 | 52 | #include <binder/BinderService.h> |
53 | +#include <binder/IAppOpsCallback.h> | |
52 | 54 | #include <binder/MemoryDealer.h> |
53 | 55 | |
54 | 56 | #include <system/audio.h> |
@@ -19,6 +19,39 @@ | ||
19 | 19 | #error This header file should only be included from AudioFlinger.h |
20 | 20 | #endif |
21 | 21 | |
22 | +// Checks and monitors OP_RECORD_AUDIO | |
23 | +class OpRecordAudioMonitor : public RefBase { | |
24 | +public: | |
25 | + ~OpRecordAudioMonitor() override; | |
26 | + bool hasOpRecordAudio() const; | |
27 | + | |
28 | + static sp<OpRecordAudioMonitor> createIfNeeded(uid_t uid, const String16& opPackageName); | |
29 | + | |
30 | +private: | |
31 | + OpRecordAudioMonitor(uid_t uid, const String16& opPackageName); | |
32 | + void onFirstRef() override; | |
33 | + | |
34 | + AppOpsManager mAppOpsManager; | |
35 | + | |
36 | + class RecordAudioOpCallback : public BnAppOpsCallback { | |
37 | + public: | |
38 | + explicit RecordAudioOpCallback(const wp<OpRecordAudioMonitor>& monitor); | |
39 | + void opChanged(int32_t op, const String16& packageName) override; | |
40 | + | |
41 | + private: | |
42 | + const wp<OpRecordAudioMonitor> mMonitor; | |
43 | + }; | |
44 | + | |
45 | + sp<RecordAudioOpCallback> mOpCallback; | |
46 | + // called by RecordAudioOpCallback when OP_RECORD_AUDIO is updated in AppOp callback | |
47 | + // and in onFirstRef() | |
48 | + void checkRecordAudio(); | |
49 | + | |
50 | + std::atomic_bool mHasOpRecordAudio; | |
51 | + const uid_t mUid; | |
52 | + const String16 mPackage; | |
53 | +}; | |
54 | + | |
22 | 55 | // record track |
23 | 56 | class RecordTrack : public TrackBase { |
24 | 57 | public: |
@@ -35,6 +68,7 @@ public: | ||
35 | 68 | uid_t uid, |
36 | 69 | audio_input_flags_t flags, |
37 | 70 | track_type type, |
71 | + const String16& opPackageName, | |
38 | 72 | audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE); |
39 | 73 | virtual ~RecordTrack(); |
40 | 74 | virtual status_t initCheck() const; |
@@ -65,7 +99,7 @@ public: | ||
65 | 99 | virtual bool isFastTrack() const { return (mFlags & AUDIO_INPUT_FLAG_FAST) != 0; } |
66 | 100 | |
67 | 101 | void setSilenced(bool silenced) { if (!isPatchTrack()) mSilenced = silenced; } |
68 | - bool isSilenced() const { return mSilenced; } | |
102 | + bool isSilenced() const; | |
69 | 103 | |
70 | 104 | status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones); |
71 | 105 |
@@ -99,6 +133,11 @@ private: | ||
99 | 133 | audio_input_flags_t mFlags; |
100 | 134 | |
101 | 135 | bool mSilenced; |
136 | + | |
137 | + // used to enforce OP_RECORD_AUDIO | |
138 | + uid_t mUid; | |
139 | + String16 mOpPackageName; | |
140 | + sp<OpRecordAudioMonitor> mOpRecordAudioMonitor; | |
102 | 141 | }; |
103 | 142 | |
104 | 143 | // playback track, used by PatchPanel |
@@ -14,12 +14,21 @@ | ||
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 | |
17 | +#include <cutils/multiuser.h> | |
18 | +#include <private/android_filesystem_config.h> | |
17 | 19 | #include <unistd.h> |
18 | 20 | |
19 | 21 | #include <binder/PermissionController.h> |
20 | 22 | |
21 | 23 | namespace android { |
22 | 24 | |
25 | +// Used for calls that should originate from system services. | |
26 | +// We allow that some services might have separate processes to | |
27 | +// handle multiple users, e.g. u10_system, u10_bluetooth, u10_radio. | |
28 | +static inline bool isServiceUid(uid_t uid) { | |
29 | + return multiuser_get_app_id(uid) < AID_APP_START; | |
30 | +} | |
31 | + | |
23 | 32 | extern pid_t getpid_cached; |
24 | 33 | bool isTrustedCallingUid(uid_t uid); |
25 | 34 | bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid); |
@@ -6778,7 +6778,7 @@ reacquire_wakelock: | ||
6778 | 6778 | // Sanitize before releasing if the track has no access to the source data |
6779 | 6779 | // An idle UID receives silence from non virtual devices until active |
6780 | 6780 | if (activeTrack->isSilenced()) { |
6781 | - memset(activeTrack->mSink.raw, 0, framesOut * mFrameSize); | |
6781 | + memset(activeTrack->mSink.raw, 0, framesOut * activeTrack->frameSize()); | |
6782 | 6782 | } |
6783 | 6783 | activeTrack->releaseBuffer(&activeTrack->mSink); |
6784 | 6784 | } |
@@ -6921,7 +6921,8 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRe | ||
6921 | 6921 | audio_input_flags_t *flags, |
6922 | 6922 | pid_t tid, |
6923 | 6923 | status_t *status, |
6924 | - audio_port_handle_t portId) | |
6924 | + audio_port_handle_t portId, | |
6925 | + const String16& opPackageName) | |
6925 | 6926 | { |
6926 | 6927 | size_t frameCount = *pFrameCount; |
6927 | 6928 | size_t notificationFrameCount = *pNotificationFrameCount; |
@@ -7047,7 +7048,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRe | ||
7047 | 7048 | track = new RecordTrack(this, client, attr, sampleRate, |
7048 | 7049 | format, channelMask, frameCount, |
7049 | 7050 | nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, uid, |
7050 | - *flags, TrackBase::TYPE_DEFAULT, portId); | |
7051 | + *flags, TrackBase::TYPE_DEFAULT, opPackageName, portId); | |
7051 | 7052 | |
7052 | 7053 | lStatus = track->initCheck(); |
7053 | 7054 | if (lStatus != NO_ERROR) { |
@@ -1413,7 +1413,8 @@ public: | ||
1413 | 1413 | audio_input_flags_t *flags, |
1414 | 1414 | pid_t tid, |
1415 | 1415 | status_t *status /*non-NULL*/, |
1416 | - audio_port_handle_t portId); | |
1416 | + audio_port_handle_t portId, | |
1417 | + const String16& opPackageName); | |
1417 | 1418 | |
1418 | 1419 | status_t start(RecordTrack* recordTrack, |
1419 | 1420 | AudioSystem::sync_event_t event, |
@@ -115,6 +115,8 @@ protected: | ||
115 | 115 | |
116 | 116 | uint32_t channelCount() const { return mChannelCount; } |
117 | 117 | |
118 | + size_t frameSize() const { return mFrameSize; } | |
119 | + | |
118 | 120 | audio_channel_mask_t channelMask() const { return mChannelMask; } |
119 | 121 | |
120 | 122 | virtual uint32_t sampleRate() const { return mSampleRate; } |
@@ -1601,6 +1601,99 @@ void AudioFlinger::PlaybackThread::PatchTrack::restartIfDisabled() | ||
1601 | 1601 | // Record |
1602 | 1602 | // ---------------------------------------------------------------------------- |
1603 | 1603 | |
1604 | +// ---------------------------------------------------------------------------- | |
1605 | +// AppOp for audio recording | |
1606 | +// ------------------------------- | |
1607 | + | |
1608 | +// static | |
1609 | +sp<AudioFlinger::RecordThread::OpRecordAudioMonitor> | |
1610 | +AudioFlinger::RecordThread::OpRecordAudioMonitor::createIfNeeded( | |
1611 | + uid_t uid, const String16& opPackageName) | |
1612 | +{ | |
1613 | + if (isServiceUid(uid)) { | |
1614 | + ALOGV("not silencing record for service uid:%d pack:%s", | |
1615 | + uid, String8(opPackageName).string()); | |
1616 | + return nullptr; | |
1617 | + } | |
1618 | + | |
1619 | + if (opPackageName.size() == 0) { | |
1620 | + Vector<String16> packages; | |
1621 | + // no package name, happens with SL ES clients | |
1622 | + // query package manager to find one | |
1623 | + PermissionController permissionController; | |
1624 | + permissionController.getPackagesForUid(uid, packages); | |
1625 | + if (packages.isEmpty()) { | |
1626 | + return nullptr; | |
1627 | + } else { | |
1628 | + ALOGV("using pack:%s for uid:%d", String8(packages[0]).string(), uid); | |
1629 | + return new OpRecordAudioMonitor(uid, packages[0]); | |
1630 | + } | |
1631 | + } | |
1632 | + | |
1633 | + return new OpRecordAudioMonitor(uid, opPackageName); | |
1634 | +} | |
1635 | + | |
1636 | +AudioFlinger::RecordThread::OpRecordAudioMonitor::OpRecordAudioMonitor( | |
1637 | + uid_t uid, const String16& opPackageName) | |
1638 | + : mHasOpRecordAudio(true), mUid(uid), mPackage(opPackageName) | |
1639 | +{ | |
1640 | +} | |
1641 | + | |
1642 | +AudioFlinger::RecordThread::OpRecordAudioMonitor::~OpRecordAudioMonitor() | |
1643 | +{ | |
1644 | + if (mOpCallback != 0) { | |
1645 | + mAppOpsManager.stopWatchingMode(mOpCallback); | |
1646 | + } | |
1647 | + mOpCallback.clear(); | |
1648 | +} | |
1649 | + | |
1650 | +void AudioFlinger::RecordThread::OpRecordAudioMonitor::onFirstRef() | |
1651 | +{ | |
1652 | + checkRecordAudio(); | |
1653 | + mOpCallback = new RecordAudioOpCallback(this); | |
1654 | + ALOGV("start watching OP_RECORD_AUDIO for pack:%s", String8(mPackage).string()); | |
1655 | + mAppOpsManager.startWatchingMode(AppOpsManager::OP_RECORD_AUDIO, mPackage, mOpCallback); | |
1656 | +} | |
1657 | + | |
1658 | +bool AudioFlinger::RecordThread::OpRecordAudioMonitor::hasOpRecordAudio() const { | |
1659 | + return mHasOpRecordAudio.load(); | |
1660 | +} | |
1661 | + | |
1662 | +// Called by RecordAudioOpCallback when OP_RECORD_AUDIO is updated in AppOp callback | |
1663 | +// and in onFirstRef() | |
1664 | +// Note this method is never called (and never to be) for audio server / patch record track | |
1665 | +// due to the UID in createIfNeeded(). As a result for those record track, it's: | |
1666 | +// - not called from constructor, | |
1667 | +// - not called from RecordAudioOpCallback because the callback is not installed in this case | |
1668 | +void AudioFlinger::RecordThread::OpRecordAudioMonitor::checkRecordAudio() | |
1669 | +{ | |
1670 | + const int32_t mode = mAppOpsManager.checkOp(AppOpsManager::OP_RECORD_AUDIO, | |
1671 | + mUid, mPackage); | |
1672 | + const bool hasIt = (mode == AppOpsManager::MODE_ALLOWED); | |
1673 | + // verbose logging only log when appOp changed | |
1674 | + ALOGI_IF(hasIt != mHasOpRecordAudio.load(), | |
1675 | + "OP_RECORD_AUDIO missing, %ssilencing record uid%d pack:%s", | |
1676 | + hasIt ? "un" : "", mUid, String8(mPackage).string()); | |
1677 | + mHasOpRecordAudio.store(hasIt); | |
1678 | +} | |
1679 | + | |
1680 | +AudioFlinger::RecordThread::OpRecordAudioMonitor::RecordAudioOpCallback::RecordAudioOpCallback( | |
1681 | + const wp<OpRecordAudioMonitor>& monitor) : mMonitor(monitor) | |
1682 | +{ } | |
1683 | + | |
1684 | +void AudioFlinger::RecordThread::OpRecordAudioMonitor::RecordAudioOpCallback::opChanged(int32_t op, | |
1685 | + const String16& packageName) { | |
1686 | + UNUSED(packageName); | |
1687 | + if (op != AppOpsManager::OP_RECORD_AUDIO) { | |
1688 | + return; | |
1689 | + } | |
1690 | + sp<OpRecordAudioMonitor> monitor = mMonitor.promote(); | |
1691 | + if (monitor != NULL) { | |
1692 | + monitor->checkRecordAudio(); | |
1693 | + } | |
1694 | +} | |
1695 | + | |
1696 | +//---------------------------------------- | |
1604 | 1697 | AudioFlinger::RecordHandle::RecordHandle( |
1605 | 1698 | const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack) |
1606 | 1699 | : BnAudioRecord(), |
@@ -1654,6 +1747,7 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack( | ||
1654 | 1747 | uid_t uid, |
1655 | 1748 | audio_input_flags_t flags, |
1656 | 1749 | track_type type, |
1750 | + const String16& opPackageName, | |
1657 | 1751 | audio_port_handle_t portId) |
1658 | 1752 | : TrackBase(thread, client, attr, sampleRate, format, |
1659 | 1753 | channelMask, frameCount, buffer, bufferSize, sessionId, uid, false /*isOut*/, |
@@ -1666,7 +1760,8 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack( | ||
1666 | 1760 | mResamplerBufferProvider(NULL), // initialize in case of early constructor exit |
1667 | 1761 | mRecordBufferConverter(NULL), |
1668 | 1762 | mFlags(flags), |
1669 | - mSilenced(false) | |
1763 | + mSilenced(false), | |
1764 | + mOpRecordAudioMonitor(OpRecordAudioMonitor::createIfNeeded(uid, opPackageName)) | |
1670 | 1765 | { |
1671 | 1766 | if (mCblk == NULL) { |
1672 | 1767 | return; |
@@ -1852,6 +1947,14 @@ void AudioFlinger::RecordThread::RecordTrack::updateTrackFrameInfo( | ||
1852 | 1947 | mServerProxy->setTimestamp(local); |
1853 | 1948 | } |
1854 | 1949 | |
1950 | +bool AudioFlinger::RecordThread::RecordTrack::isSilenced() const { | |
1951 | + if (mSilenced) { | |
1952 | + return true; | |
1953 | + } | |
1954 | + // The monitor is only created for record tracks that can be silenced. | |
1955 | + return mOpRecordAudioMonitor ? !mOpRecordAudioMonitor->hasOpRecordAudio() : false; | |
1956 | +} | |
1957 | + | |
1855 | 1958 | status_t AudioFlinger::RecordThread::RecordTrack::getActiveMicrophones( |
1856 | 1959 | std::vector<media::MicrophoneInfo>* activeMicrophones) |
1857 | 1960 | { |
@@ -1875,7 +1978,7 @@ AudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread, | ||
1875 | 1978 | : RecordTrack(recordThread, NULL, |
1876 | 1979 | audio_attributes_t{} /* currently unused for patch track */, |
1877 | 1980 | sampleRate, format, channelMask, frameCount, |
1878 | - buffer, bufferSize, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH), | |
1981 | + buffer, bufferSize, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH, String16()), | |
1879 | 1982 | mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true)) |
1880 | 1983 | { |
1881 | 1984 | uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) / |