AudioPolicyService.cpp revision 10b7123bd6ce29fe756422aeedc5cfe469c4309f
165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian/*
265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Copyright (C) 2009 The Android Open Source Project
365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * you may not use this file except in compliance with the License.
665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * You may obtain a copy of the License at
765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Unless required by applicable law or agreed to in writing, software
1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * See the License for the specific language governing permissions and
1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * limitations under the License.
1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian */
1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioPolicyService"
1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//#define LOG_NDEBUG 0
1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
20153b9fe667e6e78e0218ff0159353097428c7657Glenn Kasten#include "Configuration.h"
2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#undef __STRICT_ANSI__
2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define __STDINT_LIMITS
2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define __STDC_LIMIT_MACROS
2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdint.h>
2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/time.h>
2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h>
2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h>
2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h>
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h>
31f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <binder/ActivityManager.h>
32f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <binder/PermissionController.h>
33f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <binder/IResultReceiver.h>
3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h>
3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioPolicyService.h"
3744deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten#include "ServiceUtilities.h"
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware_legacy/power.h>
397c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <media/AudioEffect.h>
40c84d9d235679a4d48245b316b7b2e4c0b19413e7Chih-Hung Hsieh#include <media/AudioParameter.h>
4165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4264760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
437394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin#include <system/audio_policy.h>
4461a4fac2e3ec271241e3a4f405d7357b7f6ca4c2Mikhail Naganov
45f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <private/android_filesystem_config.h>
46f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
498dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
508dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
5322ecc912a87099cff8cadc424cd12f85c118673fGlenn Kastenstatic const int kDumpLockSleepUs = 20000;
5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
550ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatic const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds
565fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher
57f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatic const String16 sManageAudioPolicyPermission("android.permission.MANAGE_AUDIO_POLICY");
58fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioPolicyService()
62dce54a1492c410ad0d93253b341fb33305337505Eric Laurent    : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
63bb6c9a05840d924b502ce0f1868fca4881ada1edEric Laurent      mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
65f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent}
66f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent
67f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurentvoid AudioPolicyService::onFirstRef()
68f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent{
698b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    {
708b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        Mutex::Autolock _l(mLock);
71935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
728b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        // start tone playback thread
738b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
748b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        // start audio commands thread
758b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
768b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        // start output activity command thread
778b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
78dce54a1492c410ad0d93253b341fb33305337505Eric Laurent
798b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mAudioPolicyClient = new AudioPolicyClient(this);
808b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
818b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    }
82ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // load audio processing modules
838b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
848b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    {
858b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        Mutex::Autolock _l(mLock);
868b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mAudioPolicyEffects = audioPolicyEffects;
878b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    }
88f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
89f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy = new UidPolicy(this);
90f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy->registerSelf();
9165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
9265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::~AudioPolicyService()
9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mTonePlaybackThread->exit();
9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommandThread->exit();
97657ff61389d7316f798d4abe03efac56fd528d91Eric Laurent    mOutputCommandThread->exit();
987c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
99f269b8e0e9ab950fc6652b9594b7a3431c81630cEric Laurent    destroyAudioPolicyManager(mAudioPolicyManager);
100dce54a1492c410ad0d93253b341fb33305337505Eric Laurent    delete mAudioPolicyClient;
101b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
102b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mNotificationClients.clear();
103ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    mAudioPolicyEffects.clear();
104f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
105f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy->unregisterSelf();
106f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy.clear();
107b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
108b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
109b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// A notification client is always registered by AudioSystem when the client process
110b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// connects to AudioPolicyService.
111b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client)
112b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
113125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent    if (client == 0) {
114125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent        ALOGW("%s got NULL client", __FUNCTION__);
115125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent        return;
116125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent    }
1170ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    Mutex::Autolock _l(mNotificationClientsLock);
118b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
119b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    uid_t uid = IPCThreadState::self()->getCallingUid();
120b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    if (mNotificationClients.indexOfKey(uid) < 0) {
121b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        sp<NotificationClient> notificationClient = new NotificationClient(this,
122b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                                                                           client,
123b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                                                                           uid);
124b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        ALOGV("registerClient() client %p, uid %d", client.get(), uid);
125b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
126b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mNotificationClients.add(uid, notificationClient);
127b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
128f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        sp<IBinder> binder = IInterface::asBinder(client);
129b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        binder->linkToDeath(notificationClient);
130b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
131b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
132b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
133e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurentvoid AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
134e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent{
135e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    Mutex::Autolock _l(mNotificationClientsLock);
136e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent
137e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    uid_t uid = IPCThreadState::self()->getCallingUid();
138e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    if (mNotificationClients.indexOfKey(uid) < 0) {
139e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent        return;
140e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    }
141e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled);
142e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent}
143e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent
144b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// removeNotificationClient() is called when the client process dies.
145b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::removeNotificationClient(uid_t uid)
146b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
1470ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    {
1480ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent        Mutex::Autolock _l(mNotificationClientsLock);
1490ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent        mNotificationClients.removeItem(uid);
1500ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    }
1510ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    {
1520ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent        Mutex::Autolock _l(mLock);
153b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        if (mAudioPolicyManager) {
15410b7123bd6ce29fe756422aeedc5cfe469c4309fEric Laurent            // called from binder death notification: no need to clear caller identity
1558c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            mAudioPolicyManager->releaseResourcesForUid(uid);
156b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        }
1570ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    }
158b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
159b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
160b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPortListUpdate()
161b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
162b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mOutputCommandThread->updateAudioPortListCommand();
163b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
164b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
165b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPortListUpdate()
166b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
1670ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    Mutex::Autolock _l(mNotificationClientsLock);
168b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    for (size_t i = 0; i < mNotificationClients.size(); i++) {
169b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mNotificationClients.valueAt(i)->onAudioPortListUpdate();
170b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
171b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
172b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
173b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPatchListUpdate()
174b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
175b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mOutputCommandThread->updateAudioPatchListCommand();
17665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
17765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
178b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPatchListUpdate()
179b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
1800ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    Mutex::Autolock _l(mNotificationClientsLock);
181b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    for (size_t i = 0; i < mNotificationClients.size(); i++) {
182b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mNotificationClients.valueAt(i)->onAudioPatchListUpdate();
183b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
184b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
185b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
186e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
187de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{
188de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
189de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi            regId.string(), state);
190de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state);
191de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi}
192de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
193e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
194de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{
195de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    Mutex::Autolock _l(mNotificationClientsLock);
196de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    for (size_t i = 0; i < mNotificationClients.size(); i++) {
197de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state);
198de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    }
199de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi}
200de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
201ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivivoid AudioPolicyService::onRecordingConfigurationUpdate(int event,
202ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
2038c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
2042f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
205ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
2068c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi            clientConfig, deviceConfig, patchHandle);
2072f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
2082f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
209ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivivoid AudioPolicyService::doOnRecordingConfigurationUpdate(int event,
210ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
2118c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
2122f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
2132f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    Mutex::Autolock _l(mNotificationClientsLock);
2142f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    for (size_t i = 0; i < mNotificationClients.size(); i++) {
215ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
2168c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                clientConfig, deviceConfig, patchHandle);
2172f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    }
2182f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
2192f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
2202f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivistatus_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
2212f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                                                audio_patch_handle_t *handle,
2222f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                                                int delayMs)
2232f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
2242f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs);
2252f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
2262f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
2272f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivistatus_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle,
2282f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                                                 int delayMs)
2292f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
2302f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs);
2312f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
2322f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
233e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config,
234e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                                                      int delayMs)
235e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{
236e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
237e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent}
238e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
239b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
240b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                                                     const sp<IAudioPolicyServiceClient>& client,
241b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                                                     uid_t uid)
242e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    : mService(service), mUid(uid), mAudioPolicyServiceClient(client),
243e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent      mAudioPortCallbacksEnabled(false)
244b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
245b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
246b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
247b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::~NotificationClient()
248b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
249b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
250b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
251b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused)
252b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
253b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sp<NotificationClient> keep(this);
254b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sp<AudioPolicyService> service = mService.promote();
255b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    if (service != 0) {
256b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        service->removeNotificationClient(mUid);
257b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
258b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
259b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
260b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPortListUpdate()
261b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
262e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
263b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mAudioPolicyServiceClient->onAudioPortListUpdate();
264b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
265b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
266b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
267b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
268b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
269e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
270b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mAudioPolicyServiceClient->onAudioPatchListUpdate();
271b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
272b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
27357dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent
274de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivivoid AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
275e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh        const String8& regId, int32_t state)
276de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{
27796c7eed596077ff84e75b7b1c6f20c3a29219bd1Eric Laurent    if (mAudioPolicyServiceClient != 0 && (mUid % AID_USER_OFFSET) < AID_APP_START) {
2782f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state);
2792f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    }
2802f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
2812f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
2822f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
283ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        int event, const record_client_info_t *clientInfo,
2848c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
2858c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        audio_patch_handle_t patchHandle)
2862f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
28796c7eed596077ff84e75b7b1c6f20c3a29219bd1Eric Laurent    if (mAudioPolicyServiceClient != 0 && (mUid % AID_USER_OFFSET) < AID_APP_START) {
288ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo,
2898c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                clientConfig, deviceConfig, patchHandle);
290de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    }
291de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi}
292de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
293e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurentvoid AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled)
294e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent{
295e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    mAudioPortCallbacksEnabled = enabled;
296e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent}
297e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent
298e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent
29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::binderDied(const wp<IBinder>& who) {
300411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten    ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
301de070137f11d346fba77605bd76a44c040a618fcEric Laurent            IPCThreadState::self()->getCallingPid());
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
31222ecc912a87099cff8cadc424cd12f85c118673fGlenn Kasten        usleep(kDumpLockSleepUs);
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpInternals(int fd)
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
323dce54a1492c410ad0d93253b341fb33305337505Eric Laurent    snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager);
32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
334f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::setRecordSilenced(uid_t uid, bool silenced)
335f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov{
336eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    {
337eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
338eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (mAudioPolicyManager) {
33910b7123bd6ce29fe756422aeedc5cfe469c4309fEric Laurent            AutoCallerClear acc;
340eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov            mAudioPolicyManager->setRecordSilenced(uid, silenced);
341eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        }
342eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
343eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
344eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (af) {
345eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        af->setRecordSilenced(uid, silenced);
346eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
347f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
348f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
3490f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
35144deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!dumpAllowed()) {
35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpPermissionDenial(fd);
35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool locked = tryLock(mLock);
35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpInternals(fd);
3619d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten        if (mAudioCommandThread != 0) {
36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mAudioCommandThread->dump(fd);
36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
3649d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten        if (mTonePlaybackThread != 0) {
36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mTonePlaybackThread->dump(fd);
36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
368dce54a1492c410ad0d93253b341fb33305337505Eric Laurent        if (mAudioPolicyManager) {
369dce54a1492c410ad0d93253b341fb33305337505Eric Laurent            mAudioPolicyManager->dump(fd);
370dce54a1492c410ad0d93253b341fb33305337505Eric Laurent        }
37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (locked) mLock.unlock();
37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpPermissionDenial(int fd)
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Permission Denial: "
38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingPid(),
38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingUid());
38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::onTransact(
392f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
393f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    switch (code) {
394f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        case SHELL_COMMAND_TRANSACTION: {
395f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            int in = data.readFileDescriptor();
396f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            int out = data.readFileDescriptor();
397f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            int err = data.readFileDescriptor();
398f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            int argc = data.readInt32();
399f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            Vector<String16> args;
400f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
401f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov               args.add(data.readString16());
402f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            }
403f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            sp<IBinder> unusedCallback;
404f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            sp<IResultReceiver> resultReceiver;
405f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            status_t status;
406f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
407f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                return status;
408f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            }
409f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
410f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                return status;
411f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            }
412f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            status = shellCommand(in, out, err, args);
413f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            if (resultReceiver != nullptr) {
414f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                resultReceiver->send(status);
415f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            }
416f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            return NO_ERROR;
417f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        }
418f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
419f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnAudioPolicyService::onTransact(code, data, reply, flags);
42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
423f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov// ------------------- Shell command implementation -------------------
424f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
425f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov// NOTE: This is a remote API - make sure all args are validated
426f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::shellCommand(int in, int out, int err, Vector<String16>& args) {
427f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (!checkCallingPermission(sManageAudioPolicyPermission, nullptr, nullptr)) {
428f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return PERMISSION_DENIED;
429f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
430f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
431f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return BAD_VALUE;
432f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
433f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (args.size() == 3 && args[0] == String16("set-uid-state")) {
434f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return handleSetUidState(args, err);
435f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) {
436f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return handleResetUidState(args, err);
437f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    } else if (args.size() == 2 && args[0] == String16("get-uid-state")) {
438f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return handleGetUidState(args, out, err);
439f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    } else if (args.size() == 1 && args[0] == String16("help")) {
440f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        printHelp(out);
441f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return NO_ERROR;
442f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
443f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    printHelp(err);
444f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    return BAD_VALUE;
445f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
446f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
447f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::handleSetUidState(Vector<String16>& args, int err) {
448f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    PermissionController pc;
449f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    int uid = pc.getPackageUid(args[1], 0);
450f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (uid <= 0) {
451f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
452f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
453f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return BAD_VALUE;
454f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
455f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    bool active = false;
456f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (args[2] == String16("active")) {
457f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        active = true;
458f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    } else if ((args[2] != String16("idle"))) {
459f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
460f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return BAD_VALUE;
461f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
462f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy->addOverrideUid(uid, active);
463f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    return NO_ERROR;
464f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
465f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
466f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::handleResetUidState(Vector<String16>& args, int err) {
467f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    PermissionController pc;
468f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    int uid = pc.getPackageUid(args[1], 0);
469f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (uid < 0) {
470f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
471f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
472f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return BAD_VALUE;
473f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
474f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy->removeOverrideUid(uid);
475f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    return NO_ERROR;
476f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
477f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
478f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::handleGetUidState(Vector<String16>& args, int out, int err) {
479f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    PermissionController pc;
480f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    int uid = pc.getPackageUid(args[1], 0);
481f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (uid < 0) {
482f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
483f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
484f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return BAD_VALUE;
485f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
486f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (mUidPolicy->isUidActive(uid)) {
487f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return dprintf(out, "active\n");
488f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    } else {
489f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return dprintf(out, "idle\n");
490f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
491f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
492f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
493f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::printHelp(int out) {
494f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    return dprintf(out, "Audio policy service commands:\n"
495f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        "  get-uid-state <PACKAGE> gets the uid state\n"
496f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        "  set-uid-state <PACKAGE> <active|idle> overrides the uid state\n"
497f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        "  reset-uid-state <PACKAGE> clears the uid state override\n"
498f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        "  help print this message\n");
499f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
500f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
501f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov// -----------  AudioPolicyService::UidPolicy implementation ----------
502f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
503f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::UidPolicy::registerSelf() {
504f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    ActivityManager am;
505f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
506f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            | ActivityManager::UID_OBSERVER_IDLE
507f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            | ActivityManager::UID_OBSERVER_ACTIVE,
508f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            ActivityManager::PROCESS_STATE_UNKNOWN,
509f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            String16("audioserver"));
510eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    status_t res = am.linkToDeath(this);
511eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (!res) {
512eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
513eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        mObserverRegistered = true;
514eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    } else {
515eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
516eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        am.unregisterUidObserver(this);
517eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
518f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
519f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
520f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::UidPolicy::unregisterSelf() {
521f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    ActivityManager am;
522eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    am.unlinkToDeath(this);
523f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    am.unregisterUidObserver(this);
524eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    Mutex::Autolock _l(mLock);
525eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    mObserverRegistered = false;
526f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
527f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
528eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) {
529eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    Mutex::Autolock _l(mLock);
530eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    mCachedUids.clear();
531eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    mObserverRegistered = false;
532f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
533f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
534eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovbool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) {
535eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (isServiceUid(uid)) return true;
536eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    bool needToReregister = false;
537f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    {
538eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
539eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        needToReregister = !mObserverRegistered;
540f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
541eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (needToReregister) {
542eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        // Looks like ActivityManager has died previously, attempt to re-register.
543eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        registerSelf();
544f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
545f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    {
546eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
547eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        auto overrideIter = mOverrideUids.find(uid);
548eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (overrideIter != mOverrideUids.end()) {
549eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov            return overrideIter->second;
550f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        }
551eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        // In an absense of the ActivityManager, assume everything to be active.
552eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (!mObserverRegistered) return true;
553eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        auto cacheIter = mCachedUids.find(uid);
554eba668adbdee1ecfcf00fa9f9fc066c022cfddbaMikhail Naganov        if (cacheIter != mCachedUids.end()) {
555eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov            return cacheIter->second;
556f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        }
557f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
558eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    ActivityManager am;
559eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    bool active = am.isUidActive(uid, String16("audioserver"));
560eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    {
561eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
562eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        mCachedUids.insert(std::pair<uid_t, bool>(uid, active));
563eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
564eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    return active;
565f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
566f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
567eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
568eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    updateUidCache(uid, true, true);
569f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
570f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
571eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
572eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    updateUidCache(uid, false, false);
573eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov}
574eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov
575eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
576eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    updateUidCache(uid, false, true);
577eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov}
578eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov
579eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovbool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const {
580eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    return uid % AID_USER_OFFSET < AID_APP_START;
581eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov}
582eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov
583eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) {
584eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    sp<AudioPolicyService> service = mService.promote();
585eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (service != nullptr) {
586eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        service->setRecordSilenced(uid, !active);
587eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
588f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
589f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
590f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
591eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (isServiceUid(uid)) return;
592eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    bool wasOverridden = false, wasActive = false;
593f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    {
594eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
595eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        updateUidLocked(&mOverrideUids, uid, active, insert, &wasOverridden, &wasActive);
596f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
597eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (!wasOverridden && insert) {
598eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        notifyService(uid, active);  // Started to override.
599eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    } else if (wasOverridden && !insert) {
600eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        notifyService(uid, isUidActive(uid));  // Override ceased, notify with ground truth.
601eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    } else if (wasActive != active) {
602eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        notifyService(uid, active);  // Override updated.
603f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
604f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
605f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
606eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::updateUidCache(uid_t uid, bool active, bool insert) {
607eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (isServiceUid(uid)) return;
608eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    bool wasActive = false;
609eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    {
610eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
611eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        updateUidLocked(&mCachedUids, uid, active, insert, nullptr, &wasActive);
612eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        // Do not notify service if currently overridden.
613eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (mOverrideUids.find(uid) != mOverrideUids.end()) return;
614eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
615eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    bool nowActive = active && insert;
616eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (wasActive != nowActive) notifyService(uid, nowActive);
617eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov}
618eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov
619eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t, bool> *uids,
620eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive) {
621eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    auto it = uids->find(uid);
622eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (it != uids->end()) {
623eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (wasThere != nullptr) *wasThere = true;
624eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (wasActive != nullptr) *wasActive = it->second;
625eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (insert) {
626eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov            it->second = active;
627eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        } else {
628eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov            uids->erase(it);
629eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        }
630eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    } else if (insert) {
631eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        uids->insert(std::pair<uid_t, bool>(uid, active));
632eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
633f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
63465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// -----------  AudioPolicyService::AudioCommandThread implementation ----------
63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
637bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
638bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                                                           const wp<AudioPolicyService>& service)
639bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    : Thread(false), mName(name), mService(service)
64065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mpToneGenerator = NULL;
64265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioCommandThread::~AudioCommandThread()
64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
647bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (!mAudioCommands.isEmpty()) {
64865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        release_wake_lock(mName.string());
64965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommands.clear();
651e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    delete mpToneGenerator;
65265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::onFirstRef()
65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
656bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run(mName.string(), ANDROID_PRIORITY_AUDIO);
65765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioPolicyService::AudioCommandThread::threadLoop()
66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
661d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent    nsecs_t waitTime = -1;
66265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.lock();
66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!exitPending())
66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
66659a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent        sp<AudioPolicyService> svc;
66759a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent        while (!mAudioCommands.isEmpty() && !exitPending()) {
66865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            nsecs_t curTime = systemTime();
66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // commands are sorted by increasing time stamp: execute them from index 0 and up
67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mAudioCommands[0]->mTime <= curTime) {
6710ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                sp<AudioCommand> command = mAudioCommands[0];
67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mAudioCommands.removeAt(0);
6730ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                mLastCommand = command;
67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                switch (command->mCommand) {
67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case START_TONE: {
67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.unlock();
6780ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    ToneData *data = (ToneData *)command->mParam.get();
6793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing start tone %d on stream %d",
68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            data->mType, data->mStream);
681e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten                    delete mpToneGenerator;
68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mpToneGenerator->startTone(data->mType);
68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.lock();
68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case STOP_TONE: {
68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.unlock();
6883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing stop tone");
68965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    if (mpToneGenerator != NULL) {
69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mpToneGenerator->stopTone();
69165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        delete mpToneGenerator;
69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mpToneGenerator = NULL;
69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
69465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.lock();
69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
69665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case SET_VOLUME: {
6970ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    VolumeData *data = (VolumeData *)command->mParam.get();
6983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing set volume stream %d, \
699de070137f11d346fba77605bd76a44c040a618fcEric Laurent                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
700de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
701de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                                    data->mVolume,
702de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                                    data->mIO);
70365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case SET_PARAMETERS: {
7050ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    ParametersData *data = (ParametersData *)command->mParam.get();
706e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
707e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                            data->mKeyValuePairs.string(), data->mIO);
708e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
709e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    }break;
71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case SET_VOICE_VOLUME: {
7110ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
7123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing set voice volume volume %f",
713de070137f11d346fba77605bd76a44c040a618fcEric Laurent                            data->mVolume);
71465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
71565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
716bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                case STOP_OUTPUT: {
7170ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    StopOutputData *data = (StopOutputData *)command->mParam.get();
718bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    ALOGV("AudioCommandThread() processing stop output %d",
719bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                            data->mIO);
72059a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent                    svc = mService.promote();
721bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    if (svc == 0) {
722bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                        break;
723bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }
724bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.unlock();
725bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    svc->doStopOutput(data->mIO, data->mStream, data->mSession);
726bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.lock();
727bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }break;
728bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                case RELEASE_OUTPUT: {
7290ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
730bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    ALOGV("AudioCommandThread() processing release output %d",
731bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                            data->mIO);
73259a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent                    svc = mService.promote();
733bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    if (svc == 0) {
734bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                        break;
735bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }
736bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.unlock();
737e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                    svc->doReleaseOutput(data->mIO, data->mStream, data->mSession);
738bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.lock();
739bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }break;
740951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                case CREATE_AUDIO_PATCH: {
741951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
742951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    ALOGV("AudioCommandThread() processing create audio patch");
743951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
744951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    if (af == 0) {
745951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                        command->mStatus = PERMISSION_DENIED;
746951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    } else {
747951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                        command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
748951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    }
749951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    } break;
750951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                case RELEASE_AUDIO_PATCH: {
751951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get();
752951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    ALOGV("AudioCommandThread() processing release audio patch");
753951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
754951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    if (af == 0) {
755951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                        command->mStatus = PERMISSION_DENIED;
756951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    } else {
757951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                        command->mStatus = af->releaseAudioPatch(data->mHandle);
758951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    }
759951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    } break;
760b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                case UPDATE_AUDIOPORT_LIST: {
761b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    ALOGV("AudioCommandThread() processing update audio port list");
76259a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent                    svc = mService.promote();
763b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    if (svc == 0) {
764b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                        break;
765b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    }
766b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    mLock.unlock();
767b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    svc->doOnAudioPortListUpdate();
768b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    mLock.lock();
769b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    }break;
770b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                case UPDATE_AUDIOPATCH_LIST: {
771b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    ALOGV("AudioCommandThread() processing update audio patch list");
77259a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent                    svc = mService.promote();
773b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    if (svc == 0) {
774b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                        break;
775b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    }
776b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    mLock.unlock();
777b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    svc->doOnAudioPatchListUpdate();
778b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    mLock.lock();
779b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    }break;
780e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                case SET_AUDIOPORT_CONFIG: {
781e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
782e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    ALOGV("AudioCommandThread() processing set port config");
783e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
784e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    if (af == 0) {
785e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                        command->mStatus = PERMISSION_DENIED;
786e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    } else {
787e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                        command->mStatus = af->setAudioPortConfig(&data->mConfig);
788e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    }
789e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    } break;
790de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                case DYN_POLICY_MIX_STATE_UPDATE: {
791de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    DynPolicyMixStateUpdateData *data =
792de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                            (DynPolicyMixStateUpdateData *)command->mParam.get();
793de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d",
794de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                            data->mRegId.string(), data->mState);
795de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    svc = mService.promote();
796de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    if (svc == 0) {
797de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                        break;
798de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    }
799de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    mLock.unlock();
800de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState);
801de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    mLock.lock();
802de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    } break;
8032f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                case RECORDING_CONFIGURATION_UPDATE: {
8042f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    RecordingConfigurationUpdateData *data =
8052f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                            (RecordingConfigurationUpdateData *)command->mParam.get();
8062f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    ALOGV("AudioCommandThread() processing recording configuration update");
8072f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    svc = mService.promote();
8082f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    if (svc == 0) {
8092f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                        break;
8102f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    }
8112f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    mLock.unlock();
812ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi                    svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
813ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi                            &data->mClientConfig, &data->mDeviceConfig,
8148c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                            data->mPatchHandle);
8152f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    mLock.lock();
8162f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    } break;
81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                default:
8185ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
8200ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                {
8210ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    Mutex::Autolock _l(command->mLock);
8220ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    if (command->mWaitStatus) {
8230ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                        command->mWaitStatus = false;
8240ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                        command->mCond.signal();
8250ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    }
8260ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                }
827d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent                waitTime = -1;
828a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                // release mLock before releasing strong reference on the service as
829a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                // AudioPolicyService destructor calls AudioCommandThread::exit() which
830a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                // acquires mLock.
831a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                mLock.unlock();
832a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                svc.clear();
833a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                mLock.lock();
83465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
83565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                waitTime = mAudioCommands[0]->mTime - curTime;
83665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                break;
83765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
83865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
839a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang
840a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        // release delayed commands wake lock if the queue is empty
841a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        if (mAudioCommands.isEmpty()) {
84205f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia            release_wake_lock(mName.string());
843a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        }
844a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang
845a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        // At this stage we have either an empty command queue or the first command in the queue
846a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        // has a finite delay. So unless we are exiting it is safe to wait.
847a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        if (!exitPending()) {
84859a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent            ALOGV("AudioCommandThread() going to sleep");
849d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent            if (waitTime == -1) {
850d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent                mWaitWorkCV.wait(mLock);
851d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent            } else {
852d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent                mWaitWorkCV.waitRelative(mLock, waitTime);
853d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent            }
85459a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent        }
85565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
85605f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia    // release delayed commands wake lock before quitting
85705f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia    if (!mAudioCommands.isEmpty()) {
85805f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia        release_wake_lock(mName.string());
85905f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia    }
86065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
86165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return false;
86265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
86365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
86465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::dump(int fd)
86565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
86665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
86765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
86865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
86965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
87065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
87165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
87265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
87365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
87465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = tryLock(mLock);
87565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!locked) {
87665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        String8 result2(kCmdDeadlockedString);
87765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        write(fd, result2.string(), result2.size());
87865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
87965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
88065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "- Commands:\n");
88165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result = String8(buffer);
88265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("   Command Time        Wait pParam\n");
8838d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mAudioCommands.size(); i++) {
88465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mAudioCommands[i]->dump(buffer, SIZE);
88565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
88665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
88765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("  Last Command\n");
8880ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    if (mLastCommand != 0) {
8890ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        mLastCommand->dump(buffer, SIZE);
8900ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        result.append(buffer);
8910ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    } else {
8920ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        result.append("     none\n");
8930ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    }
89465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (locked) mLock.unlock();
89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9023d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kastenvoid AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type,
9033d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kasten        audio_stream_type_t stream)
90465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9050ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
90665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = START_TONE;
9070ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<ToneData> data = new ToneData();
90865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mType = type;
90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mStream = stream;
91048412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh    command->mParam = data;
9113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
9120ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sendCommand(command);
91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::stopToneCommand()
91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9170ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = STOP_TONE;
9193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding tone stop");
9200ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sendCommand(command);
92165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
923fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
924de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                               float volume,
92572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten                                                               audio_io_handle_t output,
926de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                               int delayMs)
92765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9280ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
92965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = SET_VOLUME;
9300ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<VolumeData> data = new VolumeData();
93165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mStream = stream;
93265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mVolume = volume;
93365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mIO = output;
93465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = data;
9350ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    command->mWaitStatus = true;
9363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
937de070137f11d346fba77605bd76a44c040a618fcEric Laurent            stream, volume, output);
9380ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    return sendCommand(command, delayMs);
93965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
94065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
94172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
942fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                                   const char *keyValuePairs,
943de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                                   int delayMs)
94465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9450ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
94665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = SET_PARAMETERS;
9470ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<ParametersData> data = new ParametersData();
94865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mIO = ioHandle;
949fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    data->mKeyValuePairs = String8(keyValuePairs);
95065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = data;
9510ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    command->mWaitStatus = true;
9523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
953fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            keyValuePairs, ioHandle, delayMs);
9540ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    return sendCommand(command, delayMs);
95565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
95665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
95765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
95865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9590ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
96065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = SET_VOICE_VOLUME;
9610ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<VoiceVolumeData> data = new VoiceVolumeData();
96265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mVolume = volume;
96365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = data;
9640ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    command->mWaitStatus = true;
9653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
9660ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    return sendCommand(command, delayMs);
96765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
96865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
969bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
970bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                                                               audio_stream_type_t stream,
971e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                                               audio_session_t session)
972bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
9730ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
974bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    command->mCommand = STOP_OUTPUT;
9750ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<StopOutputData> data = new StopOutputData();
976bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mIO = output;
977bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mStream = stream;
978bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mSession = session;
97948412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh    command->mParam = data;
980bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("AudioCommandThread() adding stop output %d", output);
9810ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sendCommand(command);
982bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
983bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
984e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentvoid AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output,
985e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                                                  audio_stream_type_t stream,
986e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                                                  audio_session_t session)
987bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
9880ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
989bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    command->mCommand = RELEASE_OUTPUT;
9900ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<ReleaseOutputData> data = new ReleaseOutputData();
991bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mIO = output;
992e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    data->mStream = stream;
993e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    data->mSession = session;
99448412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh    command->mParam = data;
995bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("AudioCommandThread() adding release output %d", output);
9960ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sendCommand(command);
9970ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent}
9980ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent
999951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
1000951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                                                const struct audio_patch *patch,
1001951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                                                audio_patch_handle_t *handle,
1002951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                                                int delayMs)
1003951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{
1004951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    status_t status = NO_ERROR;
1005951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent
1006951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    sp<AudioCommand> command = new AudioCommand();
1007951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mCommand = CREATE_AUDIO_PATCH;
1008951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    CreateAudioPatchData *data = new CreateAudioPatchData();
1009951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    data->mPatch = *patch;
1010951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    data->mHandle = *handle;
1011951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mParam = data;
1012951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mWaitStatus = true;
1013951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    ALOGV("AudioCommandThread() adding create patch delay %d", delayMs);
1014951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    status = sendCommand(command, delayMs);
1015951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    if (status == NO_ERROR) {
1016951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent        *handle = data->mHandle;
1017951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    }
1018951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    return status;
1019951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent}
1020951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent
1021951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle,
1022951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                                                 int delayMs)
1023951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{
1024951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    sp<AudioCommand> command = new AudioCommand();
1025951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mCommand = RELEASE_AUDIO_PATCH;
1026951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    ReleaseAudioPatchData *data = new ReleaseAudioPatchData();
1027951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    data->mHandle = handle;
1028951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mParam = data;
1029951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mWaitStatus = true;
1030951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    ALOGV("AudioCommandThread() adding release patch delay %d", delayMs);
1031951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    return sendCommand(command, delayMs);
1032951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent}
1033951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent
1034b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPortListCommand()
1035b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
1036b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sp<AudioCommand> command = new AudioCommand();
1037b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    command->mCommand = UPDATE_AUDIOPORT_LIST;
1038b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    ALOGV("AudioCommandThread() adding update audio port list");
1039b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sendCommand(command);
1040b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
1041b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
1042b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
1043b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
1044b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sp<AudioCommand>command = new AudioCommand();
1045b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    command->mCommand = UPDATE_AUDIOPATCH_LIST;
1046b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    ALOGV("AudioCommandThread() adding update audio patch list");
1047b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sendCommand(command);
1048b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
1049b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
1050e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
1051e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                                            const struct audio_port_config *config, int delayMs)
1052e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{
1053e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    sp<AudioCommand> command = new AudioCommand();
1054e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    command->mCommand = SET_AUDIOPORT_CONFIG;
1055e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    SetAudioPortConfigData *data = new SetAudioPortConfigData();
1056e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    data->mConfig = *config;
1057e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    command->mParam = data;
1058e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    command->mWaitStatus = true;
1059e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    ALOGV("AudioCommandThread() adding set port config delay %d", delayMs);
1060e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    return sendCommand(command, delayMs);
1061e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent}
1062e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
1063de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivivoid AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand(
1064e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh        const String8& regId, int32_t state)
1065de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{
1066de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    sp<AudioCommand> command = new AudioCommand();
1067de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    command->mCommand = DYN_POLICY_MIX_STATE_UPDATE;
1068de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData();
1069de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    data->mRegId = regId;
1070de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    data->mState = state;
1071de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    command->mParam = data;
1072de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d",
1073de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi            regId.string(), state);
1074de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    sendCommand(command);
1075de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi}
1076de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
10772f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
1078ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        int event, const record_client_info_t *clientInfo,
10798c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
10808c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        audio_patch_handle_t patchHandle)
10812f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
10822f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    sp<AudioCommand>command = new AudioCommand();
10832f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    command->mCommand = RECORDING_CONFIGURATION_UPDATE;
10842f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData();
10852f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    data->mEvent = event;
1086ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    data->mClientInfo = *clientInfo;
10877281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    data->mClientConfig = *clientConfig;
10887281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    data->mDeviceConfig = *deviceConfig;
10898c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    data->mPatchHandle = patchHandle;
10902f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    command->mParam = data;
1091ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
1092ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi            event, clientInfo->source, clientInfo->uid);
10932f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    sendCommand(command);
10942f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
10952f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
10960ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatus_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
10970ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent{
10980ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    {
10990ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        Mutex::Autolock _l(mLock);
11000ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        insertCommand_l(command, delayMs);
11010ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        mWaitWorkCV.signal();
11020ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    }
11030ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    Mutex::Autolock _l(command->mLock);
11040ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    while (command->mWaitStatus) {
11050ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs);
11060ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) {
11070ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            command->mStatus = TIMED_OUT;
11080ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            command->mWaitStatus = false;
11090ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        }
11100ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    }
11110ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    return command->mStatus;
1112bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
1113bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
111465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// insertCommand_l() must be called with mLock held
11150ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentvoid AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs)
111665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
11178d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    ssize_t i;  // not size_t because i will count down to -1
11180ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    Vector < sp<AudioCommand> > removedCommands;
111965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mTime = systemTime() + milliseconds(delayMs);
112065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // acquire wake lock to make sure delayed commands are processed
1122bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (mAudioCommands.isEmpty()) {
112365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
112465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
112565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check same pending commands with later time stamps and eliminate them
11275ff158fd499f581bdc1c3e91bbc03ce15eeeb77cIvan Lozano    for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) {
11280ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        sp<AudioCommand> command2 = mAudioCommands[i];
112965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
113065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (command2->mTime <= command->mTime) break;
1131e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent
1132e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        // create audio patch or release audio patch commands are equivalent
1133e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        // with regard to filtering
1134e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        if ((command->mCommand == CREATE_AUDIO_PATCH) ||
1135e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                (command->mCommand == RELEASE_AUDIO_PATCH)) {
1136e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            if ((command2->mCommand != CREATE_AUDIO_PATCH) &&
1137e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                    (command2->mCommand != RELEASE_AUDIO_PATCH)) {
1138e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                continue;
1139e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            }
1140e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        } else if (command2->mCommand != command->mCommand) continue;
114165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
114265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        switch (command->mCommand) {
114365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case SET_PARAMETERS: {
11440ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            ParametersData *data = (ParametersData *)command->mParam.get();
11450ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            ParametersData *data2 = (ParametersData *)command2->mParam.get();
114665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (data->mIO != data2->mIO) break;
11473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Comparing parameter command %s to new command %s",
1148de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
114965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            AudioParameter param = AudioParameter(data->mKeyValuePairs);
115065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
115165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            for (size_t j = 0; j < param.size(); j++) {
1152e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                String8 key;
1153e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                String8 value;
1154e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                param.getAt(j, key, value);
1155e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                for (size_t k = 0; k < param2.size(); k++) {
1156e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    String8 key2;
1157e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    String8 value2;
1158e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    param2.getAt(k, key2, value2);
1159e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    if (key2 == key) {
1160e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        param2.remove(key2);
1161e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        ALOGV("Filtering out parameter %s", key2.string());
1162e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        break;
1163e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    }
1164e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                }
116565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
116665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // if all keys have been filtered out, remove the command.
116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // otherwise, update the key value pairs
116865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (param2.size() == 0) {
116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                removedCommands.add(command2);
117065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
117165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                data2->mKeyValuePairs = param2.toString();
117265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
117321e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            command->mTime = command2->mTime;
117421e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // force delayMs to non 0 so that code below does not request to wait for
117521e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // command status as the command is now delayed
117621e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            delayMs = 1;
117765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } break;
117865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
117965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case SET_VOLUME: {
11800ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            VolumeData *data = (VolumeData *)command->mParam.get();
11810ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            VolumeData *data2 = (VolumeData *)command2->mParam.get();
118265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (data->mIO != data2->mIO) break;
118365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (data->mStream != data2->mStream) break;
11843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Filtering out volume command on output %d for stream %d",
1185de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    data->mIO, data->mStream);
118665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            removedCommands.add(command2);
118721e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            command->mTime = command2->mTime;
118821e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // force delayMs to non 0 so that code below does not request to wait for
118921e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // command status as the command is now delayed
119021e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            delayMs = 1;
119165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } break;
1192e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent
1193baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent        case SET_VOICE_VOLUME: {
1194baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
1195baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get();
1196baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            ALOGV("Filtering out voice volume command value %f replaced by %f",
1197baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent                  data2->mVolume, data->mVolume);
1198baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            removedCommands.add(command2);
1199baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            command->mTime = command2->mTime;
1200baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            // force delayMs to non 0 so that code below does not request to wait for
1201baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            // command status as the command is now delayed
1202baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            delayMs = 1;
1203baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent        } break;
1204baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent
1205e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        case CREATE_AUDIO_PATCH:
1206e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        case RELEASE_AUDIO_PATCH: {
1207e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            audio_patch_handle_t handle;
1208a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George            struct audio_patch patch;
1209e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            if (command->mCommand == CREATE_AUDIO_PATCH) {
1210e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle;
1211a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
1212e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            } else {
1213e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
1214e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            }
1215e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            audio_patch_handle_t handle2;
1216a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George            struct audio_patch patch2;
1217e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            if (command2->mCommand == CREATE_AUDIO_PATCH) {
1218e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle;
1219a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch;
1220e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            } else {
1221e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle;
1222f60b6b6c776a762827874f6f635c0577359a7ee4Glenn Kasten                memset(&patch2, 0, sizeof(patch2));
1223e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            }
1224e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            if (handle != handle2) break;
1225a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George            /* Filter CREATE_AUDIO_PATCH commands only when they are issued for
1226a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George               same output. */
1227a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George            if( (command->mCommand == CREATE_AUDIO_PATCH) &&
1228a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                (command2->mCommand == CREATE_AUDIO_PATCH) ) {
1229a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                bool isOutputDiff = false;
1230a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                if (patch.num_sources == patch2.num_sources) {
1231a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                    for (unsigned count = 0; count < patch.num_sources; count++) {
1232a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                        if (patch.sources[count].id != patch2.sources[count].id) {
1233a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                            isOutputDiff = true;
1234a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                            break;
1235a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                        }
1236a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                    }
1237a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                    if (isOutputDiff)
1238a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                       break;
1239a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                }
1240a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George            }
1241e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            ALOGV("Filtering out %s audio patch command for handle %d",
1242e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                  (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle);
1243e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            removedCommands.add(command2);
1244e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            command->mTime = command2->mTime;
1245e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            // force delayMs to non 0 so that code below does not request to wait for
1246e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            // command status as the command is now delayed
1247e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            delayMs = 1;
1248e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        } break;
1249e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent
1250de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        case DYN_POLICY_MIX_STATE_UPDATE: {
1251de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
1252de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        } break;
1253de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
12542f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        case RECORDING_CONFIGURATION_UPDATE: {
12552f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
12562f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        } break;
12572f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
125865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case START_TONE:
125965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case STOP_TONE:
126065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
126165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
126265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
126365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
126465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
126565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // remove filtered commands
126665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t j = 0; j < removedCommands.size(); j++) {
126765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // removed commands always have time stamps greater than current command
126865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
12690ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            if (mAudioCommands[k].get() == removedCommands[j].get()) {
12703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
127165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mAudioCommands.removeAt(k);
127265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                break;
127365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
127465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
127565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
127665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    removedCommands.clear();
127765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1278aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent    // Disable wait for status if delay is not 0.
1279aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent    // Except for create audio patch command because the returned patch handle
1280aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent    // is needed by audio policy manager
1281aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent    if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) {
1282cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent        command->mWaitStatus = false;
1283cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent    }
1284cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent
128565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // insert command at the right place according to its time stamp
12861e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent    ALOGV("inserting command: %d at index %zd, num commands %zu",
12871e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent            command->mCommand, i+1, mAudioCommands.size());
128865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommands.insertAt(command, i + 1);
128965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
129065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
129165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::exit()
129265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
12933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread::exit");
129465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
129565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AutoMutex _l(mLock);
129665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        requestExit();
129765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mWaitWorkCV.signal();
129865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
1299a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang    // Note that we can call it from the thread loop if all other references have been released
1300a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang    // but it will safely return WOULD_BLOCK in this case
130165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    requestExitAndWait();
130265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
130365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
130465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
130565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
130665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
130765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCommand,
130865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (int)ns2s(mTime),
130965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (int)ns2ms(mTime)%1000,
131065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mWaitStatus,
13110ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            mParam.get());
131265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
131365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1314fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin/******* helpers for the service_ops callbacks defined below *********/
1315fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
1316fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                       const char *keyValuePairs,
1317fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                       int delayMs)
1318fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
131972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
1320fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                           delayMs);
1321fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1322fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1323fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
1324fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                        float volume,
1325fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                        audio_io_handle_t output,
1326fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                        int delayMs)
1327fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1328fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten    return (int)mAudioCommandThread->volumeCommand(stream, volume,
132972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten                                                   output, delayMs);
1330fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1331fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1332fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::startTone(audio_policy_tone_t tone,
1333fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                  audio_stream_type_t stream)
1334fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
13356e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) {
133629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("startTone: illegal tone requested (%d)", tone);
13376e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
13386e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (stream != AUDIO_STREAM_VOICE_CALL) {
133929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("startTone: illegal stream (%d) requested for tone %d", stream,
1340e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            tone);
13416e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
1342fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
1343fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                          AUDIO_STREAM_VOICE_CALL);
1344fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return 0;
1345fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1346fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1347fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::stopTone()
1348fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1349fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mTonePlaybackThread->stopToneCommand();
1350fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return 0;
1351fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1352fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1353fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setVoiceVolume(float volume, int delayMs)
1354fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1355fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
1356fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1357fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1358fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinextern "C" {
13592d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_module_handle_t aps_load_hw_module(void *service __unused,
13602d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                             const char *name);
13612d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output(void *service __unused,
1362a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         audio_devices_t *pDevices,
1363a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         uint32_t *pSamplingRate,
1364a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         audio_format_t *pFormat,
1365a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         audio_channel_mask_t *pChannelMask,
1366a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         uint32_t *pLatencyMs,
13672d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                         audio_output_flags_t flags);
1368fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
13692d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output_on_module(void *service __unused,
1370a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_module_handle_t module,
1371a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_devices_t *pDevices,
1372a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   uint32_t *pSamplingRate,
1373a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_format_t *pFormat,
1374a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_channel_mask_t *pChannelMask,
1375a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   uint32_t *pLatencyMs,
1376ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                                                   audio_output_flags_t flags,
13772d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                                   const audio_offload_info_t *offloadInfo);
13782d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_dup_output(void *service __unused,
1379fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                 audio_io_handle_t output1,
13802d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                                 audio_io_handle_t output2);
13812d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_output(void *service __unused, audio_io_handle_t output);
13822d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_suspend_output(void *service __unused, audio_io_handle_t output);
13832d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_restore_output(void *service __unused, audio_io_handle_t output);
13842d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input(void *service __unused,
1385a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        audio_devices_t *pDevices,
1386a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        uint32_t *pSamplingRate,
1387a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        audio_format_t *pFormat,
1388a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        audio_channel_mask_t *pChannelMask,
13892d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                        audio_in_acoustics_t acoustics __unused);
13902d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input_on_module(void *service __unused,
1391a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  audio_module_handle_t module,
1392a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  audio_devices_t *pDevices,
1393a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  uint32_t *pSamplingRate,
1394a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  audio_format_t *pFormat,
13952d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                                  audio_channel_mask_t *pChannelMask);
13962d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_input(void *service __unused, audio_io_handle_t input);
13972d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_invalidate_stream(void *service __unused, audio_stream_type_t stream);
1398d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastenint aps_move_effects(void *service __unused, audio_session_t session,
1399fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                audio_io_handle_t src_output,
14002d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                audio_io_handle_t dst_output);
14012d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentchar * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
14022d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                     const char *keys);
14032d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentvoid aps_set_parameters(void *service, audio_io_handle_t io_handle,
14042d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                   const char *kv_pairs, int delay_ms);
14052d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_stream_volume(void *service, audio_stream_type_t stream,
1406fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                     float volume, audio_io_handle_t output,
14072d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                     int delay_ms);
14082d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_start_tone(void *service, audio_policy_tone_t tone,
14092d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                              audio_stream_type_t stream);
14102d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_stop_tone(void *service);
14112d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_voice_volume(void *service, float volume, int delay_ms);
14122d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent};
1413fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
14141b2a794a27caab3a1320d22b872b04ef73e96555Mikhail Naganov} // namespace android
1415