Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 908c7d77 authored by luochaojiang's avatar luochaojiang Committed by Eric Laurent
Browse files

audiopolicy: Restrict the audio port callbacks by both uid and pid



Set audio port callbacks enabled is called by each client, the client
maybe has the same uid by different pid. And the notification clients
is indexed with uid in services, so the audio port cb may be disabled
by other pid. Here is the steps to reproduce this issue:
1.make a phone call
2.plugin a USB headset
3.check the P-sensor
The screen will get black when the hand is near to the phone, actually
it should not get black

Test: make, take a photo, record a video and play video; make a call,
plugin a USB headset, and check the P-sensor status.

Change-Id: I43970ca0ab78ef47bd34d1c7191d4c8c3ad2b793
Signed-off-by: default avatarluochaojiang <luochaojiang@xiaomi.com>
parent 87a837c6
Loading
Loading
Loading
Loading
+28 −12
Original line number Diff line number Diff line
@@ -115,13 +115,17 @@ void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& cli
    Mutex::Autolock _l(mNotificationClientsLock);

    uid_t uid = IPCThreadState::self()->getCallingUid();
    if (mNotificationClients.indexOfKey(uid) < 0) {
    pid_t pid = IPCThreadState::self()->getCallingPid();
    int64_t token = ((int64_t)uid<<32) | pid;

    if (mNotificationClients.indexOfKey(token) < 0) {
        sp<NotificationClient> notificationClient = new NotificationClient(this,
                                                                           client,
                                                                           uid);
        ALOGV("registerClient() client %p, uid %d", client.get(), uid);
                                                                           uid,
                                                                           pid);
        ALOGV("registerClient() client %p, uid %d pid %d", client.get(), uid, pid);

        mNotificationClients.add(uid, notificationClient);
        mNotificationClients.add(token, notificationClient);

        sp<IBinder> binder = IInterface::asBinder(client);
        binder->linkToDeath(notificationClient);
@@ -133,22 +137,33 @@ void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
    Mutex::Autolock _l(mNotificationClientsLock);

    uid_t uid = IPCThreadState::self()->getCallingUid();
    if (mNotificationClients.indexOfKey(uid) < 0) {
    pid_t pid = IPCThreadState::self()->getCallingPid();
    int64_t token = ((int64_t)uid<<32) | pid;

    if (mNotificationClients.indexOfKey(token) < 0) {
        return;
    }
    mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled);
    mNotificationClients.valueFor(token)->setAudioPortCallbacksEnabled(enabled);
}

// removeNotificationClient() is called when the client process dies.
void AudioPolicyService::removeNotificationClient(uid_t uid)
void AudioPolicyService::removeNotificationClient(uid_t uid, pid_t pid)
{
    {
        Mutex::Autolock _l(mNotificationClientsLock);
        mNotificationClients.removeItem(uid);
        int64_t token = ((int64_t)uid<<32) | pid;
        mNotificationClients.removeItem(token);
    }
    {
        Mutex::Autolock _l(mLock);
        if (mAudioPolicyManager) {
        bool hasSameUid = false;
        for (size_t i = 0; i < mNotificationClients.size(); i++) {
            if (mNotificationClients.valueAt(i)->uid() == uid) {
                hasSameUid = true;
                break;
            }
        }
        if (mAudioPolicyManager && !hasSameUid) {
            // called from binder death notification: no need to clear caller identity
            mAudioPolicyManager->releaseResourcesForUid(uid);
        }
@@ -236,8 +251,9 @@ status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_co

AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
                                                     const sp<IAudioPolicyServiceClient>& client,
                                                     uid_t uid)
    : mService(service), mUid(uid), mAudioPolicyServiceClient(client),
                                                     uid_t uid,
                                                     pid_t pid)
    : mService(service), mUid(uid), mPid(pid), mAudioPolicyServiceClient(client),
      mAudioPortCallbacksEnabled(false)
{
}
@@ -251,7 +267,7 @@ void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who _
    sp<NotificationClient> keep(this);
    sp<AudioPolicyService> service = mService.promote();
    if (service != 0) {
        service->removeNotificationClient(mUid);
        service->removeNotificationClient(mUid, mPid);
    }
}

+8 −3
Original line number Diff line number Diff line
@@ -222,7 +222,7 @@ public:
            virtual status_t clientSetAudioPortConfig(const struct audio_port_config *config,
                                                      int delayMs);

            void removeNotificationClient(uid_t uid);
            void removeNotificationClient(uid_t uid, pid_t pid);
            void onAudioPortListUpdate();
            void doOnAudioPortListUpdate();
            void onAudioPatchListUpdate();
@@ -594,7 +594,7 @@ private:
    public:
                            NotificationClient(const sp<AudioPolicyService>& service,
                                                const sp<IAudioPolicyServiceClient>& client,
                                                uid_t uid);
                                                uid_t uid, pid_t pid);
        virtual             ~NotificationClient();

                            void      onAudioPortListUpdate();
@@ -607,6 +607,10 @@ private:
                                        audio_patch_handle_t patchHandle);
                            void      setAudioPortCallbacksEnabled(bool enabled);

                            uid_t uid() {
                                return mUid;
                            }

                // IBinder::DeathRecipient
                virtual     void        binderDied(const wp<IBinder>& who);

@@ -616,6 +620,7 @@ private:

        const wp<AudioPolicyService>        mService;
        const uid_t                         mUid;
        const pid_t                         mPid;
        const sp<IAudioPolicyServiceClient> mAudioPolicyServiceClient;
              bool                          mAudioPortCallbacksEnabled;
    };
@@ -680,7 +685,7 @@ private:
    AudioPolicyInterface *mAudioPolicyManager;
    AudioPolicyClient *mAudioPolicyClient;

    DefaultKeyedVector< uid_t, sp<NotificationClient> >    mNotificationClients;
    DefaultKeyedVector< int64_t, sp<NotificationClient> >    mNotificationClients;
    Mutex mNotificationClientsLock;  // protects mNotificationClients
    // Manage all effects configured in audio_effects.conf
    sp<AudioPolicyEffects> mAudioPolicyEffects;